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:53:54 +0000 (10:53 +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 b4e951624981e0da79bc1d9862e16a7b117b3da9..f595fcdbfe56d32d10861342746e56d92341cb04 100644 (file)
@@ -2895,6 +2895,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
  */
@@ -4672,6 +4720,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>]" },
 };
 
 /*