{
char* cache_fname = NULL;
int open_flags = O_RDWR|O_CREAT;
- bool first_try = true;
/* skip file open if it's already opened */
if (cache) return True;
- cache_fname = lock_path("gencache.tdb");
+ cache_fname = cache_path("gencache.tdb");
DEBUG(5, ("Opening cache file at %s\n", cache_fname));
-again:
cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT|TDB_INCOMPATIBLE_HASH, open_flags, 0644);
if (cache) {
int ret;
ret = tdb_check(cache, NULL, NULL);
if (ret != 0) {
tdb_close(cache);
- cache = NULL;
- if (!first_try) {
- DEBUG(0, ("gencache_init: tdb_check(%s) failed\n",
- cache_fname));
- return false;
- }
- first_try = false;
- DEBUG(0, ("gencache_init: tdb_check(%s) failed - retry after truncate\n",
- cache_fname));
- truncate(cache_fname, 0);
- goto again;
+
+ /*
+ * Retry with CLEAR_IF_FIRST.
+ *
+ * Warning: Converting this to dbwrap won't work
+ * directly. gencache.c does transactions on this tdb,
+ * and dbwrap forbids this for CLEAR_IF_FIRST
+ * databases. tdb does allow transactions on
+ * CLEAR_IF_FIRST databases, so lets use it here to
+ * clean up a broken database.
+ */
+ cache = tdb_open_log(cache_fname, 0,
+ TDB_DEFAULT|
+ TDB_INCOMPATIBLE_HASH|
+ TDB_CLEAR_IF_FIRST,
+ open_flags, 0644);
}
}
DEBUG(5, ("Opening cache file at %s\n", cache_fname));
- cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
+ cache_notrans = tdb_open_log(cache_fname, 0,
+ TDB_CLEAR_IF_FIRST|
+ TDB_INCOMPATIBLE_HASH|
+ TDB_NOSYNC,
open_flags, 0644);
if (cache_notrans == NULL) {
DEBUG(5, ("Opening %s failed: %s\n", cache_fname,
return false;
}
- DEBUG(10, ("Adding cache entry with key = %s and timeout ="
- " %s (%d seconds %s)\n", keystr, ctime(&timeout),
+ DEBUG(10, ("Adding cache entry with key=[%s] and timeout="
+ "[%s] (%d seconds %s)\n", keystr,
+ timestring(talloc_tos(), timeout),
(int)(timeout - time(NULL)),
timeout > time(NULL) ? "ahead" : "in the past"));
if (!gencache_init()) return False;
- DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
+ DEBUG(10, ("Deleting cache entry (key=[%s])\n", keystr));
/*
* We delete an element by setting its timeout to 0. This way we don't
* element.
*/
- exists = gencache_get_data_blob(keystr, &value, NULL, &was_expired);
+ exists = gencache_get_data_blob(keystr, NULL, &value, NULL,
+ &was_expired);
if (!exists && was_expired) {
/*
}
struct gencache_get_data_blob_state {
+ TALLOC_CTX *mem_ctx;
DATA_BLOB *blob;
time_t timeout;
bool result;
return;
}
- *state->blob = data_blob(blob.data, blob.length);
+ *state->blob = data_blob_talloc(state->mem_ctx, blob.data,
+ blob.length);
if (state->blob->data == NULL) {
state->result = false;
return;
* @retval False for failure
**/
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+bool gencache_get_data_blob(const char *keystr, TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob,
time_t *timeout, bool *was_expired)
{
struct gencache_get_data_blob_state state;
bool expired = false;
state.result = false;
+ state.mem_ctx = mem_ctx;
state.blob = blob;
if (!gencache_parse(keystr, gencache_get_data_blob_parser, &state)) {
DATA_BLOB blob;
bool ret = False;
- ret = gencache_get_data_blob(keystr, &blob, ptimeout, NULL);
+ ret = gencache_get_data_blob(keystr, NULL, &blob, ptimeout, NULL);
if (!ret) {
return false;
}
goto done;
}
- DEBUG(10, ("Calling function with arguments (key=%s, timeout=%s)\n",
- keystr, ctime(&timeout)));
+ DEBUG(10, ("Calling function with arguments "
+ "(key=[%s], timeout=[%s])\n",
+ keystr, timestring(talloc_tos(), timeout)));
state->fn(keystr,
data_blob_const(endptr,
}
DEBUG(10, ("Calling function with arguments "
- "(key = %s, value = %s, timeout = %s)\n",
- key, valstr, ctime(&timeout)));
+ "(key=[%s], value=[%s], timeout=[%s])\n",
+ key, valstr, timestring(talloc_tos(), timeout)));
state->fn(key, valstr, timeout, state->private_data);