ctdb_daemon: Implement controls DISABLE_NODE/ENABLE_NODE
authorMartin Schwenke <martin@meltin.net>
Fri, 9 Jul 2021 04:12:59 +0000 (14:12 +1000)
committerAmitay Isaacs <amitay@samba.org>
Thu, 9 Sep 2021 01:46:49 +0000 (01:46 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14784
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/server/ctdb_control.c
ctdb/tests/src/fake_ctdbd.c

index 206ea14969324d2cf2db55e52defdadb6d751f24..131ebd43afcf35d5eeab2bc136527a671ebe73b9 100644 (file)
@@ -173,6 +173,40 @@ done:
        TALLOC_FREE(state);
 }
 
+static int ctdb_control_disable_node(struct ctdb_context *ctdb)
+{
+       struct ctdb_node *node;
+
+       node = ctdb_find_node(ctdb, CTDB_CURRENT_NODE);
+       if (node == NULL) {
+               /* Can't happen */
+               DBG_ERR("Unable to find current node\n");
+               return -1;
+       }
+
+       D_ERR("Disable node\n");
+       node->flags |= NODE_FLAGS_PERMANENTLY_DISABLED;
+
+       return 0;
+}
+
+static int ctdb_control_enable_node(struct ctdb_context *ctdb)
+{
+       struct ctdb_node *node;
+
+       node = ctdb_find_node(ctdb, CTDB_CURRENT_NODE);
+       if (node == NULL) {
+               /* Can't happen */
+               DBG_ERR("Unable to find current node\n");
+               return -1;
+       }
+
+       D_ERR("Enable node\n");
+       node->flags &= ~NODE_FLAGS_PERMANENTLY_DISABLED;
+
+       return 0;
+}
+
 /*
   process a control request
  */
@@ -827,6 +861,14 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                return ctdb_control_echo_data(ctdb, c, indata, async_reply);
        }
 
+       case CTDB_CONTROL_DISABLE_NODE:
+               CHECK_CONTROL_DATA_SIZE(0);
+               return ctdb_control_disable_node(ctdb);
+
+       case CTDB_CONTROL_ENABLE_NODE:
+               CHECK_CONTROL_DATA_SIZE(0);
+               return ctdb_control_enable_node(ctdb);
+
        default:
                DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
                return -1;
index 146b7da344c62fd41da11e21ba67d23a0fcc81cf..d6552baee8d709fe68647c0ba93fc552071635a2 100644 (file)
@@ -3513,6 +3513,52 @@ static void control_check_pid_srvid(TALLOC_CTX *mem_ctx,
        client_send_control(req, header, &reply);
 }
 
+static void control_disable_node(TALLOC_CTX *mem_ctx,
+                                struct tevent_req *req,
+                                struct ctdb_req_header *header,
+                                struct ctdb_req_control *request)
+{
+       struct client_state *state = tevent_req_data(
+               req, struct client_state);
+       struct ctdbd_context *ctdb = state->ctdb;
+       struct ctdb_reply_control reply;
+
+       reply.rdata.opcode = request->opcode;
+
+       DEBUG(DEBUG_INFO, ("Disabling node\n"));
+       ctdb->node_map->node[header->destnode].flags |=
+               NODE_FLAGS_PERMANENTLY_DISABLED;
+
+       reply.status = 0;
+       reply.errmsg = NULL;
+
+       client_send_control(req, header, &reply);
+       return;
+}
+
+static void control_enable_node(TALLOC_CTX *mem_ctx,
+                                 struct tevent_req *req,
+                                 struct ctdb_req_header *header,
+                                 struct ctdb_req_control *request)
+{
+       struct client_state *state = tevent_req_data(
+               req, struct client_state);
+       struct ctdbd_context *ctdb = state->ctdb;
+       struct ctdb_reply_control reply;
+
+       reply.rdata.opcode = request->opcode;
+
+       DEBUG(DEBUG_INFO, ("Enable node\n"));
+       ctdb->node_map->node[header->destnode].flags &=
+               ~NODE_FLAGS_PERMANENTLY_DISABLED;
+
+       reply.status = 0;
+       reply.errmsg = NULL;
+
+       client_send_control(req, header, &reply);
+       return;
+}
+
 static bool fake_control_failure(TALLOC_CTX *mem_ctx,
                                 struct tevent_req *req,
                                 struct ctdb_req_header *header,
@@ -4205,6 +4251,14 @@ static void client_process_control(struct tevent_req *req,
                control_check_pid_srvid(mem_ctx, req, &header, &request);
                break;
 
+       case CTDB_CONTROL_DISABLE_NODE:
+               control_disable_node(mem_ctx, req, &header, &request);
+               break;
+
+       case CTDB_CONTROL_ENABLE_NODE:
+               control_enable_node(mem_ctx, req, &header, &request);
+               break;
+
        default:
                if (! (request.flags & CTDB_CTRL_FLAG_NOREPLY)) {
                        control_error(mem_ctx, req, &header, &request);