mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
r24733: Add support for storing DATA_BLOBs in gencache.tdb (including torturetest).
Mimir, please have a look. DATA_BLOBs will now just show up as "DATA_BLOB"
values with "net cache list".
Guenther
(This used to be commit b8ad546d04
)
This commit is contained in:
parent
40102ad546
commit
2af9637925
@ -28,6 +28,8 @@
|
||||
#define TIMEOUT_LEN 12
|
||||
#define CACHE_DATA_FMT "%12u/%s"
|
||||
#define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
|
||||
#define BLOB_TYPE "DATA_BLOB"
|
||||
#define BLOB_TYPE_LEN 9
|
||||
|
||||
static TDB_CONTEXT *cache;
|
||||
static BOOL cache_readonly;
|
||||
@ -243,6 +245,161 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get existing entry from the cache file.
|
||||
*
|
||||
* @param keystr string that represents a key of this entry
|
||||
* @param blob DATA_BLOB that is filled with entry's blob
|
||||
* @param expired pointer to a BOOL that indicates whether the entry is expired
|
||||
*
|
||||
* @retval true when entry is successfuly fetched
|
||||
* @retval False for failure
|
||||
**/
|
||||
|
||||
BOOL gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, BOOL *expired)
|
||||
{
|
||||
TDB_DATA databuf;
|
||||
time_t t;
|
||||
char *blob_type;
|
||||
unsigned char *buf = NULL;
|
||||
BOOL ret = False;
|
||||
fstring valstr;
|
||||
int buflen = 0, len = 0, blob_len = 0;
|
||||
unsigned char *blob_buf = NULL;
|
||||
|
||||
/* fail completely if get null pointers passed */
|
||||
SMB_ASSERT(keystr);
|
||||
|
||||
if (!gencache_init()) {
|
||||
return False;
|
||||
}
|
||||
|
||||
databuf = tdb_fetch_bystring(cache, keystr);
|
||||
if (!databuf.dptr) {
|
||||
DEBUG(10,("Cache entry with key = %s couldn't be found\n",
|
||||
keystr));
|
||||
return False;
|
||||
}
|
||||
|
||||
buf = (unsigned char *)databuf.dptr;
|
||||
buflen = databuf.dsize;
|
||||
|
||||
len += tdb_unpack(buf+len, buflen-len, "fB",
|
||||
&valstr,
|
||||
&blob_len, &blob_buf);
|
||||
if (len == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
t = strtol(valstr, &blob_type, 10);
|
||||
|
||||
if (strcmp(blob_type+1, BLOB_TYPE) != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUG(10,("Returning %s cache entry: key = %s, "
|
||||
"timeout = %s", t > time(NULL) ? "valid" :
|
||||
"expired", keystr, ctime(&t)));
|
||||
|
||||
if (t <= time(NULL)) {
|
||||
/* We're expired */
|
||||
if (expired) {
|
||||
*expired = True;
|
||||
}
|
||||
}
|
||||
|
||||
if (blob) {
|
||||
*blob = data_blob(blob_buf, blob_len);
|
||||
if (!blob->data) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = True;
|
||||
out:
|
||||
SAFE_FREE(blob_buf);
|
||||
SAFE_FREE(databuf.dptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an entry in the cache file. If there's no such
|
||||
* one, then add it.
|
||||
*
|
||||
* @param keystr string that represents a key of this entry
|
||||
* @param blob DATA_BLOB value being cached
|
||||
* @param timeout time when the value is expired
|
||||
*
|
||||
* @retval true when entry is successfuly stored
|
||||
* @retval false on failure
|
||||
**/
|
||||
|
||||
BOOL gencache_set_data_blob(const char *keystr, DATA_BLOB *blob, time_t timeout)
|
||||
{
|
||||
BOOL ret = False;
|
||||
int tdb_ret;
|
||||
TDB_DATA databuf;
|
||||
char *valstr = NULL;
|
||||
unsigned char *buf = NULL;
|
||||
int len = 0, buflen = 0;
|
||||
|
||||
/* fail completely if get null pointers passed */
|
||||
SMB_ASSERT(keystr && blob);
|
||||
|
||||
if (!gencache_init()) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (cache_readonly) {
|
||||
return False;
|
||||
}
|
||||
|
||||
asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE);
|
||||
if (!valstr) {
|
||||
return False;
|
||||
}
|
||||
|
||||
again:
|
||||
len = 0;
|
||||
|
||||
len += tdb_pack(buf+len, buflen-len, "fB",
|
||||
valstr,
|
||||
blob->length, blob->data);
|
||||
|
||||
if (len == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (buflen < len) {
|
||||
SAFE_FREE(buf);
|
||||
buf = SMB_MALLOC_ARRAY(unsigned char, len);
|
||||
if (!buf) {
|
||||
goto out;
|
||||
}
|
||||
buflen = len;
|
||||
goto again;
|
||||
}
|
||||
|
||||
databuf = make_tdb_data(buf, len);
|
||||
|
||||
DEBUG(10,("Adding cache entry with key = %s; "
|
||||
"blob size = %d and timeout = %s"
|
||||
"(%d seconds %s)\n", keystr, (int)databuf.dsize,
|
||||
ctime(&timeout), (int)(timeout - time(NULL)),
|
||||
timeout > time(NULL) ? "ahead" : "in the past"));
|
||||
|
||||
tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0);
|
||||
if (tdb_ret == 0) {
|
||||
ret = True;
|
||||
}
|
||||
|
||||
out:
|
||||
SAFE_FREE(valstr);
|
||||
SAFE_FREE(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through all entries which key matches to specified pattern
|
||||
|
@ -4820,6 +4820,7 @@ static BOOL run_local_gencache(int dummy)
|
||||
{
|
||||
char *val;
|
||||
time_t tm;
|
||||
DATA_BLOB blob;
|
||||
|
||||
if (!gencache_init()) {
|
||||
d_printf("%s: gencache_init() failed\n", __location__);
|
||||
@ -4861,6 +4862,46 @@ static BOOL run_local_gencache(int dummy)
|
||||
return False;
|
||||
}
|
||||
|
||||
blob = data_blob_string_const("bar");
|
||||
tm = time(NULL);
|
||||
|
||||
if (!gencache_set_data_blob("foo", &blob, tm)) {
|
||||
d_printf("%s: gencache_set_data_blob() failed\n", __location__);
|
||||
return False;
|
||||
}
|
||||
|
||||
data_blob_free(&blob);
|
||||
|
||||
if (!gencache_get_data_blob("foo", &blob, NULL)) {
|
||||
d_printf("%s: gencache_get_data_blob() failed\n", __location__);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (strcmp((const char *)blob.data, "bar") != 0) {
|
||||
d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
|
||||
__location__, (const char *)blob.data, "bar");
|
||||
data_blob_free(&blob);
|
||||
return False;
|
||||
}
|
||||
|
||||
data_blob_free(&blob);
|
||||
|
||||
if (!gencache_del("foo")) {
|
||||
d_printf("%s: gencache_del() failed\n", __location__);
|
||||
return False;
|
||||
}
|
||||
if (gencache_del("foo")) {
|
||||
d_printf("%s: second gencache_del() succeeded\n",
|
||||
__location__);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (gencache_get_data_blob("foo", &blob, NULL)) {
|
||||
d_printf("%s: gencache_get_data_blob() on deleted entry "
|
||||
"succeeded\n", __location__);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!gencache_shutdown()) {
|
||||
d_printf("%s: gencache_shutdown() failed\n", __location__);
|
||||
return False;
|
||||
|
Loading…
Reference in New Issue
Block a user