add a new command "ctdb tfetch" that can read a record straight out of the
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 25 Aug 2010 00:53:54 +0000 (10:53 +1000)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 25 Aug 2010 00:56:02 +0000 (10:56 +1000)
tdb file.

the command automatically strips off the initial ctdb header off the record so it can only be used on ctdb managed tdb files, not on normal tdb files.

tools/ctdb.c

index 83fe0a6..f600fe2 100644 (file)
@@ -2933,6 +2933,54 @@ static int control_pfetch(struct ctdb_context *ctdb, int argc, const char **argv
        return 0;
 }
 
+/*
+  fetch a record from a tdb-file
+ */
+static int control_tfetch(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       const char *tdb_file;
+       TDB_CONTEXT *tdb;
+       TDB_DATA key, data;
+       int fd;
+
+       if (argc < 2) {
+               usage();
+       }
+
+       tdb_file = argv[0];
+
+       tdb = tdb_open(tdb_file, 0, 0, O_RDONLY, 0);
+       if (tdb == NULL) {
+               DEBUG(DEBUG_ERR,("Failed to open TDB file %s\n", tdb_file));
+               return -1;
+       }
+
+       key.dptr  = discard_const(argv[1]);
+       key.dsize = strlen(argv[1]);
+       data = tdb_fetch(tdb, key);
+       if (data.dptr == NULL || data.dsize < sizeof(struct ctdb_ltdb_header)) {
+               DEBUG(DEBUG_ERR,("Failed to read record %s from tdb %s\n", argv[1], tdb_file));
+               tdb_close(tdb);
+               return -1;
+       }
+
+       tdb_close(tdb);
+
+       if (argc == 3) {
+         fd = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0600);
+               if (fd == -1) {
+                       DEBUG(DEBUG_ERR,("Failed to open output file %s\n", argv[2]));
+                       return -1;
+               }
+               write(fd, data.dptr+sizeof(struct ctdb_ltdb_header), data.dsize-sizeof(struct ctdb_ltdb_header));
+               close(fd);
+       } else {
+               write(1, data.dptr+sizeof(struct ctdb_ltdb_header), data.dsize-sizeof(struct ctdb_ltdb_header));
+       }
+
+       return 0;
+}
+
 /*
   write a record to a persistent database
  */
@@ -4710,6 +4758,7 @@ static const struct {
        { "sync",            control_ipreallocate,      true,   false,  "wait until ctdbd has synced all state changes" },
        { "pfetch",          control_pfetch,            true,   false,  "fetch a record from a persistent database", "<db> <key> [<file>]" },
        { "pstore",          control_pstore,            true,   false,  "write a record to a persistent database", "<db> <key> <file containing record>" },
+       { "tfetch",          control_tfetch,            true,   false,  "fetch a record from a [c]tdb-file", "<tdb-file> <key> [<file>]" },
 };
 
 /*