From: Ronnie Sahlberg Date: Sun, 29 Apr 2007 08:34:11 +0000 (+1000) Subject: add a new control to set all records in a database to a new dmaster X-Git-Tag: tevent-0.9.20~348^2~2800^2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c0b0b4a0f5073323b8b9ca2a2154f1691a0b49a4;p=thirdparty%2Fsamba.git add a new control to set all records in a database to a new dmaster (This used to be ctdb commit fd0d2385206b0329b74d908f3bdf89d3f32095d1) --- diff --git a/ctdb/common/cmdline.c b/ctdb/common/cmdline.c index 988fee81e84..0487406a8ad 100644 --- a/ctdb/common/cmdline.c +++ b/ctdb/common/cmdline.c @@ -134,7 +134,7 @@ XXX table for the daemons. exit(1); } ctdb->vnn_map->generation = 1; - ctdb->vnn_map->size = 1024; + ctdb->vnn_map->size = ctdb->num_nodes; ctdb->vnn_map->map = talloc_array(ctdb->vnn_map, uint32_t, ctdb->vnn_map->size); if (ctdb->vnn_map->map == NULL) { DEBUG(0,(__location__ " Unable to allocate vnn_map->map structure\n")); diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index 178624bce22..b6a3963a497 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -958,6 +958,32 @@ int ctdb_getkeys(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid, TA return 0; } +/* + change dmaster for all keys in the database to the new value + */ +int ctdb_setdmaster(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster) +{ + 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] = dmaster; + + ret = ctdb_control(ctdb, destnode, 0, + CTDB_CONTROL_SET_DMASTER, indata, + mem_ctx, &outdata, &res); + if (ret != 0 || res != 0) { + DEBUG(0,(__location__ " ctdb_control for setdmaster failed\n")); + return -1; + } + + return 0; +} + /* ping a node */ diff --git a/ctdb/common/ctdb_control.c b/ctdb/common/ctdb_control.c index 7141d20ae8c..903722a1846 100644 --- a/ctdb/common/ctdb_control.c +++ b/ctdb/common/ctdb_control.c @@ -43,6 +43,22 @@ struct ctdb_control_state { } while (0) +static int traverse_setdmaster(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p) +{ + uint32_t *dmaster = (uint32_t *)p; + struct ctdb_ltdb_header *header = (struct ctdb_ltdb_header *)data.dptr; + int ret; + + header->dmaster = *dmaster; + + 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; +} + struct getkeys_params { struct ctdb_db_context *ctdb_db; TDB_DATA *outdata; @@ -54,7 +70,7 @@ static int traverse_getkeys(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data TDB_DATA *outdata = talloc_get_type(params->outdata, TDB_DATA); struct ctdb_db_context *ctdb_db = talloc_get_type(params->ctdb_db, struct ctdb_db_context); unsigned char *ptr; - int len, ret; + int len; len=outdata->dsize; len+=4; /*lmaster*/ @@ -250,6 +266,36 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, return 0; } + case CTDB_CONTROL_SET_DMASTER: { + uint32_t dbid, dmaster; + struct ctdb_db_context *ctdb_db; + struct tdb_wrap *db; + + 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; + } + + dmaster = ((uint32_t *)(&indata.dptr[0]))[1]; + + outdata->dsize = 0; + outdata->dptr = NULL; + + db = tdb_wrap_open(NULL, ctdb_db->db_path, 0, TDB_DEFAULT, O_RDONLY, 0); + if (db == NULL) { + DEBUG(0,(__location__ " failed to open db\n")); + return -1; + } + + tdb_traverse(db->tdb, traverse_setdmaster, &dmaster); + + talloc_free(db); + + 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 3e666de06bb..ef38582f3cd 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -261,4 +261,9 @@ int ctdb_get_config(struct ctdb_context *ctdb); int ctdb_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *level); int ctdb_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, uint32_t level); +/* + change dmaster for all keys in the database to the new value + */ +int ctdb_setdmaster(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster); + #endif diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 7c6fa8ee238..f1d414efb67 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -255,7 +255,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS, CTDB_CONTROL_SET_DEBUG, CTDB_CONTROL_GET_DBMAP, CTDB_CONTROL_GET_NODEMAP, - CTDB_CONTROL_GET_KEYS}; + CTDB_CONTROL_GET_KEYS, + CTDB_CONTROL_SET_DMASTER}; 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 35cd6ea96f3..c5f28eb87ca 100644 --- a/ctdb/tools/ctdb_control.c +++ b/ctdb/tools/ctdb_control.c @@ -43,6 +43,7 @@ static void usage(void) printf(" getdbmap lists databases on a node\n"); printf(" getnodemap lists nodes known to a ctdb daemon\n"); printf(" getkeys lists all keys in a remote tdb\n"); + printf(" setdmaster sets new dmaster for all records in the database\n"); exit(1); } @@ -296,6 +297,30 @@ static int control_setvnnmap(struct ctdb_context *ctdb, int argc, const char **a return 0; } +/* + set the dmaster for all records in a database + */ +static int control_setdmaster(struct ctdb_context *ctdb, int argc, const char **argv) +{ + uint32_t vnn, dbid, dmaster; + int ret; + + if (argc < 2) { + usage(); + } + + vnn = strtoul(argv[0], NULL, 0); + dbid = strtoul(argv[1], NULL, 0); + dmaster = strtoul(argv[2], NULL, 0); + + ret = ctdb_setdmaster(ctdb, vnn, ctdb, dbid, dmaster); + if (ret != 0) { + printf("Unable to set dmaster for node %u db:0x%08x\n", vnn, dbid); + return ret; + } + return 0; +} + /* ping all node */ @@ -424,6 +449,8 @@ int main(int argc, const char *argv[]) ret = control_getkeys(ctdb, extra_argc-1, extra_argv+1); } else if (strcmp(control, "setvnnmap") == 0) { ret = control_setvnnmap(ctdb, extra_argc-1, extra_argv+1); + } else if (strcmp(control, "setdmaster") == 0) { + ret = control_setdmaster(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) {