]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-tests: Correctly handle adding a deleted node at the end
authorMartin Schwenke <mschwenke@ddn.com>
Thu, 11 Jul 2024 02:14:07 +0000 (12:14 +1000)
committerGünther Deschner <gd@samba.org>
Wed, 17 Jul 2024 00:06:53 +0000 (00:06 +0000)
The current fake_ctdbd code for reloading the nodes file overruns the
allocation when adding a deleted node at the end.  This is a very
unlikely case, but it might as well work.

Check the size of the internal node map when marking a node deleted.
Also, update the code that adds a node to correctly set the deleted
flag when appropriate.

The included test case tests this.

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Guenther Deschner <gd@samba.org>
Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Wed Jul 17 00:06:53 UTC 2024 on atb-devel-224

ctdb/tests/UNIT/tool/ctdb.reloadnodes.040.sh [new file with mode: 0755]
ctdb/tests/src/fake_ctdbd.c

diff --git a/ctdb/tests/UNIT/tool/ctdb.reloadnodes.040.sh b/ctdb/tests/UNIT/tool/ctdb.reloadnodes.040.sh
new file mode 100755 (executable)
index 0000000..19481b8
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+define_test "3 nodes, comment added at end, new deleted node"
+
+setup_nodes <<EOF
+192.168.20.41
+192.168.20.42
+192.168.20.43
+# Adding a comment!
+EOF
+
+setup_ctdbd <<EOF
+NODEMAP
+0       192.168.20.41   0x0     CURRENT RECMASTER
+1       192.168.20.42   0x0
+2       192.168.20.43   0x0
+EOF
+
+ok <<EOF
+Node 3 is NEW
+EOF
+simple_test
+
+ok <<EOF
+Number of nodes:4 (including 1 deleted nodes)
+pnn:0 192.168.20.41    OK (THIS NODE)
+pnn:1 192.168.20.42    OK
+pnn:2 192.168.20.43    OK
+EOF
+simple_test_other nodestatus all
index 1b44f1de688d469d037994d3a85f7e448fc04be3..f3af4bd43f9bd90d28497942a6b0405d21552469 100644 (file)
@@ -2499,7 +2499,15 @@ static void control_reload_nodes_file(TALLOC_CTX *mem_ctx,
        }
 
        for (i=0; i<nodemap->num; i++) {
-               struct node *node;
+               struct node *node = NULL;
+               ctdb_sock_addr zero = {};
+               int ret;
+
+               ret = ctdb_sock_addr_from_string("0.0.0.0", &zero, false);
+               if (ret != 0) {
+                       /* Can't happen, but Coverity... */
+                       goto fail;
+               }
 
                if (i < node_map->num_nodes &&
                    ctdb_sock_addr_same(&nodemap->node[i].addr,
@@ -2507,18 +2515,12 @@ static void control_reload_nodes_file(TALLOC_CTX *mem_ctx,
                        continue;
                }
 
-               if (nodemap->node[i].flags & NODE_FLAGS_DELETED) {
-                       int ret;
-
+               if (i < node_map->num_nodes &&
+                   nodemap->node[i].flags & NODE_FLAGS_DELETED) {
                        node = &node_map->node[i];
 
                        node->flags |= NODE_FLAGS_DELETED;
-                       ret = ctdb_sock_addr_from_string("0.0.0.0", &node->addr,
-                                                        false);
-                       if (ret != 0) {
-                               /* Can't happen, but Coverity... */
-                               goto fail;
-                       }
+                       node->addr = zero;
 
                        continue;
                }
@@ -2543,7 +2545,11 @@ static void control_reload_nodes_file(TALLOC_CTX *mem_ctx,
 
                node->addr = nodemap->node[i].addr;
                node->pnn = nodemap->node[i].pnn;
-               node->flags = 0;
+               if (ctdb_sock_addr_same_ip(&node->addr, &zero)) {
+                       node->flags = NODE_FLAGS_DELETED;
+               } else {
+                       node->flags = 0;
+               }
                node->capabilities = CTDB_CAP_DEFAULT;
                node->recovery_disabled = false;
                node->recovery_substate = NULL;