]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
add a new "recovery mode" field to ctdb.
authorRonnie Sahlberg <sahlberg@ronnie>
Sun, 29 Apr 2007 12:51:56 +0000 (22:51 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Sun, 29 Apr 2007 12:51:56 +0000 (22:51 +1000)
while recovery is in progress  the daemon will discard all CTDB_REQ_CALL
and rely on clients retransmitting them

add new controls to get/set the recovery mode

(This used to be ctdb commit 41458a61577885ac49150f830e92e93e634c5411)

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

index 63e5b6543848b5588bcdeb0836834012e1fa2f79..d2cf41f647ae5337116ea72ba2ba70970ea31228 100644 (file)
@@ -252,6 +252,18 @@ void ctdb_recv_pkt(struct ctdb_context *ctdb, uint8_t *data, uint32_t length)
                                hdr->generation));
                        break;
                }
+               /* if we are in recovery mode we discard all traffic
+                  until the cluster has recovered.
+               */
+               if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
+                       DEBUG(0,(__location__ " ctdb request %d of type"
+                               " %d length %d from node %d to %d"
+                               " while we are in recovery mode\n", 
+                               hdr->reqid, hdr->operation, hdr->length, 
+                                hdr->srcnode, hdr->destnode));
+                       break;
+               }
+
                ctdb->status.count.req_call++;
                ctdb_request_call(ctdb, hdr);
                break;
@@ -445,6 +457,7 @@ struct ctdb_context *ctdb_init(struct event_context *ev)
 
        ctdb = talloc_zero(ev, struct ctdb_context);
        ctdb->ev = ev;
+       ctdb->recovery_mode = CTDB_RECOVERY_NORMAL;
        ctdb->upcalls = &ctdb_upcalls;
        ctdb->idr = idr_init(ctdb);
        ctdb->max_lacount = CTDB_DEFAULT_MAX_LACOUNT;
index 4dd21ecc599a42ca16e850d265b4b361ce5b7d02..d7dc7be54d72c6ff9817157de024aa0656687203 100644 (file)
@@ -793,6 +793,53 @@ int ctdb_getvnnmap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_vnn
        return 0;
 }
 
+/*
+  get the recovery mode of a remote node
+ */
+int ctdb_getrecmode(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *recmode)
+{
+       int ret;
+       TDB_DATA data, outdata;
+       int32_t res;
+
+       ZERO_STRUCT(data);
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_RECMODE, data, 
+                          ctdb, &outdata, &res);
+       if (ret != 0 || res != 0) {
+               DEBUG(0,(__location__ " ctdb_control for getrecmode failed\n"));
+               return -1;
+       }
+
+       *recmode = ((uint32_t *)outdata.dptr)[0];
+
+       return 0;
+}
+
+/*
+  set the recovery mode of a remote node
+ */
+int ctdb_setrecmode(struct ctdb_context *ctdb, uint32_t destnode, uint32_t recmode)
+{
+       int ret;
+       TDB_DATA data, outdata;
+       int32_t res;
+
+       ZERO_STRUCT(data);
+       data.dsize = sizeof(uint32_t);
+       data.dptr = (unsigned char *)&recmode;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_SET_RECMODE, data, 
+                          ctdb, &outdata, &res);
+       if (ret != 0 || res != 0) {
+               DEBUG(0,(__location__ " ctdb_control for getrecmode failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
 /*
   get a list of databases off a remote node
  */
index b26d84ac57143fbb6882f287ed9fdad3671d6f0d..102d0debb31f7f43ef8cf13792dbb7b0fe4d812f 100644 (file)
@@ -354,6 +354,20 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                return 0;
        }
 
+       case CTDB_CONTROL_SET_RECMODE: {
+               ctdb->recovery_mode = ((uint32_t *)(&indata.dptr[0]))[0];
+
+               return 0;
+       }
+
+       case CTDB_CONTROL_GET_RECMODE: {
+               outdata->dsize = sizeof(uint32_t);
+               outdata->dptr = (unsigned char *)talloc_array(outdata, uint32_t, 1);
+               *((uint32_t *)(&outdata->dptr[0])) = ctdb->recovery_mode;
+
+               return 0;
+       }
+
        case CTDB_CONTROL_CONFIG: {
                CHECK_CONTROL_DATA_SIZE(0);
                outdata->dptr = (uint8_t *)ctdb;
index f7eb16b75e5e3f3b1d1dc2bad96696759e07ac1a..aa2f31fa34c5a15a3071b1f63b4b2cd5df942d8e 100644 (file)
@@ -276,4 +276,16 @@ int ctdb_cleardb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_c
  */
 int ctdb_pulldb(struct ctdb_context *ctdb, uint32_t destnode, TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t from_vnn);
 
+
+#define CTDB_RECOVERY_NORMAL           0
+#define CTDB_RECOVERY_ACTIVE           1
+/*
+  get the recovery mode of a remote node
+ */
+int ctdb_getrecmode(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *recmode);
+/*
+  set the recovery mode of a remote node
+ */
+int ctdb_setrecmode(struct ctdb_context *ctdb, uint32_t destnode, uint32_t recmode);
+
 #endif
index ce47f9948dacc66cfef9b39c4cd724f0a46af200..73de824f33c6dc4dfa4f057ca8d3949a673e91b8 100644 (file)
@@ -173,6 +173,7 @@ struct ctdb_vnn_map {
 /* main state of the ctdb daemon */
 struct ctdb_context {
        struct event_context *ev;
+       uint32_t recovery_mode;
        struct ctdb_address address;
        const char *name;
        const char *db_directory;
@@ -258,7 +259,9 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS,
                    CTDB_CONTROL_GET_KEYS,
                    CTDB_CONTROL_SET_DMASTER,
                    CTDB_CONTROL_CLEAR_DB,
-                   CTDB_CONTROL_PULL_DB};
+                   CTDB_CONTROL_PULL_DB,
+                   CTDB_CONTROL_GET_RECMODE,
+                   CTDB_CONTROL_SET_RECMODE};
 
 enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
 
index 4fb3ff80decc0df691e3b518154fe37cc25f6ac3..d2fa2a43083fee89100fb861fb3432647cf47287 100644 (file)
@@ -46,6 +46,8 @@ static void usage(void)
        printf("  setdmaster <vnn> <dbid> <dmaster>  sets new dmaster for all records in the database\n");
        printf("  cleardb <vnn> <dbid>               deletes all records in a db\n");
        printf("  pulldb <vnn> <dbid> <from vnn>     pull a db from a remote node\n");
+       printf("  getrecmode <vnn>                   get recovery mode\n");
+       printf("  setrecmode <vnn> <mode>            set recovery mode\n");
        exit(1);
 }
 
@@ -160,6 +162,56 @@ static int control_getvnnmap(struct ctdb_context *ctdb, int argc, const char **a
        return 0;
 }
 
+/*
+  display recovery mode of a remote node
+ */
+static int control_getrecmode(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       uint32_t vnn, recmode;
+       int ret;
+
+
+       if (argc < 1) {
+               usage();
+       }
+
+       vnn     = strtoul(argv[0], NULL, 0);
+
+       ret = ctdb_getrecmode(ctdb, vnn, &recmode);
+       if (ret != 0) {
+               printf("Unable to get recmode from node %u\n", vnn);
+               return ret;
+       }
+       printf("Recovery mode:%s (%d)\n",recmode==CTDB_RECOVERY_NORMAL?"NORMAL":"RECOVERY",recmode);
+
+       return 0;
+}
+
+/*
+  set recovery mode of a remote node
+ */
+static int control_setrecmode(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       uint32_t vnn, recmode;
+       int ret;
+
+
+       if (argc < 2) {
+               usage();
+       }
+
+       vnn     = strtoul(argv[0], NULL, 0);
+       recmode = strtoul(argv[0], NULL, 0);
+
+       ret = ctdb_setrecmode(ctdb, vnn, recmode);
+       if (ret != 0) {
+               printf("Unable to set recmode on node %u\n", vnn);
+               return ret;
+       }
+
+       return 0;
+}
+
 /*
   display remote list of keys for a tdb
  */
@@ -504,6 +556,10 @@ int main(int argc, const char *argv[])
                ret = control_cleardb(ctdb, extra_argc-1, extra_argv+1);
        } else if (strcmp(control, "pulldb") == 0) {
                ret = control_pulldb(ctdb, extra_argc-1, extra_argv+1);
+       } else if (strcmp(control, "getrecmode") == 0) {
+               ret = control_getrecmode(ctdb, extra_argc-1, extra_argv+1);
+       } else if (strcmp(control, "setrecmode") == 0) {
+               ret = control_setrecmode(ctdb, extra_argc-1, extra_argv+1);
        } else if (strcmp(control, "ping") == 0) {
                ret = control_ping(ctdb, extra_argc-1, extra_argv+1);
        } else if (strcmp(control, "debug") == 0) {