[SCM] Samba Shared Repository - branch master updated

Amitay Isaacs amitay at samba.org
Mon Mar 23 08:05:03 MDT 2015


The branch, master has been updated
       via  c8918b7 ctdb-tools: Use a broadcast to connected nodes for "reloadnodes"
       via  c99d270 ctdb-tests: Add unit tests for "reloadnodes" sanity checking
       via  1cebd75 ctdb-tools: Sanity check changes before processing "reloadnodes"
       via  2cb2aa5 ctdb-tests: Add "ctdb reloadnodes" unit tests
       via  16c79eb ctdb-tools: Add cross-node file comparison to "reloadnodes"
       via  5207d13 ctdb-tests: Test stub for ctrl_getnodesfile()
       via  81e5269 ctdb-daemon: New control CTDB_CONTROL_GET_NODES_FILE
       via  8e12e11 ctdb-tools: "reloadnodes" should only run against current node
       via  77e8792 ctdb-tools: Remove unused struct pnn_node and function read_pnn_node_file()
       via  3703e8a ctdb-tools: Reimplement read_natgw_nodes_file() using ctdb_read_nodes_file()
       via  c5538a4 ctdb-tools: Reimplement read_nodes_file() using ctdb_get_nodes_file()
       via  5148228 ctdb-daemon: Move ctdb_read_nodes_file() to utilities
       via  1ada9c4 ctdb-daemon: Factor out node parsing code
       via  a5be2c2 ctdb-daemon: Store node addresses as ctdb_sock_addr rather than strings
       via  3cbeb17 ctdb-common: Drop ctdb context from ctdb_parse_address()
       via  a1e65d0 ctdb-daemon: Remove function ctdb_add_deleted_node()
       via  8765290 ctdb-daemon: Set node PNN in one place
       via  db6385a ctdb-daemon: Move VNN map initialisation out of node loading
       via  ee073f6 ctdb-tests: Fix error return for ctdb_client_async_control_stub()
       via  c089133 ctdb-tests: Add asserts to ensure that pointers are set
      from  c07a54b torture: Fix the usage of the MEMORY credential cache.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c8918b70b9bc422dfb51f8e14b9ef54f1e845fad
Author: Martin Schwenke <martin at meltin.net>
Date:   Wed Feb 25 11:43:10 2015 +1100

    ctdb-tools: Use a broadcast to connected nodes for "reloadnodes"
    
    There is no reason to serialise these or even handle remote nodes
    first.  Using a broadcast is more efficient and is less code.
    
    Update expected test results to reflect changed order of messages.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    Autobuild-User(master): Amitay Isaacs <amitay at samba.org>
    Autobuild-Date(master): Mon Mar 23 15:04:00 CET 2015 on sn-devel-104

commit c99d2702eecbb38afa3bd1e07c5be772b64b05b6
Author: Martin Schwenke <martin at meltin.net>
Date:   Wed Feb 4 14:57:03 2015 +1100

    ctdb-tests: Add unit tests for "reloadnodes" sanity checking
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 1cebd75f62bfe6129ab4765658a48e59c64c5c39
Author: Martin Schwenke <martin at meltin.net>
Date:   Fri Jan 30 20:14:26 2015 +1100

    ctdb-tools: Sanity check changes before processing "reloadnodes"
    
    "ctdb reloadnodes" currently does no sanity checking of the nodes
    file.  This can cause chaos if a line is deleted from the nodes file
    rather than commented out.  It also repeatedly produces a spurious
    warning for each deleted node, even if the node was deleted a long
    time ago.
    
    Instead compare the nodemap with the contents of the local nodes file
    to sanity check before attempting any reloads.  Note that this is
    still imperfect if the nodes files are inconsistent across nodes but
    it is better.  Also ensure that any nodes that are to be deleted are
    already disconnected.  Avoid trying to talk to deleted nodes.
    
    The current implementation is a bit unfortunate when it comes to
    deleting nodes.  The most obvious alternative to the above complexity
    would be to reloadnodes on the specified node first, then fetch the
    node map (in which newly deleted nodes would be marked as such) and
    then handle the remote nodes.  However, the implementation of
    reloadnodes is asynchronous and it only actions the reload after 1
    second.  This is presumably to avoid the recovery master noticing the
    inconsistency between nodemaps and triggering a recovery before all
    nodes have had their nodemaps updated.
    
    Note that this recovery can still occur if the check is done at an
    inconvenient time.  A better long term approach might be to quiesce
    the recovery master checks while reloadnodes is in progress.
    
    Update a unit test to reflect the change.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 2cb2aa58d003980af777bf37fbabbd91cf859fea
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Mar 17 20:12:22 2015 +1100

    ctdb-tests: Add "ctdb reloadnodes" unit tests
    
    A basic test and some for cross-node consistency checking.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 16c79eb8873b4c16db3ba01f0cacfdafa54e7369
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 24 16:13:46 2015 +1100

    ctdb-tools: Add cross-node file comparison to "reloadnodes"
    
    This compares the nodes file on the current node with that on all
    nodes.  If any are different then do not reload nodes.
    
    If any nodes files can't be fetched then do not reload nodes.  This
    could be because some nodes are running an older version without this
    feature.  This is unsupported: why make a major cluster
    reconfiguration while a cluster is half upgraded?
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 5207d131528f796db12ae4fb4753fa3200742bff
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 24 16:13:09 2015 +1100

    ctdb-tests: Test stub for ctrl_getnodesfile()
    
    Also stub support for CTDB_CONTROL_GET_NODES_FILE
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 81e526965c017193e5fe1556de4f594515cf1ec1
Author: Martin Schwenke <martin at meltin.net>
Date:   Fri Feb 20 21:19:01 2015 +1100

    ctdb-daemon: New control CTDB_CONTROL_GET_NODES_FILE
    
    This is like CTDB_CONTROL_GET_NODEMAP but it loads from the nodes file
    instead of the daemon.
    
    Also new client function ctdb_ctrl_getnodesfile()
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 8e12e112f8fe14716f6a1a0f07783c7df03db3b9
Author: Martin Schwenke <martin at meltin.net>
Date:   Wed Jan 28 11:54:39 2015 +1100

    ctdb-tools: "reloadnodes" should only run against current node
    
    It should not be possible to specify "-n <othernode>", unless
    <othernode> is the current node.  To support this, add new function
    assert_current_node_only().
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 77e879253b2e2a7b5ec630daad3a7709abd67953
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 24 11:18:34 2015 +1100

    ctdb-tools: Remove unused struct pnn_node and function read_pnn_node_file()
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 3703e8aadd33ab95985e17d72ec84584dd9e1234
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 24 11:17:20 2015 +1100

    ctdb-tools: Reimplement read_natgw_nodes_file() using ctdb_read_nodes_file()
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit c5538a464f82a0a41b2db42ddf3dc0f7496a1676
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Feb 23 22:05:36 2015 +1100

    ctdb-tools: Reimplement read_nodes_file() using ctdb_get_nodes_file()
    
    Update the implementation of "ctdb xpnn" and "ctdb listnodes"
    accordingly.  Update associated tests too.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 5148228f414ea1cc2ad71dfbb4d5f82353ae5b56
Author: Martin Schwenke <martin at meltin.net>
Date:   Sun Feb 22 06:49:04 2015 +1100

    ctdb-daemon: Move ctdb_read_nodes_file() to utilities
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 1ada9c4ef787af4097f228c4629fac99a5b9bf13
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 17 15:35:07 2015 +1100

    ctdb-daemon: Factor out node parsing code
    
    New function ctdb_read_nodes_file() reads a nodes file into a node
    map, which is a useful intermediate format.  This function should
    replace the node reading code in the ctdb CLI tool.  It will also be
    useful for sanity checking of nodes files across the cluster.
    
    New function convert_node_map_to_list() converts a node map to a node
    array (and associated node count).  This fills in the details that
    aren't present in the node map.  This may also useful as a separate
    function later if node list reloading stages the data after a sanity
    check - the approach is not yet finalised.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit a5be2c245d5634695bd23387913c7e2e2481879b
Author: Martin Schwenke <martin at meltin.net>
Date:   Fri Feb 20 11:47:23 2015 +1100

    ctdb-daemon: Store node addresses as ctdb_sock_addr rather than strings
    
    Every time a nodemap is contructed the node IP addresses all need to
    be parsed.  This isn't very productive use of CPU.
    
    Instead, parse each string once when the nodes file is loaded.  This
    results in much simpler code.
    
    This code also removes the use of ctdb_address.  Duplicating the port
    is pointless without an abstraction layer around ctdb_address.  If
    CTDB gets an incompatible transport in the future then add an
    abstraction layer.
    
    Note that the infiniband code is not updated.  Compilation of the
    infiniband code is already broken.  Fixing it will be a separate,
    properly tested effort.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    Pair-programmed-with: Amitay Isaacs <amitay at gmail.com>

commit 3cbeb17d0f9f1e4b6a3faa9aba2982793cf8494b
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Feb 23 10:34:33 2015 +1100

    ctdb-common: Drop ctdb context from ctdb_parse_address()
    
    Having it require a CTDB context stops ctdb_parse_address() from being
    used in more generic code.  Just use the existing talloc context for
    memory allocations.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit a1e65d0c8d0b39fdae58128695ccbeb50775a6be
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 10 20:50:05 2015 +1100

    ctdb-daemon: Remove function ctdb_add_deleted_node()
    
    Just add a flags parameter to ctdb_add_nodes() and use the same code.
    Less is more.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit 876529054a00d107ece720771b11b2403bfa608d
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 17 15:21:15 2015 +1100

    ctdb-daemon: Set node PNN in one place
    
    This is currently set in 2 places.  One of them makes the node loading
    code difficult to refactor.  Also, when the surrounding code in either
    place is touched then it might get broken.
    
    This only needs to be done once at startup, not on every reload.  So
    do it once in a very obvious way, sacrificing a few CPU cycles for
    some added clarity.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit db6385afe9a459e109f785167c02fc1fd6064abf
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Feb 17 12:34:41 2015 +1100

    ctdb-daemon: Move VNN map initialisation out of node loading
    
    Each node reload unnecessarily and incorrectly resets the VNN map,
    causing a potentially unnecessary recovery.  When nodes are reloaded
    any newly deleted nodes should already be disconnected and any newly
    added nodes should also be disconnected.  This means that reloading
    the nodes file should not cause a change in the VNN map.
    
    The current implementation also leaks memory every time the nodes are
    reloaded.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit ee073f60b1eebe1362c86d703bcfdde3c54be787
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Mar 17 20:14:08 2015 +1100

    ctdb-tests: Fix error return for ctdb_client_async_control_stub()
    
    It should be -1 even without a failure callback registered.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

commit c0891339ec269dd559b18e6e2347757a54aef55e
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Mar 17 11:03:52 2015 +1100

    ctdb-tests: Add asserts to ensure that pointers are set
    
    These can be unset if a NODEMAP, IFACES or VNNMAP section is missing.
    Affected functions would then dereference a NULL pointer and the test
    program would crash.  Adding some helpful messages makes the problem
    easier to diagnose when writing tests.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>

-----------------------------------------------------------------------

Summary of changes:
 ctdb/client/ctdb_client.c                          |  25 ++
 ctdb/common/ctdb_util.c                            | 123 ++++++-
 ctdb/common/system_util.c                          |   6 +
 ctdb/include/ctdb_client.h                         |   6 +-
 ctdb/include/ctdb_private.h                        |  23 +-
 ctdb/include/ctdb_protocol.h                       |   1 +
 ctdb/server/ctdb_control.c                         |   3 +
 ctdb/server/ctdb_daemon.c                          |  72 +++-
 ctdb/server/ctdb_recover.c                         |  15 +-
 ctdb/server/ctdb_server.c                          | 206 +++--------
 ctdb/tcp/tcp_connect.c                             | 107 ++----
 ctdb/tcp/tcp_init.c                                |   2 +-
 ctdb/tests/src/ctdb_test.c                         |   7 +
 ctdb/tests/src/ctdb_test_stubs.c                   |  95 ++++-
 ctdb/tests/tool/scripts/local.sh                   |  19 +-
 ctdb/tests/tool/stubby.listnodes.001.sh            |   2 +-
 ctdb/tests/tool/stubby.reloadnodes.001.sh          |  31 ++
 ctdb/tests/tool/stubby.reloadnodes.002.sh          |  34 ++
 ctdb/tests/tool/stubby.reloadnodes.003.sh          |  37 ++
 ctdb/tests/tool/stubby.reloadnodes.011.sh          |  38 ++
 ctdb/tests/tool/stubby.reloadnodes.012.sh          |  33 ++
 ctdb/tests/tool/stubby.reloadnodes.013.sh          |  32 ++
 ctdb/tests/tool/stubby.reloadnodes.014.sh          |  33 ++
 ctdb/tests/tool/stubby.reloadnodes.015.sh          |  32 ++
 ctdb/tests/tool/stubby.reloadnodes.016.sh          |  33 ++
 ctdb/tests/tool/stubby.reloadnodes.017.sh          |  32 ++
 ctdb/tests/tool/stubby.reloadnodes.018.sh          |  42 +++
 ctdb/tests/tool/stubby.reloadnodes.019.sh          |  37 ++
 ctdb/tests/tool/stubby.reloadnodes.020.sh          |  37 ++
 ctdb/tests/tool/stubby.reloadnodes.021.sh          |  36 ++
 ...pabilities.002.sh => stubby.reloadnodes.022.sh} |  23 +-
 ctdb/tests/tool/stubby.reloadnodes.023.sh          |  33 ++
 ctdb/tests/tool/stubby.xpnn.003.sh                 |   2 +-
 ctdb/tools/ctdb.c                                  | 389 +++++++++++++++------
 34 files changed, 1225 insertions(+), 421 deletions(-)
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.001.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.002.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.003.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.011.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.012.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.013.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.014.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.015.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.016.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.017.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.018.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.019.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.020.sh
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.021.sh
 copy ctdb/tests/tool/{stubby.getcapabilities.002.sh => stubby.reloadnodes.022.sh} (53%)
 create mode 100755 ctdb/tests/tool/stubby.reloadnodes.023.sh


Changeset truncated at 500 lines:

diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
index fc34b8a..f46cfc6 100644
--- a/ctdb/client/ctdb_client.c
+++ b/ctdb/client/ctdb_client.c
@@ -1541,6 +1541,31 @@ int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
 }
 
 /*
+  load nodes file on a remote node and return as a node map
+ */
+int ctdb_ctrl_getnodesfile(struct ctdb_context *ctdb,
+			   struct timeval timeout, uint32_t destnode,
+			   TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
+{
+	int ret;
+	TDB_DATA outdata;
+	int32_t res;
+
+	ret = ctdb_control(ctdb, destnode, 0,
+			   CTDB_CONTROL_GET_NODES_FILE, 0, tdb_null,
+			   mem_ctx, &outdata, &res, &timeout, NULL);
+	if (ret != 0 || res != 0 || outdata.dsize == 0) {
+		DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
+		return -1;
+	}
+
+	*nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
+	talloc_free(outdata.dptr);
+
+	return 0;
+}
+
+/*
   old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
  */
 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb, 
diff --git a/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c
index bd68c55..76fb06d 100644
--- a/ctdb/common/ctdb_util.c
+++ b/ctdb/common/ctdb_util.c
@@ -155,32 +155,26 @@ void ctdb_external_trace(void)
 /*
   parse a IP:port pair
 */
-int ctdb_parse_address(struct ctdb_context *ctdb,
-		       TALLOC_CTX *mem_ctx, const char *str,
-		       struct ctdb_address *address)
+int ctdb_parse_address(TALLOC_CTX *mem_ctx, const char *str,
+		       ctdb_sock_addr *address)
 {
 	struct servent *se;
-	ctdb_sock_addr addr;
+	int port;
 
 	setservent(0);
 	se = getservbyname("ctdb", "tcp");
 	endservent();
 
-	/* Parse IP address and re-convert to string.  This ensure correct
-	 * string form for IPv6 addresses.
-	 */
-	if (! parse_ip(str, NULL, 0, &addr)) {
-		return -1;
-	}
-
-	address->address = talloc_strdup(mem_ctx, ctdb_addr_to_str(&addr));
-	CTDB_NO_MEMORY(ctdb, address->address);
-
 	if (se == NULL) {
-		address->port = CTDB_PORT;
+		port = CTDB_PORT;
 	} else {
-		address->port = ntohs(se->s_port);
+		port = ntohs(se->s_port);
 	}
+
+	if (! parse_ip(str, NULL, port, address)) {
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -188,9 +182,10 @@ int ctdb_parse_address(struct ctdb_context *ctdb,
 /*
   check if two addresses are the same
 */
-bool ctdb_same_address(struct ctdb_address *a1, struct ctdb_address *a2)
+bool ctdb_same_address(ctdb_sock_addr *a1, ctdb_sock_addr *a2)
 {
-	return strcmp(a1->address, a2->address) == 0 && a1->port == a2->port;
+	return ctdb_same_ip(a1, a2) &&
+		ctdb_addr_to_port(a1) == ctdb_addr_to_port(a2);
 }
 
 
@@ -491,6 +486,98 @@ unsigned ctdb_addr_to_port(ctdb_sock_addr *addr)
 	return 0;
 }
 
+/* Add a node to a node map with given address and flags */
+static bool node_map_add(TALLOC_CTX *mem_ctx,
+			 const char *nstr, uint32_t flags,
+			 struct ctdb_node_map **node_map)
+{
+	ctdb_sock_addr addr;
+	uint32_t num;
+	size_t s;
+	struct ctdb_node_and_flags *n;
+
+	/* Might as well do this before trying to allocate memory */
+	if (ctdb_parse_address(mem_ctx, nstr, &addr) == -1) {
+		return false;
+	}
+
+	num = (*node_map)->num + 1;
+	s = offsetof(struct ctdb_node_map, nodes) +
+		num * sizeof(struct ctdb_node_and_flags);
+	*node_map = talloc_realloc_size(mem_ctx, *node_map, s);
+	if (*node_map == NULL) {
+		DEBUG(DEBUG_ERR, (__location__ " Out of memory\n"));
+		return false;
+	}
+
+	n = &(*node_map)->nodes[(*node_map)->num];
+	n->addr = addr;
+	n->pnn = (*node_map)->num;
+	n->flags = flags;
+
+	(*node_map)->num++;
+
+	return true;
+}
+
+/* Read a nodes file into a node map */
+struct ctdb_node_map *ctdb_read_nodes_file(TALLOC_CTX *mem_ctx,
+					   const char *nlist)
+{
+	char **lines;
+	int nlines;
+	int i;
+	struct ctdb_node_map *ret;
+
+	/* Allocate node map header */
+	ret = talloc_zero_size(mem_ctx, offsetof(struct ctdb_node_map, nodes));
+	if (ret == NULL) {
+		DEBUG(DEBUG_ERR, (__location__ " Out of memory\n"));
+		return false;
+	}
+
+	lines = file_lines_load(nlist, &nlines, 0, mem_ctx);
+	if (lines == NULL) {
+		DEBUG(DEBUG_ERR, ("Failed to read nodes file \"%s\"\n", nlist));
+		return false;
+	}
+	while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
+		nlines--;
+	}
+
+	for (i=0; i < nlines; i++) {
+		const char *node;
+		uint32_t flags;
+
+		node = lines[i];
+		/* strip leading spaces */
+		while((*node == ' ') || (*node == '\t')) {
+			node++;
+		}
+		if (strcmp(node, "") == 0) {
+			continue;
+		}
+		if (*node == '#') {
+			/* A "deleted" node is a node that is
+			   commented out in the nodes file.  This is
+			   used instead of removing a line, which
+			   would cause subsequent nodes to change
+			   their PNN. */
+			flags = NODE_FLAGS_DELETED;
+			node = "0.0.0.0";
+		} else {
+			flags = 0;
+		}
+		if (!node_map_add(mem_ctx, node, flags, &ret)) {
+			talloc_free(lines);
+			TALLOC_FREE(ret);
+			return NULL;
+		}
+	}
+
+	talloc_free(lines);
+	return ret;
+}
 
 const char *ctdb_eventscript_call_names[] = {
 	"init",
diff --git a/ctdb/common/system_util.c b/ctdb/common/system_util.c
index 6ff82f7..1ae0bae 100644
--- a/ctdb/common/system_util.c
+++ b/ctdb/common/system_util.c
@@ -156,6 +156,9 @@ bool parse_ipv4(const char *s, unsigned port, struct sockaddr_in *sin)
 		return false;
 	}
 
+#ifdef HAVE_SOCK_SIN_LEN
+	sin->ip.sin_len = sizeof(*sin);
+#endif
 	return true;
 }
 
@@ -181,6 +184,9 @@ static bool parse_ipv6(const char *s, const char *ifaces, unsigned port, ctdb_so
 		saddr->ip6.sin6_scope_id = if_nametoindex(ifaces);
 	}
 
+#ifdef HAVE_SOCK_SIN_LEN
+	saddr->ip6.sin6_len = sizeof(*saddr);
+#endif
 	return true;
 }
 
diff --git a/ctdb/include/ctdb_client.h b/ctdb/include/ctdb_client.h
index 18b74b2..3051596 100644
--- a/ctdb/include/ctdb_client.h
+++ b/ctdb/include/ctdb_client.h
@@ -81,7 +81,7 @@ const char *ctdb_get_socketname(struct ctdb_context *ctdb);
   Check that a specific ip address exists in the node list and returns
   the id for the node or -1
 */
-int ctdb_ip_to_nodeid(struct ctdb_context *ctdb, const char *nodeip);
+int ctdb_ip_to_nodeid(struct ctdb_context *ctdb, const ctdb_sock_addr *nodeip);
 
 /*
   start the ctdb protocol
@@ -225,6 +225,10 @@ int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
 		    struct timeval timeout, uint32_t destnode,
 		    TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap);
 
+int ctdb_ctrl_getnodesfile(struct ctdb_context *ctdb,
+			   struct timeval timeout, uint32_t destnode,
+			   TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap);
+
 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb,
 		    struct timeval timeout, uint32_t destnode,
 		    TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap);
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index ed4d612..3248a56 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -140,15 +140,6 @@ struct ctdb_registered_call {
 };
 
 /*
-  this address structure might need to be generalised later for some
-  transports
-*/
-struct ctdb_address {
-	const char *address;
-	int port;
-};
-
-/*
   check that a pnn is valid
  */
 #define ctdb_validate_pnn(ctdb, pnn) (((uint32_t)(pnn)) < (ctdb)->num_nodes)
@@ -221,7 +212,7 @@ struct ctdb_vnn {
 */
 struct ctdb_node {
 	struct ctdb_context *ctdb;
-	struct ctdb_address address;
+	ctdb_sock_addr address;
 	const char *name; /* for debug messages */
 	void *private_data; /* private to transport */
 	uint32_t pnn;
@@ -466,7 +457,7 @@ struct ctdb_context {
 	struct ctdb_freeze_handle *freeze_handles[NUM_DB_PRIORITIES+1];
 	bool freeze_transaction_started;
 	uint32_t freeze_transaction_id;
-	struct ctdb_address address;
+	ctdb_sock_addr *address;
 	const char *name;
 	const char *db_directory;
 	const char *db_directory_persistent;
@@ -725,10 +716,9 @@ void ctdb_die(struct ctdb_context *ctdb, const char *msg);
 bool ctdb_set_helper(const char *type, char *helper, size_t size,
 		     const char *envvar, const char *dir, const char *file);
 void ctdb_external_trace(void);
-bool ctdb_same_address(struct ctdb_address *a1, struct ctdb_address *a2);
-int ctdb_parse_address(struct ctdb_context *ctdb,
-		       TALLOC_CTX *mem_ctx, const char *str,
-		       struct ctdb_address *address);
+bool ctdb_same_address(ctdb_sock_addr *a1, ctdb_sock_addr *a2);
+int ctdb_parse_address(TALLOC_CTX *mem_ctx, const char *str,
+		       ctdb_sock_addr *address);
 bool ctdb_same_ip(const ctdb_sock_addr *ip1, const ctdb_sock_addr *ip2);
 bool ctdb_same_sockaddr(const ctdb_sock_addr *ip1, const ctdb_sock_addr *ip2);
 uint32_t ctdb_hash(const TDB_DATA *key);
@@ -946,6 +936,7 @@ int ctdb_control_setvnnmap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA
 int ctdb_control_getdbmap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata);
 int ctdb_control_getnodemapv4(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata);
 int ctdb_control_getnodemap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata);
+int ctdb_control_getnodesfile(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata);
 int ctdb_control_writerecord(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata);
 
 
@@ -1398,6 +1389,8 @@ int ctdb_client_async_control(struct ctdb_context *ctdb,
 			        client_async_callback fail_callback,
 				void *callback_data);
 
+struct ctdb_node_map *ctdb_read_nodes_file(TALLOC_CTX *mem_ctx,
+					   const char *nlist);
 void ctdb_load_nodes_file(struct ctdb_context *ctdb);
 
 int ctdb_control_reload_nodes_file(struct ctdb_context *ctdb, uint32_t opcode);
diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h
index 3cecc12..c828c01 100644
--- a/ctdb/include/ctdb_protocol.h
+++ b/ctdb/include/ctdb_protocol.h
@@ -411,6 +411,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS          = 0,
 		    CTDB_CONTROL_IPREALLOCATED		 = 137,
 		    CTDB_CONTROL_GET_RUNSTATE		 = 138,
 		    CTDB_CONTROL_DB_DETACH		 = 139,
+		    CTDB_CONTROL_GET_NODES_FILE		 = 140,
 };
 
 /*
diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c
index 7bd1d0d..dafdc42 100644
--- a/ctdb/server/ctdb_control.c
+++ b/ctdb/server/ctdb_control.c
@@ -169,6 +169,9 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 	case CTDB_CONTROL_GET_NODEMAP:
 		return ctdb_control_getnodemap(ctdb, opcode, indata, outdata);
 
+	case CTDB_CONTROL_GET_NODES_FILE:
+		return ctdb_control_getnodesfile(ctdb, opcode, indata, outdata);
+
 	case CTDB_CONTROL_RELOAD_NODES_FILE:
 		CHECK_CONTROL_DATA_SIZE(0);
 		return ctdb_control_reload_nodes_file(ctdb, opcode);
diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c
index aac507c..f5876a6 100644
--- a/ctdb/server/ctdb_daemon.c
+++ b/ctdb/server/ctdb_daemon.c
@@ -1139,6 +1139,54 @@ static void ctdb_create_pidfile(pid_t pid)
 	}
 }
 
+static void ctdb_initialise_vnn_map(struct ctdb_context *ctdb)
+{
+	int i, j, count;
+
+	/* initialize the vnn mapping table, skipping any deleted nodes */
+	ctdb->vnn_map = talloc(ctdb, struct ctdb_vnn_map);
+	CTDB_NO_MEMORY_FATAL(ctdb, ctdb->vnn_map);
+
+	count = 0;
+	for (i = 0; i < ctdb->num_nodes; i++) {
+		if ((ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) == 0) {
+			count++;
+		}
+	}
+
+	ctdb->vnn_map->generation = INVALID_GENERATION;
+	ctdb->vnn_map->size = count;
+	ctdb->vnn_map->map = talloc_array(ctdb->vnn_map, uint32_t, ctdb->vnn_map->size);
+	CTDB_NO_MEMORY_FATAL(ctdb, ctdb->vnn_map->map);
+
+	for(i=0, j=0; i < ctdb->vnn_map->size; i++) {
+		if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
+			continue;
+		}
+		ctdb->vnn_map->map[j] = i;
+		j++;
+	}
+}
+
+static void ctdb_set_my_pnn(struct ctdb_context *ctdb)
+{
+	int nodeid;
+
+	if (ctdb->address == NULL) {
+		ctdb_fatal(ctdb,
+			   "Can not determine PNN - node address is not set\n");
+	}
+
+	nodeid = ctdb_ip_to_nodeid(ctdb, ctdb->address);
+	if (nodeid == -1) {
+		ctdb_fatal(ctdb,
+			   "Can not determine PNN - node address not found in node list\n");
+	}
+
+	ctdb->pnn = ctdb->nodes[nodeid]->pnn;
+	DEBUG(DEBUG_NOTICE, ("PNN is %u\n", ctdb->pnn));
+}
+
 /*
   start the protocol going as a daemon
 */
@@ -1247,11 +1295,14 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork)
 		ctdb_fatal(ctdb, "transport is unavailable. can not initialize.");
 	}
 
-	/* initialise the transport  */
+	/* Initialise the transport.  This sets the node address if it
+	 * was not set via the command-line. */
 	if (ctdb->methods->initialise(ctdb) != 0) {
 		ctdb_fatal(ctdb, "transport failed to initialise");
 	}
 
+	ctdb_set_my_pnn(ctdb);
+
 	initialise_node_flags(ctdb);
 
 	if (ctdb->public_addresses_file) {
@@ -1265,6 +1316,7 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork)
 		}
 	}
 
+	ctdb_initialise_vnn_map(ctdb);
 
 	/* attach to existing databases */
 	if (ctdb_attach_databases(ctdb) != 0) {
@@ -1730,6 +1782,24 @@ int32_t ctdb_control_process_exists(struct ctdb_context *ctdb, pid_t pid)
 	return kill(pid, 0);
 }
 
+int ctdb_control_getnodesfile(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata)
+{
+	struct ctdb_node_map *node_map = NULL;
+
+	CHECK_CONTROL_DATA_SIZE(0);
+
+	node_map = ctdb_read_nodes_file(ctdb, ctdb->nodes_file);
+	if (node_map == NULL) {
+		DEBUG(DEBUG_ERR, ("Failed to read nodes file\n"));
+		return -1;
+	}
+
+	outdata->dptr  = (unsigned char *)node_map;
+	outdata->dsize = talloc_get_size(outdata->dptr);
+
+	return 0;
+}
+
 void ctdb_shutdown_sequence(struct ctdb_context *ctdb, int exit_code)
 {
 	if (ctdb->runstate == CTDB_RUNSTATE_SHUTDOWN) {
diff --git a/ctdb/server/ctdb_recover.c b/ctdb/server/ctdb_recover.c
index db88f06..eb3f46d 100644
--- a/ctdb/server/ctdb_recover.c
+++ b/ctdb/server/ctdb_recover.c
@@ -138,14 +138,7 @@ ctdb_control_getnodemap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA ind
 	node_map = (struct ctdb_node_map *)outdata->dptr;
 	node_map->num = num_nodes;
 	for (i=0; i<num_nodes; i++) {
-		if (parse_ip(ctdb->nodes[i]->address.address,
-			     NULL, /* TODO: pass in the correct interface here*/
-			     0,
-			     &node_map->nodes[i].addr) == 0)
-		{
-			DEBUG(DEBUG_ERR, (__location__ " Failed to parse %s into a sockaddr\n", ctdb->nodes[i]->address.address));
-		}
-
+		node_map->nodes[i].addr = ctdb->nodes[i]->address;
 		node_map->nodes[i].pnn   = ctdb->nodes[i]->pnn;
 		node_map->nodes[i].flags = ctdb->nodes[i]->flags;
 	}
@@ -176,11 +169,7 @@ ctdb_control_getnodemapv4(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA i
 	node_map = (struct ctdb_node_mapv4 *)outdata->dptr;
 	node_map->num = num_nodes;
 	for (i=0; i<num_nodes; i++) {
-		if (parse_ipv4(ctdb->nodes[i]->address.address, 0, &node_map->nodes[i].sin) == 0) {
-			DEBUG(DEBUG_ERR, (__location__ " Failed to parse %s into a sockaddr\n", ctdb->nodes[i]->address.address));
-			return -1;
-		}
-
+		node_map->nodes[i].sin   = ctdb->nodes[i]->address.ip;
 		node_map->nodes[i].pnn   = ctdb->nodes[i]->pnn;
 		node_map->nodes[i].flags = ctdb->nodes[i]->flags;
 	}
diff --git a/ctdb/server/ctdb_server.c b/ctdb/server/ctdb_server.c
index 2598c4c..81ef361 100644
--- a/ctdb/server/ctdb_server.c
+++ b/ctdb/server/ctdb_server.c
@@ -39,7 +39,7 @@ int ctdb_set_transport(struct ctdb_context *ctdb, const char *transport)
   Check whether an ip is a valid node ip
   Returns the node id for this ip address or -1
 */
-int ctdb_ip_to_nodeid(struct ctdb_context *ctdb, const char *nodeip)
+int ctdb_ip_to_nodeid(struct ctdb_context *ctdb, const ctdb_sock_addr *nodeip)
 {
 	int nodeid;
 
@@ -47,7 +47,7 @@ int ctdb_ip_to_nodeid(struct ctdb_context *ctdb, const char *nodeip)
 		if (ctdb->nodes[nodeid]->flags & NODE_FLAGS_DELETED) {
 			continue;
 		}
-		if (!strcmp(ctdb->nodes[nodeid]->address.address, nodeip)) {
+		if (ctdb_same_ip(&ctdb->nodes[nodeid]->address, nodeip)) {
 			return nodeid;
 		}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list