summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonnie Sahlberg <sahlberg@ronnie>2007-04-29 22:14:51 +1000
committerRonnie Sahlberg <sahlberg@ronnie>2007-04-29 22:14:51 +1000
commit1af701291f8a6b8a04ed201ff862e1a7813dff05 (patch)
tree0e17cf0cc558d57fa579532b67e694c9433bd3be
parent376a3ea85224f805ad12c245f01c96b7b188cd9b (diff)
implement a control to pull a database from a remote node
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)
-rw-r--r--ctdb/common/ctdb_client.c26
-rw-r--r--ctdb/common/ctdb_control.c43
-rw-r--r--ctdb/include/ctdb.h5
-rw-r--r--ctdb/include/ctdb_private.h3
-rw-r--r--ctdb/tools/ctdb_control.c27
5 files changed, 103 insertions, 1 deletions
diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c
index 990c3d4ddd..4dd21ecc59 100644
--- a/ctdb/common/ctdb_client.c
+++ b/ctdb/common/ctdb_client.c
@@ -1010,6 +1010,32 @@ int ctdb_cleardb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_c
}
/*
+ 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
*/
int ctdb_ping(struct ctdb_context *ctdb, uint32_t destnode)
diff --git a/ctdb/common/ctdb_control.c b/ctdb/common/ctdb_control.c
index eab6cf5af4..b26d84ac57 100644
--- a/ctdb/common/ctdb_control.c
+++ b/ctdb/common/ctdb_control.c
@@ -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;
diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h
index bf8643f22d..f7eb16b75e 100644
--- a/ctdb/include/ctdb.h
+++ b/ctdb/include/ctdb.h
@@ -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
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index 5207bea970..ce47f9948d 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -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};
diff --git a/ctdb/tools/ctdb_control.c b/ctdb/tools/ctdb_control.c
index f96fad8af1..4fb3ff80de 100644
--- a/ctdb/tools/ctdb_control.c
+++ b/ctdb/tools/ctdb_control.c
@@ -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);
}
@@ -346,6 +347,30 @@ static int control_cleardb(struct ctdb_context *ctdb, int argc, const char **arg
}
/*
+ 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
*/
static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
@@ -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) {