LibCTDB: add get persistent db seqnum control
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Sun, 27 Nov 2011 23:57:39 +0000 (10:57 +1100)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Tue, 29 Nov 2011 23:14:31 +0000 (10:14 +1100)
include/ctdb.h
libctdb/control.c
libctdb/sync.c
tools/ctdb.c

index c95c2e1e26796fc7af934e2077678435e3109a86..f6b5f9f59349408e88e9f80c349182d58861afc7 100644 (file)
@@ -452,6 +452,35 @@ bool ctdb_getpnn_recv(struct ctdb_connection *ctdb,
                      struct ctdb_request *req, uint32_t *pnn);
 
 
+/**
+ * ctdb_getdbseqnum_send - read the sequence number off a db
+ * @ctdb: the ctdb_connection from ctdb_connect.
+ * @destnode: the destination node (see below)
+ * @dbid: database id
+ * @callback: the callback when ctdb replies to our message (typesafe)
+ * @cbdata: the argument to callback()
+ *
+ * There are several special values for destnode, detailed in
+ * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the
+ * local ctdbd.
+ */
+struct ctdb_request *
+ctdb_getdbseqnum_send(struct ctdb_connection *ctdb,
+                uint32_t destnode,
+                uint32_t dbid,
+                ctdb_callback_t callback,
+                void *cbdata);
+/**
+ * ctdb_getdbseqnum_recv - read the sequence number off a database
+ * @ctdb: the ctdb_connection from ctdb_connect.
+ * @req: the completed request.
+ * @seqnum: a pointer to the seqnum to fill in
+ *
+ * This returns false if something went wrong, or otherwise fills in pnn.
+ */
+bool ctdb_getdbseqnum_recv(struct ctdb_connection *ctdb,
+                     struct ctdb_request *req, uint64_t *seqnum);
+
 /**
  * ctdb_getnodemap_send - read the nodemap number from a node.
  * @ctdb: the ctdb_connection from ctdb_connect.
@@ -651,6 +680,25 @@ bool ctdb_getpnn(struct ctdb_connection *ctdb,
                 uint32_t destnode,
                 uint32_t *pnn);
 
+/**
+ * ctdb_getdbseqnum - read the seqnum of a database
+ * @ctdb: the ctdb_connection from ctdb_connect.
+ * @destnode: the destination node (see below)
+ * @dbid: database id
+ * @seqnum: sequence number for the database
+ *
+ * There are several special values for destnode, detailed in
+ * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the
+ * local ctdbd.
+ *
+ * Returns true and fills in *pnn on success.
+ */
+bool
+ctdb_getdbseqnum(struct ctdb_connection *ctdb,
+                uint32_t destnode,
+                uint32_t dbid,
+                uint64_t *seqnum);
+
 /**
  * ctdb_getrecmaster - read the recovery master of a node (synchronous)
  * @ctdb: the ctdb_connection from ctdb_connect.
@@ -783,4 +831,8 @@ void ctdb_free_publicips(struct ctdb_all_public_ips *ips);
        ctdb_getpublicips_send((ctdb), (destnode),                      \
                         ctdb_sendcb((cb), (cbdata)), (cbdata))
 
+#define ctdb_getdbseqnum_send(ctdb, destnode, dbid, cb, cbdata)                \
+       ctdb_getdbseqnum_send((ctdb), (destnode), (dbid),               \
+                        ctdb_sendcb((cb), (cbdata)), (cbdata))
+
 #endif
index 07185dbb41bad23a8e29b03a9508c91aa8441d37..18ec1fbd51c9a413635e37936399918f6f3cc12c 100644 (file)
@@ -26,6 +26,7 @@
 #undef ctdb_getpnn_send
 #undef ctdb_getnodemap_send
 #undef ctdb_getpublicips_send
+#undef ctdb_getdbseqnum_send
 
 bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb,
                           struct ctdb_request *req, uint32_t *recmaster)
@@ -172,3 +173,42 @@ void ctdb_free_publicips(struct ctdb_all_public_ips *ips)
        }
        free(ips);
 }
+
+bool ctdb_getdbseqnum_recv(struct ctdb_connection *ctdb,
+                          struct ctdb_request *req, uint64_t *seqnum)
+{
+       struct ctdb_reply_control *reply;
+
+       reply = unpack_reply_control(ctdb, req, CTDB_CONTROL_GET_DB_SEQNUM);
+       if (!reply) {
+               return false;
+       }
+       if (reply->status == -1) {
+               DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum_recv: status -1");
+               return false;
+       }
+
+       if (reply->datalen != sizeof(uint64_t)) {
+               DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum wrong size of data was %d but expected %d bytes", reply->datalen, (int)sizeof(uint64_t));
+               return false;
+       }
+
+       *seqnum = *((uint64_t *)reply->data);
+
+       return true;
+}
+
+struct ctdb_request *ctdb_getdbseqnum_send(struct ctdb_connection *ctdb,
+                                           uint32_t destnode,
+                                           uint32_t dbid,
+                                           ctdb_callback_t callback,
+                                           void *private_data)
+{
+       uint64_t indata;
+
+       *((uint32_t *)&indata) = dbid;
+
+       return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_DB_SEQNUM,
+                                       destnode, &indata, sizeof(uint64_t),
+                                       callback, private_data);
+}
index a1be3be9fadf6a50309eae7ddcde2bac7ff49dcc..26fae5679a7b8346051825b5d3a8102833a3e2c6 100644 (file)
@@ -227,3 +227,21 @@ struct ctdb_lock *ctdb_readrecordlock(struct ctdb_connection *ctdb,
        }
        return rrl.lock;
 }
+
+bool ctdb_getdbseqnum(struct ctdb_connection *ctdb,
+                     uint32_t destnode, uint32_t dbid,
+                     uint64_t *seqnum)
+{
+       struct ctdb_request *req;
+       bool done = false;
+       bool ret = false;
+
+       req = synchronous(ctdb,
+                         ctdb_getdbseqnum_send(ctdb, destnode, dbid, set, &done),
+                         &done);
+       if (req != NULL) {
+               ret = ctdb_getdbseqnum_recv(ctdb, req, seqnum);
+               ctdb_request_free(ctdb, req);
+       }
+       return ret;
+}
index d49bc8f813346c8362d935db51ae1b647e96a71f..62dc54a1b05f248a09c59bc790f74fe107758f9b 100644 (file)
@@ -4020,6 +4020,32 @@ static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **a
        return 0;
 }
 
+/*
+  get db seqnum
+ */
+static int control_getdbseqnum(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       bool ret;
+       uint32_t db_id;
+       uint64_t seqnum;
+
+       if (argc < 1) {
+               usage();
+       }
+
+       db_id = strtoul(argv[0], NULL, 0);
+
+       ret = ctdb_getdbseqnum(ctdb_connection, options.pnn, db_id, &seqnum);
+       if (!ret) {
+               DEBUG(DEBUG_ERR, ("Unable to get seqnum from node."));
+               return -1;
+       }
+
+       printf("Sequence number:%lld\n", (long long)seqnum);
+
+       return 0;
+}
+
 /*
   run an eventscript on a node
  */
@@ -5020,6 +5046,7 @@ static const struct {
        { "readkey",         control_readkey,           true,   false,  "read the content off a database key", "<tdb-file> <key>" },
        { "writekey",        control_writekey,          true,   false,  "write to a database key", "<tdb-file> <key> <value>" },
        { "checktcpport",    control_chktcpport,        false,  true,  "check if a service is bound to a specific tcp port or not", "<port>" },
+       { "getdbseqnum",     control_getdbseqnum,       false,  false, "get the sequence number off a database", "<dbid>" },
 };
 
 /*