dbwrap: Simplify dbwrap_store_int32_bystring
[kai/samba-autobuild/.git] / lib / dbwrap / dbwrap_tdb.c
index ece7b9d8b5f0c6335c7c0f842bb2bb2058ed0818..c30bedee77548c54f00433f402da235b578551b9 100644 (file)
@@ -24,6 +24,8 @@
 #include "lib/tdb_wrap/tdb_wrap.h"
 #include "lib/util/util_tdb.h"
 #include "system/filesys.h"
+#include "lib/param/param.h"
+#include "libcli/util/error.h"
 
 struct db_tdb_ctx {
        struct tdb_wrap *wtdb;
@@ -34,17 +36,19 @@ struct db_tdb_ctx {
        } id;
 };
 
-static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag);
+static NTSTATUS db_tdb_storev(struct db_record *rec,
+                             const TDB_DATA *dbufs, int num_dbufs, int flag);
 static NTSTATUS db_tdb_delete(struct db_record *rec);
 
 static void db_tdb_log_key(const char *prefix, TDB_DATA key)
 {
        size_t len;
        char *keystr;
-
+       TALLOC_CTX *frame;
        if (DEBUGLEVEL < 10) {
                return;
        }
+       frame = talloc_stackframe();
        len = key.dsize;
        if (DEBUGLEVEL == 10) {
                /*
@@ -52,10 +56,10 @@ static void db_tdb_log_key(const char *prefix, TDB_DATA key)
                 */
                len = MIN(10, key.dsize);
        }
-       keystr = hex_encode_talloc(talloc_tos(), (unsigned char *)(key.dptr),
+       keystr = hex_encode_talloc(frame, (unsigned char *)(key.dptr),
                                   len);
        DEBUG(10, ("%s key %s\n", prefix, keystr));
-       TALLOC_FREE(keystr);
+       TALLOC_FREE(frame);
 }
 
 static int db_tdb_record_destr(struct db_record* data)
@@ -134,8 +138,8 @@ static struct db_record *db_tdb_fetch_locked_internal(
 
        talloc_set_destructor(state.result, db_tdb_record_destr);
 
-       state.result->private_data = talloc_reference(state.result, ctx);
-       state.result->store = db_tdb_store;
+       state.result->private_data = ctx;
+       state.result->storev = db_tdb_storev;
        state.result->delete_rec = db_tdb_delete;
 
        DEBUG(10, ("Allocated locked data 0x%p\n", state.result));
@@ -171,6 +175,50 @@ static struct db_record *db_tdb_try_fetch_locked(
        return db_tdb_fetch_locked_internal(db, mem_ctx, key);
 }
 
+static NTSTATUS db_tdb_do_locked(struct db_context *db, TDB_DATA key,
+                                void (*fn)(struct db_record *rec,
+                                           void *private_data),
+                                void *private_data)
+{
+       struct db_tdb_ctx *ctx = talloc_get_type_abort(
+               db->private_data, struct db_tdb_ctx);
+       uint8_t *buf = NULL;
+       struct db_record rec;
+       int ret;
+
+       ret = tdb_chainlock(ctx->wtdb->tdb, key);
+       if (ret == -1) {
+               enum TDB_ERROR err = tdb_error(ctx->wtdb->tdb);
+               DBG_DEBUG("tdb_chainlock failed: %s\n",
+                         tdb_errorstr(ctx->wtdb->tdb));
+               return map_nt_error_from_tdb(err);
+       }
+
+       ret = tdb_fetch_talloc(ctx->wtdb->tdb, key, ctx, &buf);
+
+       if ((ret != 0) && (ret != ENOENT)) {
+               DBG_DEBUG("tdb_fetch_talloc failed: %s\n",
+                         strerror(errno));
+               tdb_chainunlock(ctx->wtdb->tdb, key);
+               return map_nt_error_from_unix_common(ret);
+       }
+
+       rec = (struct db_record) {
+               .db = db, .key = key,
+               .value = (struct TDB_DATA) { .dptr = buf,
+                                            .dsize = talloc_get_size(buf) },
+               .storev = db_tdb_storev, .delete_rec = db_tdb_delete,
+               .private_data = ctx
+       };
+
+       fn(&rec, private_data);
+
+       talloc_free(buf);
+
+       tdb_chainunlock(ctx->wtdb->tdb, key);
+
+       return NT_STATUS_OK;
+}
 
 static int db_tdb_exists(struct db_context *db, TDB_DATA key)
 {
@@ -186,6 +234,13 @@ static int db_tdb_wipe(struct db_context *db)
        return tdb_wipe_all(ctx->wtdb->tdb);
 }
 
+static int db_tdb_check(struct db_context *db)
+{
+       struct db_tdb_ctx *ctx = talloc_get_type_abort(
+               db->private_data, struct db_tdb_ctx);
+       return tdb_check(ctx->wtdb->tdb, NULL, NULL);
+}
+
 struct db_tdb_parse_state {
        void (*parser)(TDB_DATA key, TDB_DATA data,
                       void *private_data);
@@ -227,10 +282,12 @@ static NTSTATUS db_tdb_parse(struct db_context *db, TDB_DATA key,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag)
+static NTSTATUS db_tdb_storev(struct db_record *rec,
+                             const TDB_DATA *dbufs, int num_dbufs, int flag)
 {
        struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
                                                       struct db_tdb_ctx);
+       int ret;
 
        /*
         * This has a bug: We need to replace rec->value for correct
@@ -238,8 +295,8 @@ static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag)
         * anymore after it was stored.
         */
 
-       return (tdb_store(ctx->wtdb->tdb, rec->key, data, flag) == 0) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+       ret = tdb_storev(ctx->wtdb->tdb, rec->key, dbufs, num_dbufs, flag);
+       return (ret == 0) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
 static NTSTATUS db_tdb_delete(struct db_record *rec)
@@ -273,7 +330,7 @@ static int db_tdb_traverse_func(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
 
        rec.key = kbuf;
        rec.value = dbuf;
-       rec.store = db_tdb_store;
+       rec.storev = db_tdb_storev;
        rec.delete_rec = db_tdb_delete;
        rec.private_data = ctx->db->private_data;
        rec.db = ctx->db;
@@ -295,7 +352,9 @@ static int db_tdb_traverse(struct db_context *db,
        return tdb_traverse(db_ctx->wtdb->tdb, db_tdb_traverse_func, &ctx);
 }
 
-static NTSTATUS db_tdb_store_deny(struct db_record *rec, TDB_DATA data, int flag)
+static NTSTATUS db_tdb_storev_deny(struct db_record *rec,
+                                  const TDB_DATA *dbufs, int num_dbufs,
+                                  int flag)
 {
        return NT_STATUS_MEDIA_WRITE_PROTECTED;
 }
@@ -314,7 +373,7 @@ static int db_tdb_traverse_read_func(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA d
 
        rec.key = kbuf;
        rec.value = dbuf;
-       rec.store = db_tdb_store_deny;
+       rec.storev = db_tdb_storev_deny;
        rec.delete_rec = db_tdb_delete_deny;
        rec.private_data = ctx->db->private_data;
        rec.db = ctx->db;
@@ -351,6 +410,19 @@ static int db_tdb_transaction_start(struct db_context *db)
        return tdb_transaction_start(db_ctx->wtdb->tdb) ? -1 : 0;
 }
 
+static NTSTATUS db_tdb_transaction_start_nonblock(struct db_context *db)
+{
+       struct db_tdb_ctx *db_ctx =
+               talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+       int ret;
+
+       ret = tdb_transaction_start_nonblock(db_ctx->wtdb->tdb);
+       if (ret != 0) {
+               return map_nt_error_from_tdb(tdb_error(db_ctx->wtdb->tdb));
+       }
+       return NT_STATUS_OK;
+}
+
 static int db_tdb_transaction_commit(struct db_context *db)
 {
        struct db_tdb_ctx *db_ctx =
@@ -366,20 +438,24 @@ static int db_tdb_transaction_cancel(struct db_context *db)
        return 0;
 }
 
-static void db_tdb_id(struct db_context *db, const uint8_t **id, size_t *idlen)
+static size_t db_tdb_id(struct db_context *db, uint8_t *id, size_t idlen)
 {
        struct db_tdb_ctx *db_ctx =
                talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
-       *id = (uint8_t *)&db_ctx->id;
-       *idlen = sizeof(db_ctx->id);
+
+       if (idlen >= sizeof(db_ctx->id)) {
+               memcpy(id, &db_ctx->id, sizeof(db_ctx->id));
+       }
+
+       return sizeof(db_ctx->id);
 }
 
 struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
-                              struct loadparm_context *lp_ctx,
                               const char *name,
                               int hash_size, int tdb_flags,
                               int open_flags, mode_t mode,
-                              enum dbwrap_lock_order lock_order)
+                              enum dbwrap_lock_order lock_order,
+                              uint64_t dbwrap_flags)
 {
        struct db_context *result = NULL;
        struct db_tdb_ctx *db_tdb;
@@ -399,7 +475,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
        result->lock_order = lock_order;
 
        db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, tdb_flags,
-                                    open_flags, mode, lp_ctx);
+                                    open_flags, mode);
        if (db_tdb->wtdb == NULL) {
                DEBUG(3, ("Could not open tdb: %s\n", strerror(errno)));
                goto fail;
@@ -416,23 +492,24 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
 
        result->fetch_locked = db_tdb_fetch_locked;
        result->try_fetch_locked = db_tdb_try_fetch_locked;
+       result->do_locked = db_tdb_do_locked;
        result->traverse = db_tdb_traverse;
        result->traverse_read = db_tdb_traverse_read;
        result->parse_record = db_tdb_parse;
        result->get_seqnum = db_tdb_get_seqnum;
        result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
        result->transaction_start = db_tdb_transaction_start;
+       result->transaction_start_nonblock = db_tdb_transaction_start_nonblock;
        result->transaction_commit = db_tdb_transaction_commit;
        result->transaction_cancel = db_tdb_transaction_cancel;
        result->exists = db_tdb_exists;
        result->wipe = db_tdb_wipe;
        result->id = db_tdb_id;
-       result->stored_callback = NULL;
+       result->check = db_tdb_check;
+       result->name = tdb_name(db_tdb->wtdb->tdb);
        return result;
 
  fail:
-       if (result != NULL) {
-               TALLOC_FREE(result);
-       }
+       TALLOC_FREE(result);
        return NULL;
 }