]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
implement a control to pull a database from a remote node
authorRonnie Sahlberg <sahlberg@ronnie>
Sun, 29 Apr 2007 12:14:51 +0000 (22:14 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Sun, 29 Apr 2007 12:14:51 +0000 (22:14 +1000)
it does not yet work since ctdb_control can right now only be called
from client context and the pull is implemented as the target ctdb node
itself using a get_keys to pull the keys from the source node   thus
ctdb daemon needs to ctdb_control to a remote node

(This used to be ctdb commit a55c7c64b4ff87f54b90649c9f469b1ff36dc9ea)

ctdb/common/ctdb_client.c
ctdb/common/ctdb_control.c
ctdb/include/ctdb.h
ctdb/include/ctdb_private.h
ctdb/tools/ctdb_control.c

index 990c3d4dddc0b571bac2b29b4cf82cbd0a8b705d..4dd21ecc599a42ca16e850d265b4b361ce5b7d02 100644 (file)
@@ -1009,6 +1009,32 @@ int ctdb_cleardb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_c
        return 0;
 }
 
+/*
+  pull a db from a remote node
+ */
+int ctdb_pulldb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t from_vnn)
+{
+       int ret;
+       TDB_DATA indata, outdata;
+       int32_t res;
+
+       indata.dsize = 2*sizeof(uint32_t);
+       indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
+
+       ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
+       ((uint32_t *)(&indata.dptr[0]))[1] = from_vnn;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_PULL_DB, indata, 
+                          mem_ctx, &outdata, &res);
+       if (ret != 0 || res != 0) {
+               DEBUG(0,(__location__ " ctdb_control for pulldb failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
 /*
   ping a node
  */
index eab6cf5af4493cfaf2f78b1e58ce4116dd51648d..b26d84ac57143fbb6882f287ed9fdad3671d6f0d 100644 (file)
@@ -311,6 +311,49 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                return 0;
        }
 
+       case CTDB_CONTROL_PULL_DB: {
+               uint32_t dbid, from_vnn;
+               struct ctdb_db_context *ctdb_db;
+               struct ctdb_key_list keys;
+               int i, ret;
+
+               dbid = ((uint32_t *)(&indata.dptr[0]))[0];
+               ctdb_db = find_ctdb_db(ctdb, dbid);
+               if (!ctdb_db) {
+                       DEBUG(0,(__location__ " Unknown db 0x%08x\n",dbid));
+                       return -1;
+               }
+
+               from_vnn = ((uint32_t *)(&indata.dptr[0]))[1];
+
+               outdata->dsize = 0;
+               outdata->dptr = NULL;
+
+               ret = ctdb_getkeys(ctdb, from_vnn, dbid, outdata, &keys);
+               if (ret != 0) {
+                       DEBUG(0, (__location__ "Unable to pull keys from node %u\n", from_vnn));
+                       return -1;
+               }
+               
+               for(i=0;i<keys.num;i++){
+                       ret = ctdb_ltdb_lock(ctdb_db, keys.keys[i]);
+                       if (ret != 0) {
+                               DEBUG(0, (__location__ "Unable to lock db\n"));
+                               ctdb_ltdb_unlock(ctdb_db, keys.keys[i]);
+                               return -1;
+                       }
+                       ret = ctdb_ltdb_store(ctdb_db, keys.keys[i], &keys.headers[i], keys.data[i]);
+                       if (ret != 0) {
+                               DEBUG(0, (__location__ "Unable to store record\n"));
+                               ctdb_ltdb_unlock(ctdb_db, keys.keys[i]);
+                               return -1;
+                       }
+                       ctdb_ltdb_unlock(ctdb_db, keys.keys[i]);
+               }
+
+               return 0;
+       }
+
        case CTDB_CONTROL_CONFIG: {
                CHECK_CONTROL_DATA_SIZE(0);
                outdata->dptr = (uint8_t *)ctdb;
index bf8643f22dd027824e0aff33dadb1a73b6caf4ed..f7eb16b75e5e3f3b1d1dc2bad96696759e07ac1a 100644 (file)
@@ -271,4 +271,9 @@ int ctdb_setdmaster(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *me
  */
 int ctdb_cleardb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid);
 
+/*
+  pull a db from a remote node
+ */
+int ctdb_pulldb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t from_vnn);
+
 #endif
index 5207bea9709eda43ef43500b73753e10da43cea8..ce47f9948dacc66cfef9b39c4cd724f0a46af200 100644 (file)
@@ -257,7 +257,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS,
                    CTDB_CONTROL_GET_NODEMAP,
                    CTDB_CONTROL_GET_KEYS,
                    CTDB_CONTROL_SET_DMASTER,
-                   CTDB_CONTROL_CLEAR_DB};
+                   CTDB_CONTROL_CLEAR_DB,
+                   CTDB_CONTROL_PULL_DB};
 
 enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
 
index f96fad8af1efbb6467a676b4a153c08af21b075f..4fb3ff80decc0df691e3b518154fe37cc25f6ac3 100644 (file)
@@ -45,6 +45,7 @@ static void usage(void)
        printf("  getkeys <vnn> <dbid>               lists all keys in a remote tdb\n");
        printf("  setdmaster <vnn> <dbid> <dmaster>  sets new dmaster for all records in the database\n");
        printf("  cleardb <vnn> <dbid>               deletes all records in a db\n");
+       printf("  pulldb <vnn> <dbid> <from vnn>     pull a db from a remote node\n");
        exit(1);
 }
 
@@ -345,6 +346,30 @@ static int control_cleardb(struct ctdb_context *ctdb, int argc, const char **arg
        return 0;
 }
 
+/*
+  pull all records from a remote database to the local node
+ */
+static int control_pulldb(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       uint32_t vnn, dbid, fromvnn;
+       int ret;
+
+       if (argc < 3) {
+               usage();
+       }
+
+       vnn     = strtoul(argv[0], NULL, 0);
+       dbid    = strtoul(argv[1], NULL, 0);
+       fromvnn = strtoul(argv[2], NULL, 0);
+
+       ret = ctdb_pulldb(ctdb, vnn, ctdb, dbid, fromvnn);
+       if (ret != 0) {
+               printf("Unable to pull db for node %u db:0x%08x\n", vnn, dbid);
+               return ret;
+       }
+       return 0;
+}
+
 /*
   ping all node
  */
@@ -477,6 +502,8 @@ int main(int argc, const char *argv[])
                ret = control_setdmaster(ctdb, extra_argc-1, extra_argv+1);
        } else if (strcmp(control, "cleardb") == 0) {
                ret = control_cleardb(ctdb, extra_argc-1, extra_argv+1);
+       } else if (strcmp(control, "pulldb") == 0) {
+               ret = control_pulldb(ctdb, extra_argc-1, extra_argv+1);
        } else if (strcmp(control, "ping") == 0) {
                ret = control_ping(ctdb, extra_argc-1, extra_argv+1);
        } else if (strcmp(control, "debug") == 0) {