From: Andrew Tridgell Date: Fri, 4 May 2007 02:18:39 +0000 (+1000) Subject: nicer interface to ctdb traverse X-Git-Tag: tevent-0.9.20~348^2~2785 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f2fd53056dd2d9ce06a80a10f92d8495806875cd;p=thirdparty%2Fsamba.git nicer interface to ctdb traverse (This used to be ctdb commit e5ce866dcc5037b5069e42bf1e168b646f007b01) --- diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index ee195569183..eb1b9529193 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -1397,55 +1397,26 @@ int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id) } -/* - start a cluster wide traverse. each record is sent as a message to - the given srvid - */ -int ctdb_traverse_all(struct ctdb_db_context *ctdb_db, uint64_t srvid) -{ - TDB_DATA data; - struct ctdb_traverse_start t; - int32_t status; - int ret; - - t.db_id = ctdb_db->db_id; - t.srvid = srvid; - t.reqid = 0; - - data.dptr = (uint8_t *)&t; - data.dsize = sizeof(t); - - ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START, 0, - data, NULL, NULL, &status, NULL); - if (ret != 0 || status != 0) { - DEBUG(0,("ctdb_traverse_all failed\n")); - return -1; - } - - return 0; -} - -struct list_keys_state { - FILE *f; +struct traverse_state { bool done; uint32_t count; + ctdb_traverse_func fn; + void *private_data; }; /* - called on each key during a list_keys + called on each key during a ctdb_traverse */ -static void list_keys_handler(struct ctdb_context *ctdb, uint64_t srvid, - TDB_DATA data, void *p) +static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p) { - struct list_keys_state *state = (struct list_keys_state *)p; + struct traverse_state *state = (struct traverse_state *)p; struct ctdb_traverse_data *d = (struct ctdb_traverse_data *)data.dptr; TDB_DATA key; - char *keystr, *datastr; - struct ctdb_ltdb_header *h; if (data.dsize < sizeof(uint32_t) || d->length != data.dsize) { - DEBUG(0,("Bad data size %u in list_keys_handler\n", data.dsize)); + DEBUG(0,("Bad data size %u in traverse_handler\n", data.dsize)); + state->done = True; return; } @@ -1460,46 +1431,52 @@ static void list_keys_handler(struct ctdb_context *ctdb, uint64_t srvid, return; } - h = (struct ctdb_ltdb_header *)data.dptr; - if (data.dsize < sizeof(struct ctdb_ltdb_header)) { - DEBUG(0,("Bad ctdb ltdb header in list_keys_handler\n")); - return; + if (state->fn(ctdb, key, data, state->private_data) != 0) { + state->done = True; } - - - keystr = hex_encode(ctdb, key.dptr, key.dsize); - datastr = hex_encode(ctdb, data.dptr+sizeof(*h), data.dsize-sizeof(*h)); - - fprintf(state->f, "dmaster: %u\n", h->dmaster); - fprintf(state->f, "rsn: %llu\n", (unsigned long long)h->rsn); - fprintf(state->f, "key: %s\ndata: %s\n", keystr, datastr); - - talloc_free(keystr); - talloc_free(datastr); state->count++; } + /* - convenience function to list all keys to stdout + start a cluster wide traverse, calling the supplied fn on each record + return the number of records traversed, or -1 on error */ -int ctdb_list_keys(struct ctdb_db_context *ctdb_db, FILE *f) +int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data) { + TDB_DATA data; + struct ctdb_traverse_start t; + int32_t status; int ret; uint64_t srvid = (getpid() | 0xFLL<<60); - struct list_keys_state state; + struct traverse_state state; - state.f = f; state.done = False; state.count = 0; + state.private_data = private_data; + state.fn = fn; - ret = ctdb_set_message_handler(ctdb_db->ctdb, srvid, list_keys_handler, &state); + ret = ctdb_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state); if (ret != 0) { - DEBUG(0,("Failed to setup list keys handler\n")); + DEBUG(0,("Failed to setup traverse handler\n")); return -1; } - ret = ctdb_traverse_all(ctdb_db, srvid); + t.db_id = ctdb_db->db_id; + t.srvid = srvid; + t.reqid = 0; + + data.dptr = (uint8_t *)&t; + data.dsize = sizeof(t); + + ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START, 0, + data, NULL, NULL, &status, NULL); + if (ret != 0 || status != 0) { + DEBUG(0,("ctdb_traverse_all failed\n")); + ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state); + return -1; + } while (!state.done) { event_loop_once(ctdb_db->ctdb->ev); @@ -1507,9 +1484,39 @@ int ctdb_list_keys(struct ctdb_db_context *ctdb_db, FILE *f) ret = ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state); if (ret != 0) { - DEBUG(0,("Failed to remove list keys handler\n")); + DEBUG(0,("Failed to remove ctdb_traverse handler\n")); return -1; } return state.count; } + +/* + called on each key during a catdb + */ +static int dumpdb_fn(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p) +{ + FILE *f = (FILE *)p; + char *keystr, *datastr; + struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr; + + keystr = hex_encode(ctdb, key.dptr, key.dsize); + datastr = hex_encode(ctdb, data.dptr+sizeof(*h), data.dsize-sizeof(*h)); + + fprintf(f, "dmaster: %u\n", h->dmaster); + fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn); + fprintf(f, "key: %s\ndata: %s\n", keystr, datastr); + + talloc_free(keystr); + talloc_free(datastr); + return 0; +} + +/* + convenience function to list all keys to stdout + */ +int ctdb_dump_db(struct ctdb_db_context *ctdb_db, FILE *f) +{ + return ctdb_traverse(ctdb_db, dumpdb_fn, f); +} + diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index 93e75af6737..14abd29053c 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -287,6 +287,9 @@ int ctdb_status_reset(struct ctdb_context *ctdb, uint32_t destnode); int ctdb_set_logfile(struct ctdb_context *ctdb, const char *logfile); -int ctdb_list_keys(struct ctdb_db_context *ctdb_db, FILE *f); +typedef int (*ctdb_traverse_func)(struct ctdb_context *, TDB_DATA, TDB_DATA, void *); +int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data); + +int ctdb_dump_db(struct ctdb_db_context *ctdb_db, FILE *f); #endif diff --git a/ctdb/tests/ctdb_test.c b/ctdb/tests/ctdb_test.c index 2e765368049..a57375b140a 100644 --- a/ctdb/tests/ctdb_test.c +++ b/ctdb/tests/ctdb_test.c @@ -176,7 +176,7 @@ int main(int argc, const char *argv[]) } talloc_free(call.reply_data.dptr); - ctdb_list_keys(ctdb_db, stdout); + ctdb_dump_db(ctdb_db, stdout); /* go into a wait loop to allow other nodes to complete */ ctdb_shutdown(ctdb); diff --git a/ctdb/tests/ctdbd.sh b/ctdb/tests/ctdbd.sh index 53857e2442b..1664a68d639 100755 --- a/ctdb/tests/ctdbd.sh +++ b/ctdb/tests/ctdbd.sh @@ -8,7 +8,6 @@ $VALGRIND bin/ctdbd --nlist direct/nodes.txt echo "Testing ping" $VALGRIND bin/ctdb_control ping || exit 1 -exit 0 echo "Testing status" $VALGRIND bin/ctdb_control status all || exit 1 diff --git a/ctdb/tools/ctdb_control.c b/ctdb/tools/ctdb_control.c index 1961572a530..09414d478a3 100644 --- a/ctdb/tools/ctdb_control.c +++ b/ctdb/tools/ctdb_control.c @@ -46,7 +46,7 @@ static void usage(void) " getdbmap lists databases on a node\n" " getnodemap lists nodes known to a ctdb daemon\n" " createdb create a database\n" - " catdb lists all keys in a remote tdb\n" + " catdb lists all keys/data in a db\n" " cpdb lists all keys in a remote tdb\n" " setdmaster sets new dmaster for all records in the database\n" " cleardb deletes all records in a db\n" @@ -508,43 +508,33 @@ static int control_setrecmode(struct ctdb_context *ctdb, int argc, const char ** } /* - display remote list of keys for a tdb + display remote list of keys/data for a db */ static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv) { - uint32_t vnn, dbid; - int i, j, ret; - struct ctdb_key_list keys; - TALLOC_CTX *mem_ctx; + uint32_t dbid; + struct ctdb_db_context *ctdb_db; + int ret; - if (argc < 2) { + if (argc < 1) { usage(); } - vnn = strtoul(argv[0], NULL, 0); - dbid = strtoul(argv[1], NULL, 0); - - mem_ctx = talloc_new(ctdb); - ret = ctdb_ctrl_pulldb(ctdb, vnn, dbid, CTDB_LMASTER_ANY, mem_ctx, &keys); - if (ret != 0) { - printf("Unable to get keys from node %u\n", vnn); - return ret; + dbid = strtoul(argv[0], NULL, 0); + + ctdb_db = find_ctdb_db(ctdb, dbid); + if (ctdb_db == NULL) { + printf("Unable to find database 0x%x\n", dbid); + return -1; } - printf("Number of keys:%d in dbid:0x%08x\n",keys.num,keys.dbid); - for(i=0;i