From: Ronnie Sahlberg Date: Sun, 29 Apr 2007 12:51:56 +0000 (+1000) Subject: add a new "recovery mode" field to ctdb. X-Git-Tag: tevent-0.9.20~348^2~2800^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=77ce5750b2a18c1b4a82f3bc982fbb3ea465b60c;p=thirdparty%2Fsamba.git add a new "recovery mode" field to ctdb. 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) --- diff --git a/ctdb/common/ctdb.c b/ctdb/common/ctdb.c index 63e5b654384..d2cf41f647a 100644 --- a/ctdb/common/ctdb.c +++ b/ctdb/common/ctdb.c @@ -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; diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index 4dd21ecc599..d7dc7be54d7 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -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 */ diff --git a/ctdb/common/ctdb_control.c b/ctdb/common/ctdb_control.c index b26d84ac571..102d0debb31 100644 --- a/ctdb/common/ctdb_control.c +++ b/ctdb/common/ctdb_control.c @@ -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; diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index f7eb16b75e5..aa2f31fa34c 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -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 diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index ce47f9948da..73de824f33c 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -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}; diff --git a/ctdb/tools/ctdb_control.c b/ctdb/tools/ctdb_control.c index 4fb3ff80dec..d2fa2a43083 100644 --- a/ctdb/tools/ctdb_control.c +++ b/ctdb/tools/ctdb_control.c @@ -46,6 +46,8 @@ static void usage(void) printf(" setdmaster sets new dmaster for all records in the database\n"); printf(" cleardb deletes all records in a db\n"); printf(" pulldb pull a db from a remote node\n"); + printf(" getrecmode get recovery mode\n"); + printf(" setrecmode 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) {