]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
nicer interface to ctdb traverse
authorAndrew Tridgell <tridge@samba.org>
Fri, 4 May 2007 02:18:39 +0000 (12:18 +1000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 4 May 2007 02:18:39 +0000 (12:18 +1000)
(This used to be ctdb commit e5ce866dcc5037b5069e42bf1e168b646f007b01)

ctdb/common/ctdb_client.c
ctdb/include/ctdb.h
ctdb/tests/ctdb_test.c
ctdb/tests/ctdbd.sh
ctdb/tools/ctdb_control.c

index ee195569183f029198a421dfc82d3c0301262c6d..eb1b9529193c63806348d2729f8505b54853bcf2 100644 (file)
@@ -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);
+}
+
index 93e75af673746652597b0c22a001dbf5c34fa65a..14abd29053cabb16269b38da88c920e0e9d20cf8 100644 (file)
@@ -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
index 2e765368049a9ca3030af63338eacbafd6244bec..a57375b140a26e100643a99ca3de6c82ad628c39 100644 (file)
@@ -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);
index 53857e2442b87fbe6b467f328e9c1384177dfcde..1664a68d639aa13032448283f82cb70066c32fb0 100755 (executable)
@@ -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
index 1961572a5301944c251d00bf48a5ba9ac17021cf..09414d478a3d6bd1aed9db246c31dcc36b7475e5 100644 (file)
@@ -46,7 +46,7 @@ static void usage(void)
                "  getdbmap <vnn>                     lists databases on a node\n"
                "  getnodemap <vnn>                   lists nodes known to a ctdb daemon\n"
                "  createdb <vnn> <dbname>            create a database\n"
-               "  catdb <vnn> <dbid>                 lists all keys in a remote tdb\n"
+               "  catdb <dbid>                       lists all keys/data in a db\n"
                "  cpdb <fromvnn> <tovnn> <dbid>      lists all keys in a remote tdb\n"
                "  setdmaster <vnn> <dbid> <dmaster>  sets new dmaster for all records in the database\n"
                "  cleardb <vnn> <dbid>               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<keys.num;i++){
-               printf("key:");
-               for(j=0;j<keys.keys[i].dsize;j++){
-                       printf("%02x",keys.keys[i].dptr[j]);
-               }
-               printf(" lmaster:%d rsn:%llu dmaster:%d laccessor:%d lacount:%d",keys.lmasters[i],keys.headers[i].rsn,keys.headers[i].dmaster,keys.headers[i].laccessor,keys.headers[i].lacount);
-               printf(" data:");       
-               for(j=0;j<keys.data[i].dsize;j++){
-                       printf("%02x",keys.data[i].dptr[j]);
-               }
-               printf("\n");
+
+       ret = ctdb_dump_db(ctdb_db, stdout);
+       if (ret == -1) {
+               printf("Unable to dump database\n");
+               return -1;
        }
 
-       talloc_free(mem_ctx);
+       printf("Dumped %d records\n", ret);
        return 0;
 }