]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
add a control to read an entire tdb from a node including
authorRonnie Sahlberg <sahlberg@ronnie>
Sat, 28 Apr 2007 19:47:13 +0000 (05:47 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Sat, 28 Apr 2007 19:47:13 +0000 (05:47 +1000)
key/lmaster/header and data

(This used to be ctdb commit ac00d6271ba6356c1edf804df44d0d2600791610)

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

index 415d38b0fcee372b69e0c89908cc9f72396ed6e2..178624bce22c8d49280188ac97321d28235d054c 100644 (file)
@@ -896,6 +896,68 @@ int ctdb_setvnnmap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_vnn
        return 0;
 }
 
+/*
+  get all keys for a specific database
+ */
+int ctdb_getkeys(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx, struct ctdb_key_list *keys)
+{
+       int i, ret;
+       TDB_DATA indata, outdata;
+       int32_t res;
+       unsigned char *ptr;
+
+       indata.dsize = sizeof(uint32_t);
+       indata.dptr = (unsigned char *)&dbid;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_KEYS, indata, 
+                          mem_ctx, &outdata, &res);
+       if (ret != 0 || res != 0) {
+               DEBUG(0,(__location__ " ctdb_control for getkeys failed\n"));
+               return -1;
+       }
+
+
+       keys->num= *((uint32_t *)(&outdata.dptr[0]));
+       keys->keys=talloc_array(mem_ctx, TDB_DATA, keys->num);
+       keys->headers=talloc_array(mem_ctx, struct ctdb_ltdb_header, keys->num);
+       keys->lmasters=talloc_array(mem_ctx, uint32_t, keys->num);
+       keys->data=talloc_array(mem_ctx, TDB_DATA, keys->num);
+
+       /* loop over all key/data pairs */
+       ptr=&outdata.dptr[4];
+       for(i=0;i<keys->num;i++){
+               uint32_t len;
+               TDB_DATA *key, *data;
+
+               keys->lmasters[i]= *((uint32_t *)ptr);
+               ptr+=4;
+
+               key=&keys->keys[i];
+               key->dsize= *((uint32_t *)ptr);
+               ptr+=4;
+               key->dptr=talloc_size(mem_ctx, key->dsize);
+               memcpy(key->dptr, ptr, key->dsize);
+               len = (key->dsize+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+               ptr+=len;
+
+               memcpy(&keys->headers[i], ptr, sizeof(struct ctdb_ltdb_header));
+               len = (sizeof(struct ctdb_ltdb_header)+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+               ptr+=len;
+
+               data=&keys->data[i];
+               data->dsize= *((uint32_t *)ptr);
+               ptr+=4;
+               data->dptr=talloc_size(mem_ctx, data->dsize);
+               memcpy(data->dptr, ptr, data->dsize);
+               len = (data->dsize+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+               ptr+=len;
+
+       }
+
+       return 0;
+}
+
 /*
   ping a node
  */
index 83bac958e06ff9d0cab2696cc79219db99ea121f..7141d20ae8cf93553de2860ac845d763174f8b50 100644 (file)
@@ -25,6 +25,7 @@
 #include "system/wait.h"
 #include "../include/ctdb_private.h"
 #include "lib/util/dlinklist.h"
+#include "db_wrap.h"
 
 struct ctdb_control_state {
        struct ctdb_context *ctdb;
@@ -41,6 +42,56 @@ struct ctdb_control_state {
  } \
  } while (0)
 
+
+struct getkeys_params {
+       struct ctdb_db_context *ctdb_db;
+       TDB_DATA *outdata;
+};
+
+static int traverse_getkeys(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p)
+{
+       struct getkeys_params *params = (struct getkeys_params *)p;
+       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;
+
+       len=outdata->dsize;
+       len+=4; /*lmaster*/
+       len+=4; /*key len*/
+       len+=key.dsize;
+       len=(len+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+       len+=sizeof(struct ctdb_ltdb_header);
+       len=(len+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+       len+=4; /*data len */
+       len+=data.dsize;
+       len=(len+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+
+       ptr=outdata->dptr=talloc_realloc_size(outdata, outdata->dptr, len);
+       ptr+=outdata->dsize;
+       outdata->dsize=len;
+       /* number of records is stored as the first 4 bytes */
+       (*((uint32_t *)(&outdata->dptr[0])))++;
+
+       *((uint32_t *)ptr)=ctdb_lmaster(ctdb_db->ctdb, &key);
+       ptr+=4;
+
+       *((uint32_t *)ptr)=key.dsize;
+       ptr+=4;
+       memcpy(ptr, key.dptr, key.dsize);
+       ptr+= (key.dsize+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+
+       memcpy(ptr, data.dptr, sizeof(struct ctdb_ltdb_header));
+       ptr+=(sizeof(struct ctdb_ltdb_header)+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+
+       *((uint32_t *)ptr)=data.dsize-sizeof(struct ctdb_ltdb_header);
+       ptr+=4;
+       memcpy(ptr, data.dptr+sizeof(struct ctdb_ltdb_header), data.dsize-sizeof(struct ctdb_ltdb_header));
+       ptr+= (data.dsize-sizeof(struct ctdb_ltdb_header)+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
+
+       return 0;
+}
+
 /*
   process a control request
  */
@@ -167,6 +218,38 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                return 0;
        }
 
+       case CTDB_CONTROL_GET_KEYS: {
+               uint32_t dbid;
+               struct ctdb_db_context *ctdb_db;
+               struct tdb_wrap *db;
+               struct getkeys_params params;
+
+               dbid = *((uint32_t *)(&indata.dptr[0]));
+               ctdb_db = find_ctdb_db(ctdb, dbid);
+               if (!ctdb_db) {
+                       DEBUG(0,(__location__ " Unknown db\n"));
+                       return -1;
+               }
+
+               outdata->dsize = sizeof(uint32_t);
+               outdata->dptr = (unsigned char *)talloc_array(outdata, uint32_t, 1);
+               *((uint32_t *)(&outdata->dptr[0]))=0;
+
+               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;
+               }
+
+               params.ctdb_db = ctdb_db;
+               params.outdata = outdata;
+               tdb_traverse(db->tdb, traverse_getkeys, &params);
+
+               talloc_free(db);
+
+               return 0;
+       }
+
        case CTDB_CONTROL_CONFIG: {
                CHECK_CONTROL_DATA_SIZE(0);
                outdata->dptr = (uint8_t *)ctdb;
index 7dba352a46ffb374277c7c56b3ba6a857a4c7b79..3e666de06bbe7109c0d98be592d73b2841ea9d22 100644 (file)
@@ -241,6 +241,15 @@ struct ctdb_node_map {
 };
 int ctdb_getnodemap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_node_map *nodemap);
 
+struct ctdb_key_list {
+       uint32_t num;
+       TDB_DATA *keys;
+       struct ctdb_ltdb_header *headers;
+       uint32_t *lmasters;
+       TDB_DATA *data;
+};
+int ctdb_getkeys(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx, struct ctdb_key_list *keys);
+
 int ctdb_getdbpath(struct ctdb_context *ctdb, uint32_t dbid, TALLOC_CTX *mem_ctx, const char **path);
 
 int ctdb_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid);
index dbbce30a447d82b39b8ef68d47dda5df2a90ed33..7c6fa8ee238de980284fce20328d0188abbe41ae 100644 (file)
@@ -254,7 +254,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS,
                    CTDB_CONTROL_GET_DEBUG,
                    CTDB_CONTROL_SET_DEBUG,
                    CTDB_CONTROL_GET_DBMAP,
-                   CTDB_CONTROL_GET_NODEMAP};
+                   CTDB_CONTROL_GET_NODEMAP,
+                   CTDB_CONTROL_GET_KEYS};
 
 enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
 
index 2af25ed2c18449c750f8976492cb3391d4e14197..3d5ace27e95936de6b3cb1eb56222276b85ca01b 100644 (file)
@@ -247,6 +247,10 @@ int main(int argc, const char *argv[])
 
        printf("DATA:\n%s\n", (char *)call.reply_data.dptr);
 
+#if 1 
+/* to keep the cluster up so one can play with it using the controls */ 
+sleep(9999999);
+#endif
        /* go into a wait loop to allow other nodes to complete */
        ctdb_shutdown(ctdb);
 
index 3a8bb777e901b9cca858cda0259cac49b1dbaa6e..35cd6ea96f31028056518eb81d72d75d16cb408d 100644 (file)
@@ -42,6 +42,7 @@ static void usage(void)
        printf("  setvnnmap <vnn> <generation> <numslots> <lmaster>*\n");
        printf("  getdbmap <vnn>                     lists databases on a node\n");
        printf("  getnodemap <vnn>                   lists nodes known to a ctdb daemon\n");
+       printf("  getkeys <vnn> <dbid>               lists all keys in a remote tdb\n");
        exit(1);
 }
 
@@ -156,6 +157,47 @@ static int control_getvnnmap(struct ctdb_context *ctdb, int argc, const char **a
        return 0;
 }
 
+/*
+  display remote list of keys for a tdb
+ */
+static int control_getkeys(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;
+
+       if (argc < 2) {
+               usage();
+       }
+
+       vnn  = strtoul(argv[0], NULL, 0);
+       dbid = strtoul(argv[1], NULL, 0);
+
+       mem_ctx = talloc_new(ctdb);
+       ret = ctdb_getkeys(ctdb, vnn, dbid, mem_ctx, &keys);
+       if (ret != 0) {
+               printf("Unable to get keys from node %u\n", vnn);
+               return ret;
+       }
+       printf("Number of keys:%d\n",keys.num);
+       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");
+       }
+
+       talloc_free(mem_ctx);
+       return 0;
+}
+
 /*
   display a list of the databases on a remote ctdb
  */
@@ -378,6 +420,8 @@ int main(int argc, const char *argv[])
                ret = control_getdbmap(ctdb, extra_argc-1, extra_argv+1);
        } else if (strcmp(control, "getnodemap") == 0) {
                ret = control_getnodemap(ctdb, extra_argc-1, extra_argv+1);
+       } else if (strcmp(control, "getkeys") == 0) {
+               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, "ping") == 0) {