return 0;
}
+/*
+ set/clear the permanent disabled bit on a remote node
+ */
+int ctdb_ctrl_permdisable(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t mode)
+{
+ int ret;
+ TDB_DATA data;
+ int32_t res;
+
+ data.dsize = sizeof(uint32_t);
+ data.dptr = (unsigned char *)&mode;
+
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_PERMANENTLY_DISABLE, 0, data,
+ NULL, NULL, &res, &timeout, NULL);
+ if (ret != 0 || res != 0) {
+ DEBUG(0,(__location__ " ctdb_control for setpermdisable failed\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
case CTDB_CONTROL_LIST_TUNABLES:
return ctdb_control_list_tunables(ctdb, outdata);
+ case CTDB_CONTROL_PERMANENTLY_DISABLE:
+ CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
+ if ( *(uint32_t *)indata.dptr ){
+ ctdb->nodes[ctdb->vnn]->flags |= NODE_FLAGS_PERMANENTLY_DISABLED;
+ } else {
+ ctdb->nodes[ctdb->vnn]->flags &= ~NODE_FLAGS_PERMANENTLY_DISABLED;
+ }
+ return 0;
+
default:
DEBUG(0,(__location__ " Unknown CTDB control opcode %u\n", opcode));
return -1;
timeval_current_ofs(ctdb->tunable.monitor_interval, 0),
ctdb_check_health, ctdb);
- if (status != 0 && !(node->flags & NODE_FLAGS_DISABLED)) {
+ if (node->flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
+ if ( !(node->flags & NODE_FLAGS_DISABLED) ) {
+ DEBUG(0,("monitoring - node is permanently disabled\n"));
+ node->flags |= NODE_FLAGS_DISABLED;
+ }
+ } else if (status != 0 && !(node->flags & NODE_FLAGS_DISABLED)) {
DEBUG(0,("monitor event failed - disabling node\n"));
node->flags |= NODE_FLAGS_DISABLED;
} else if (status == 0 && (node->flags & NODE_FLAGS_DISABLED)) {
TALLOC_CTX *mem_ctx,
const char ***list, uint32_t *count);
-
+int ctdb_ctrl_permdisable(struct ctdb_context *ctdb,
+ struct timeval timeout,
+ uint32_t destnode,
+ uint32_t mode);
#endif
const char *name; /* for debug messages */
void *private_data; /* private to transport */
uint32_t vnn;
-#define NODE_FLAGS_CONNECTED 0x00000001
-#define NODE_FLAGS_DISABLED 0x00000002
+#define NODE_FLAGS_CONNECTED 0x00000001
+#define NODE_FLAGS_DISABLED 0x00000002
+#define NODE_FLAGS_PERMANENTLY_DISABLED 0x00000004
uint32_t flags;
/* used by the dead node monitoring */
CTDB_CONTROL_GET_TUNABLE = 49,
CTDB_CONTROL_LIST_TUNABLES = 50,
CTDB_CONTROL_GET_PUBLIC_IPS = 51,
+ CTDB_CONTROL_PERMANENTLY_DISABLE = 52,
};
/*
printf("Number of nodes:%d\n", nodemap->num);
for(i=0;i<nodemap->num;i++){
const char *flags_str;
- if (nodemap->nodes[i].flags & NODE_FLAGS_DISABLED) {
+ if (nodemap->nodes[i].flags & NODE_FLAGS_PERMANENTLY_DISABLED) {
+ flags_str = "PERM DISABLED";
+ } else if (nodemap->nodes[i].flags & NODE_FLAGS_DISABLED) {
flags_str = "DISABLED";
} else if (nodemap->nodes[i].flags & NODE_FLAGS_CONNECTED) {
flags_str = "CONNECTED";
return 0;
}
+/*
+ disable a remote node
+ */
+static int control_disable(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret;
+
+ ret = ctdb_ctrl_permdisable(ctdb, TIMELIMIT(), options.vnn, NODE_FLAGS_PERMANENTLY_DISABLED);
+ if (ret != 0) {
+ printf("Unable to disable node %u\n", options.vnn);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ enable a disabled remote node
+ */
+static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret;
+
+ ret = ctdb_ctrl_permdisable(ctdb, TIMELIMIT(), options.vnn, 0);
+ if (ret != 0) {
+ printf("Unable to enable node %u\n", options.vnn);
+ return ret;
+ }
+
+ return 0;
+}
+
/*
shutdown a daemon
*/
{ "attach", control_attach, "attach to a database", "<dbname>" },
{ "dumpmemory", control_dumpmemory, "dump memory map to logs" },
{ "getpid", control_getpid, "get ctdbd process ID" },
+ { "disable", control_disable, "disable a node" },
+ { "enable", control_enable, "enable a node" },
{ "shutdown", control_shutdown, "shutdown ctdbd" },
{ "recover", control_recover, "force recovery" },
{ "freeze", control_freeze, "freeze all databases" },