]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
add a control to bump the rsn number for all records in a database
authorRonnie Sahlberg <sahlberg@ronnie>
Fri, 11 May 2007 00:36:47 +0000 (10:36 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Fri, 11 May 2007 00:36:47 +0000 (10:36 +1000)
use this control from the recovery daemon to ensure that the recmaster
always have a higher rsn than andy other node for the records after
recovery completes

(This used to be ctdb commit 6fb6a8b981a804bfcc460c4481c51c7c647230f6)

ctdb/common/ctdb_client.c
ctdb/common/ctdb_control.c
ctdb/common/ctdb_recover.c
ctdb/direct/ctdb_recoverd.c
ctdb/include/ctdb.h
ctdb/include/ctdb_private.h

index ff7528b1417a764d2450f6f354c391f48cd1ac45..9c4d84ad2914afb430ccc652982202473751792c 100644 (file)
@@ -1174,6 +1174,31 @@ int ctdb_ctrl_cleardb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *
        return 0;
 }
 
+/*
+  bump rsn on all records
+ */
+int ctdb_ctrl_bumprsn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid)
+{
+       int ret;
+       TDB_DATA indata, outdata;
+       int32_t res;
+
+       indata.dsize = sizeof(uint32_t);
+       indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 1);
+
+       ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_BUMP_RSN, 0, indata, 
+                          mem_ctx, &outdata, &res, &timeout);
+       if (ret != 0 || res != 0) {
+               DEBUG(0,(__location__ " ctdb_control for bumprsn failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
 /*
   ping a node, return number of clients connected
  */
index c64b873368e4fff8ffec917a3d6f57cca3bdc336..48880f84b0716f198f540dc54ca02c5c31b611a0 100644 (file)
@@ -108,6 +108,10 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
                return ctdb_control_clear_db(ctdb, indata);
 
+       case CTDB_CONTROL_BUMP_RSN: 
+               CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
+               return ctdb_control_bump_rsn(ctdb, indata);
+
        case CTDB_CONTROL_PUSH_DB:
                return ctdb_control_push_db(ctdb, indata);
 
index 047543d4acd6214d3289e56cabb0918adb8997b7..5f5112d11f8a9c33a26795e39cb8e320d0c9c221 100644 (file)
@@ -367,3 +367,41 @@ int32_t ctdb_control_clear_db(struct ctdb_context *ctdb, TDB_DATA indata)
 
        return 0;
 }
+
+static int traverse_bumprsn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p)
+{
+       struct ctdb_ltdb_header *header = (struct ctdb_ltdb_header *)data.dptr;
+       int ret;
+
+       header->rsn++;
+
+       ret = tdb_store(tdb, key, data, TDB_REPLACE);
+       if (ret) {
+               DEBUG(0,(__location__ "failed to write tdb data back  ret:%d\n",ret));
+               return ret;
+       }
+       return 0;
+}
+
+int32_t ctdb_control_bump_rsn(struct ctdb_context *ctdb, TDB_DATA indata)
+{
+       uint32_t dbid = *(uint32_t *)indata.dptr;
+       struct ctdb_db_context *ctdb_db;
+
+       ctdb_db = find_ctdb_db(ctdb, dbid);
+       if (!ctdb_db) {
+               DEBUG(0,(__location__ " Unknown db 0x%08x\n",dbid));
+               return -1;
+       }
+
+       if (tdb_lockall_nonblock(ctdb_db->ltdb->tdb) != 0) {
+               DEBUG(0,(__location__ " Failed to get nonblock lock on entired db - failing\n"));
+               return -1;
+       }       
+
+       tdb_traverse(ctdb_db->ltdb->tdb, traverse_bumprsn, NULL);
+
+       tdb_unlockall(ctdb_db->ltdb->tdb);
+
+       return 0;
+}
index d7de606b1481690ad50aeabba31aaf4de9981cd7..50dfd9eabe9717fe9919cc3120dfdf2d31cc8956 100644 (file)
@@ -255,6 +255,23 @@ static int update_dmaster_on_all_databases(struct ctdb_context *ctdb, struct ctd
 }
 
 
+static int bump_rsn_on_all_databases(struct ctdb_context *ctdb, uint32_t vnn, struct ctdb_dbid_map *dbmap, TALLOC_CTX *mem_ctx)
+{
+       int i, ret;
+
+       /* bump rsn for all records in all databases */
+       for (i=0;i<dbmap->num;i++) {
+               ret = ctdb_ctrl_bumprsn(ctdb, timeval_current_ofs(1, 0), vnn, ctdb, dbmap->dbids[i]);
+               if (ret != 0) {
+                       DEBUG(0, (__location__ "Unable to bump rsn for db:0x%08x\n", dbmap->dbids[i]));
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+
 static int push_all_local_databases(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap, uint32_t vnn, struct ctdb_dbid_map *dbmap, TALLOC_CTX *mem_ctx)
 {
        int i, j, ret;
@@ -448,6 +465,14 @@ static int do_recovery(struct ctdb_context *ctdb, struct event_context *ev,
        }
 
 
+       /* bump the rsn number on all databases
+        */
+       ret = bump_rsn_on_all_databases(ctdb, vnn, dbmap, mem_ctx);
+       if (ret != 0) {
+               DEBUG(0, (__location__ "Unable to bump the rsn on all databases\n"));
+               return -1;
+       }
+
 
        /* disable recovery mode */
        ret = set_recovery_mode(ctdb, nodemap, CTDB_RECOVERY_NORMAL);
index f5e02ebdee118514543c5952f424719ef5f9b8e2..6c94d3574afd3eedcb7ce8ae46b36489e57acf63 100644 (file)
@@ -278,6 +278,11 @@ int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb,
  */
 int ctdb_ctrl_cleardb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid);
 
+/*
+  bump the rsn number for al records
+ */
+int ctdb_ctrl_bumprsn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid);
+
 /*
   write a record on a specific db (this implicitely updates dmaster of the record to locally be the vnn of the node where the control is executed on)
  */
index a22c5c3a5e79a99347b69507ba3604afbf74a80a..b2119b30972bfebd6139afbed39a79e6ede4d491 100644 (file)
@@ -343,6 +343,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS,
                    CTDB_CONTROL_GET_PID,
                    CTDB_CONTROL_GET_RECMASTER,
                    CTDB_CONTROL_SET_RECMASTER,
+                   CTDB_CONTROL_BUMP_RSN,
 };
 
 
@@ -780,5 +781,6 @@ int32_t ctdb_control_pull_db(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DAT
 int32_t ctdb_control_push_db(struct ctdb_context *ctdb, TDB_DATA indata);
 int32_t ctdb_control_set_dmaster(struct ctdb_context *ctdb, TDB_DATA indata);
 int32_t ctdb_control_clear_db(struct ctdb_context *ctdb, TDB_DATA indata);
+int32_t ctdb_control_bump_rsn(struct ctdb_context *ctdb, TDB_DATA indata);
 
 #endif