------------------------------------------------------------
revno: 623
revision-id: [EMAIL PROTECTED]
parent: [EMAIL PROTECTED]
committer: Andrew Tridgell <[EMAIL PROTECTED]>
branch nick: s3-ctdb-tridge
timestamp: Fri 2007-09-21 16:04:09 +1000
message:
  added persistent ctdb support
modified:
  source/include/dbwrap.h        dbwrap.h-20070413105316-iw5xqs7joqzburfk-1
  source/lib/dbwrap_ctdb.c       dbwrap_ctdb.c-20070415131935-89u7zduywa3g216g-1
  source/lib/dbwrap_file.c       dbwrap_file.c-20070413105316-iw5xqs7joqzburfk-3
  source/lib/dbwrap_tdb.c        dbwrap_tdb.c-20070413105316-iw5xqs7joqzburfk-4
  source/lib/messages.c          messages.c-20070210173807-1wjifrbwaz6xnmgl-491
=== modified file 'source/include/dbwrap.h'
--- a/source/include/dbwrap.h   2007-05-17 12:44:40 +0000
+++ b/source/include/dbwrap.h   2007-09-21 06:04:09 +0000
@@ -44,6 +44,7 @@
                             void *private_data);
        int (*get_seqnum)(struct db_context *db);
        void *private_data;
+       bool persistent;
 };
 
 struct db_context *db_open(TALLOC_CTX *mem_ctx,

=== modified file 'source/lib/dbwrap_ctdb.c'
--- a/source/lib/dbwrap_ctdb.c  2007-08-30 12:33:50 +0000
+++ b/source/lib/dbwrap_ctdb.c  2007-09-21 06:04:09 +0000
@@ -55,6 +55,41 @@
        return (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
 }
 
+/* for persistent databases the store is a bit different. We have to
+   ask the ctdb daemon to push the record to all nodes after the
+   store */
+static NTSTATUS db_ctdb_store_persistent(struct db_record *rec, TDB_DATA data, 
int flag)
+{
+       struct db_ctdb_rec *crec = talloc_get_type_abort(
+               rec->private_data, struct db_ctdb_rec);
+       TDB_DATA cdata;
+       int ret;
+       NTSTATUS status;
+
+       cdata.dsize = sizeof(crec->header) + data.dsize;
+
+       if (!(cdata.dptr = SMB_MALLOC_ARRAY(uint8, cdata.dsize))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       crec->header.rsn++;
+
+       memcpy(cdata.dptr, &crec->header, sizeof(crec->header));
+       memcpy(cdata.dptr + sizeof(crec->header), data.dptr, data.dsize);
+
+       ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, cdata, 
TDB_REPLACE);
+       status = (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
+       
+       /* now tell ctdbd to update this record on all other nodes */
+       if (NT_STATUS_IS_OK(status)) {
+               status = ctdbd_persistent_store(crec->ctdb_ctx->db_id, 
rec->key, cdata);
+       }
+
+       SAFE_FREE(cdata.dptr);
+
+       return status;
+}
+
 static NTSTATUS db_ctdb_delete(struct db_record *rec)
 {
        struct db_ctdb_rec *crec = talloc_get_type_abort(
@@ -141,7 +176,11 @@
                return NULL;
        }
 
-       result->store = db_ctdb_store;
+       if (db->persistent) {
+               result->store = db_ctdb_store_persistent;
+       } else {
+               result->store = db_ctdb_store;
+       }
        result->delete_rec = db_ctdb_delete;
        talloc_set_destructor(result, db_ctdb_record_destr);
 
@@ -392,6 +431,7 @@
        result->traverse = db_ctdb_traverse;
        result->traverse_read = db_ctdb_traverse_read;
        result->get_seqnum = db_ctdb_get_seqnum;
+       result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
 
        DEBUG(3,("db_open_ctdb: opened database '%s' with dbid 0x%x\n",
                 name, db_ctdb->db_id));

=== modified file 'source/lib/dbwrap_file.c'
--- a/source/lib/dbwrap_file.c  2007-05-17 12:44:40 +0000
+++ b/source/lib/dbwrap_file.c  2007-09-21 06:04:09 +0000
@@ -364,6 +364,7 @@
        result->fetch_locked = db_file_fetch_locked;
        result->traverse = db_file_traverse;
        result->traverse_read = db_file_traverse;
+       result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
 
        ctx->locked_record = NULL;
        if (!(ctx->dirname = talloc_strdup(ctx, name))) {

=== modified file 'source/lib/dbwrap_tdb.c'
--- a/source/lib/dbwrap_tdb.c   2007-06-03 03:51:12 +0000
+++ b/source/lib/dbwrap_tdb.c   2007-09-21 06:04:09 +0000
@@ -247,6 +247,7 @@
        result->traverse = db_tdb_traverse;
        result->traverse_read = db_tdb_traverse_read;
        result->get_seqnum = db_tdb_get_seqnum;
+       result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
        return result;
 
  fail:

=== modified file 'source/lib/messages.c'
--- a/source/lib/messages.c     2007-09-19 03:05:17 +0000
+++ b/source/lib/messages.c     2007-09-21 06:04:09 +0000
@@ -1892,5 +1892,40 @@
 }
 
 
+/*
+  persstent store. Used when we update a record in a persistent database
+ */
+NTSTATUS ctdbd_persistent_store(uint32_t db_id, TDB_DATA key, TDB_DATA data)
+{
+       int cstatus=0;
+       struct ctdb_rec_data *rec;
+       TDB_DATA recdata;
+       size_t length;
+       NTSTATUS status;
+
+       length = offsetof(struct ctdb_rec_data, data) + key.dsize + data.dsize;
+
+       rec = (struct ctdb_rec_data *)talloc_size(ctdbd_ctx, length);
+       NT_STATUS_HAVE_NO_MEMORY(rec);
+
+       rec->length = length;
+       rec->reqid  = db_id;
+       rec->keylen = key.dsize;
+       rec->datalen= data.dsize;
+       memcpy(&rec->data[0], key.dptr, key.dsize);
+       memcpy(&rec->data[key.dsize], data.dptr, data.dsize);
+
+       recdata.dptr  = (uint8_t *)rec;
+       recdata.dsize = length;
+
+       status = ctdbd_control(ctdbd_ctx, CTDB_CURRENT_NODE, 
+                              CTDB_CONTROL_PERSISTENT_STORE, 
+                              0, recdata, NULL, NULL, &cstatus);
+       if (cstatus != 0) {
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+       return status;
+}
+
 /** @} **/
 

Reply via email to