[SCM] CTDB repository - branch master updated - ctdb-2.1-198-gc574309

Amitay Isaacs amitay at samba.org
Fri May 24 05:47:27 MDT 2013


The branch, master has been updated
       via  c57430998a3bdedc8a904eb3a9cdfde1421aff50 (commit)
       via  f15dd562fd8c08cafd957ce9509102db7eb49668 (commit)
       via  c0c27762ea728ed86405b29c642ba9e43200f4ae (commit)
       via  1190bb0d9c14dc5889c2df56f6c8986db23d81a1 (commit)
       via  40e34773b8063196457746ffe7a048eb87d96d61 (commit)
       via  03fd90d41f9cd9b8c42dc6b8b8d46ae19101a544 (commit)
       via  473cfcb019f0cb4a094bf10397f7414f7923ee57 (commit)
       via  f6792f478197774d2f3b2258c969b67c83e017ab (commit)
      from  c50eca6fbf49a6c7bf50905334704f8d2d3237d7 (commit)

http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c57430998a3bdedc8a904eb3a9cdfde1421aff50
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon May 6 20:31:08 2013 +1000

    tests/takeover: New tests to check runstate handling
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit f15dd562fd8c08cafd957ce9509102db7eb49668
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon May 6 15:36:29 2013 +1000

    recoverd: Nodes can only takeover IPs if they are in runstate RUNNING
    
    Currently the order of the first IP allocation, including the first
    "ipreallocated" event, and the "startup" event is undefined.  Both of
    these events can (re)start services.
    
    This stops IPs being hosted before the "startup" event has completed.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Pair-programmed-with: Amitay Isaacs <amitay at gmail.com>

commit c0c27762ea728ed86405b29c642ba9e43200f4ae
Author: Martin Schwenke <martin at meltin.net>
Date:   Thu May 23 19:03:11 2013 +1000

    recoverd: Handle errors carefully when fetching tunables
    
    If a tunable is not implemented on a remote node then this should not
    be fatal.  In this case the takeover run can continue using benign
    defaults for the tunables.
    
    However, timeouts and any unexpected errors should be fatal.  These
    should abort the takeover run because they can lead to unexpected IP
    movements.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit 1190bb0d9c14dc5889c2df56f6c8986db23d81a1
Author: Martin Schwenke <martin at meltin.net>
Date:   Thu May 23 19:01:01 2013 +1000

    recoverd: Set explicit default value when getting tunable from nodes
    
    Both of the current defaults are implicitly 0.  It is better to make
    the defaults obvious.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit 40e34773b8063196457746ffe7a048eb87d96d61
Author: Martin Schwenke <martin at meltin.net>
Date:   Thu May 23 16:09:38 2013 +1000

    client: async_callback() sets result to -ETIME if a control times out
    
    Otherwise there is no way of treating a timeout differently to a
    general failure.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Pair-programmed-with: Amitay Isaacs <amitay at gmail.com>

commit 03fd90d41f9cd9b8c42dc6b8b8d46ae19101a544
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue May 21 15:41:56 2013 +1000

    ctdbd: Update the get_tunable code to return -EINVAL for unknown tunable
    
    Otherwise callers can't tell the difference between some other failure
    (e.g. memory allocation failure) and an unknown tunable.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit 473cfcb019f0cb4a094bf10397f7414f7923ee57
Author: Martin Schwenke <martin at meltin.net>
Date:   Wed May 22 17:19:34 2013 +1000

    recoverd: Whitespace improvements
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit f6792f478197774d2f3b2258c969b67c83e017ab
Author: Martin Schwenke <martin at meltin.net>
Date:   Wed May 22 20:56:03 2013 +1000

    recoverd: Use talloc_array_length() for simpler code
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

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

Summary of changes:
 client/ctdb_client.c                        |    7 +-
 server/ctdb_takeover.c                      |  211 +++++++++++++++++++++++----
 server/ctdb_tunables.c                      |    2 +-
 tests/src/ctdb_takeover_tests.c             |   30 ++++-
 tests/takeover/lcp2.024.sh                  |   42 ++++++
 tests/takeover/{lcp2.007.sh => lcp2.025.sh} |   24 ++--
 tests/takeover/{lcp2.007.sh => lcp2.026.sh} |   24 ++--
 tools/ctdb.c                                |    2 +-
 8 files changed, 287 insertions(+), 55 deletions(-)
 create mode 100755 tests/takeover/lcp2.024.sh
 copy tests/takeover/{lcp2.007.sh => lcp2.025.sh} (71%)
 copy tests/takeover/{lcp2.007.sh => lcp2.026.sh} (70%)


Changeset truncated at 500 lines:

diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index e930bff..334d830 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -2502,7 +2502,7 @@ int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
 	talloc_free(data.dptr);
 	if (ret != 0 || res != 0) {
 		DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
-		return -1;
+		return ret != 0 ? ret : res;
 	}
 
 	if (outdata.dsize != sizeof(uint32_t)) {
@@ -3329,6 +3329,11 @@ static void async_callback(struct ctdb_client_control_state *state)
 			DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
 		}
 		data->fail_count++;
+		if (state->state == CTDB_CONTROL_TIMEOUT) {
+			res = -ETIME;
+		} else {
+			res = -1;
+		}
 		if (data->fail_callback) {
 			data->fail_callback(ctdb, destnode, res, outdata,
 					data->callback_data);
diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c
index d8e77df..b5e7f87 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -1324,7 +1324,7 @@ static bool can_node_host_ip(struct ctdb_context *ctdb, int32_t pnn,
 		return false;
 	}
 
-	for (i=0;i<public_ips->num;i++) {
+	for (i=0; i<public_ips->num; i++) {
 		if (ctdb_same_ip(&ip->addr, &public_ips->ips[i].addr)) {
 			/* yes, this node can serve this public ip */
 			return true;
@@ -1357,9 +1357,9 @@ static int find_takeover_node(struct ctdb_context *ctdb,
 	int pnn, min=0, num;
 	int i, numnodes;
 
-	numnodes = talloc_get_size(ipflags) / sizeof(struct ctdb_ipflags);
+	numnodes = talloc_array_length(ipflags);
 	pnn    = -1;
-	for (i=0;i<numnodes;i++) {
+	for (i=0; i<numnodes; i++) {
 		/* verify that this node can serve this ip */
 		if (!can_node_takeover_ip(ctdb, i, ipflags[i], ip)) {
 			/* no it couldnt   so skip to the next node */
@@ -1626,7 +1626,7 @@ static void basic_failback(struct ctdb_context *ctdb,
 	int maxnode, maxnum, minnode, minnum, num, retries;
 	struct ctdb_public_ip_list *tmp_ip;
 
-	numnodes = talloc_get_size(ipflags) / sizeof(struct ctdb_ipflags);
+	numnodes = talloc_array_length(ipflags);
 	retries = 0;
 
 try_again:
@@ -1648,7 +1648,7 @@ try_again:
 		*/
 		maxnode = -1;
 		minnode = -1;
-		for (i=0;i<numnodes;i++) {
+		for (i=0; i<numnodes; i++) {
 			/* only check nodes that can actually serve this ip */
 			if (!can_node_takeover_ip(ctdb, i, ipflags[i], tmp_ip)) {
 				/* no it couldnt   so skip to the next node */
@@ -1742,14 +1742,14 @@ static void lcp2_init(struct ctdb_context *tmp_ctx,
 	int i, numnodes;
 	struct ctdb_public_ip_list *tmp_ip;
 
-	numnodes = talloc_get_size(ipflags) / sizeof(struct ctdb_ipflags);
+	numnodes = talloc_array_length(ipflags);
 
 	*rebalance_candidates = talloc_array(tmp_ctx, bool, numnodes);
 	CTDB_NO_MEMORY_FATAL(tmp_ctx, *rebalance_candidates);
 	*lcp2_imbalances = talloc_array(tmp_ctx, uint32_t, numnodes);
 	CTDB_NO_MEMORY_FATAL(tmp_ctx, *lcp2_imbalances);
 
-	for (i=0;i<numnodes;i++) {
+	for (i=0; i<numnodes; i++) {
 		(*lcp2_imbalances)[i] = lcp2_imbalance(all_ips, i);
 		/* First step: assume all nodes are candidates */
 		(*rebalance_candidates)[i] = true;
@@ -1801,7 +1801,7 @@ static void lcp2_allocate_unassigned(struct ctdb_context *ctdb,
 	bool should_loop = true;
 	bool have_unassigned = true;
 
-	numnodes = talloc_get_size(ipflags) / sizeof(struct ctdb_ipflags);
+	numnodes = talloc_array_length(ipflags);
 
 	while (have_unassigned && should_loop) {
 		should_loop = false;
@@ -1819,7 +1819,7 @@ static void lcp2_allocate_unassigned(struct ctdb_context *ctdb,
 				continue;
 			}
 
-			for (dstnode=0; dstnode < numnodes; dstnode++) {
+			for (dstnode=0; dstnode<numnodes; dstnode++) {
 				/* only check nodes that can actually takeover this ip */
 				if (!can_node_takeover_ip(ctdb, dstnode,
 							  ipflags[dstnode],
@@ -1904,7 +1904,7 @@ static bool lcp2_failback_candidate(struct ctdb_context *ctdb,
 	mindstnode = -1;
 	mindstimbl = 0;
 
-	numnodes = talloc_get_size(ipflags) / sizeof(struct ctdb_ipflags);
+	numnodes = talloc_array_length(ipflags);
 
 	DEBUG(DEBUG_DEBUG,(" ----------------------------------------\n"));
 	DEBUG(DEBUG_DEBUG,(" CONSIDERING MOVES FROM %d [%d]\n", srcnode, candimbl));
@@ -1925,7 +1925,7 @@ static bool lcp2_failback_candidate(struct ctdb_context *ctdb,
 		 * to do gratuitous failover of IPs just to make minor
 		 * balance improvements.
 		 */
-		for (dstnode=0; dstnode < numnodes; dstnode++) {
+		for (dstnode=0; dstnode<numnodes; dstnode++) {
 			if (!rebalance_candidates[dstnode]) {
 				continue;
 			}
@@ -2009,7 +2009,7 @@ static void lcp2_failback(struct ctdb_context *ctdb,
 	struct lcp2_imbalance_pnn * lips;
 	bool again;
 
-	numnodes = talloc_get_size(ipflags) / sizeof(struct ctdb_ipflags);
+	numnodes = talloc_array_length(ipflags);
 
 try_again:
 
@@ -2018,7 +2018,7 @@ try_again:
 	 * continuing on...
 	 */
 	num_rebalance_candidates = 0;
-	for (i = 0; i < numnodes; i++) {
+	for (i=0; i<numnodes; i++) {
 		if (rebalance_candidates[i]) {
 			num_rebalance_candidates++;
 		}
@@ -2032,7 +2032,7 @@ try_again:
 	 * used, so this doesn't cost much...
 	 */
 	lips = talloc_array(ctdb, struct lcp2_imbalance_pnn, numnodes);
-	for (i = 0; i < numnodes; i++) {
+	for (i=0; i<numnodes; i++) {
 		lips[i].imbalance = lcp2_imbalances[i];
 		lips[i].pnn = i;
 	}
@@ -2040,7 +2040,7 @@ try_again:
 	      lcp2_cmp_imbalance_pnn);
 
 	again = false;
-	for (i = 0; i < numnodes; i++) {
+	for (i=0; i<numnodes; i++) {
 		/* This means that all nodes had 0 or 1 addresses, so
 		 * can't be imbalanced.
 		 */
@@ -2097,7 +2097,7 @@ static void ip_alloc_deterministic_ips(struct ctdb_context *ctdb,
 	struct ctdb_public_ip_list *tmp_ip;
 	int i, numnodes;
 
-	numnodes = talloc_get_size(ipflags) / sizeof(struct ctdb_ipflags);
+	numnodes = talloc_array_length(ipflags);
 
 	DEBUG(DEBUG_NOTICE,("Deterministic IPs enabled. Resetting all ip allocations\n"));
        /* Allocate IPs to nodes in a modulo fashion so that IPs will
@@ -2106,7 +2106,7 @@ static void ip_alloc_deterministic_ips(struct ctdb_context *ctdb,
 	*/
 
 	for (i=0,tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next,i++) {
-		tmp_ip->pnn = i%numnodes;
+		tmp_ip->pnn = i % numnodes;
 	}
 
 	/* IP failback doesn't make sense with deterministic
@@ -2229,6 +2229,7 @@ static void ctdb_takeover_run_core(struct ctdb_context *ctdb,
 struct get_tunable_callback_data {
 	const char *tunable;
 	uint32_t *out;
+	bool fatal;
 };
 
 static void get_tunable_callback(struct ctdb_context *ctdb, uint32_t pnn,
@@ -2240,9 +2241,7 @@ static void get_tunable_callback(struct ctdb_context *ctdb, uint32_t pnn,
 	int size;
 
 	if (res != 0) {
-		DEBUG(DEBUG_ERR,
-		      ("Failure to read \"%s\" tunable from remote node %d\n",
-		       cd->tunable, pnn));
+		/* Already handled in fail callback */
 		return;
 	}
 
@@ -2250,10 +2249,11 @@ static void get_tunable_callback(struct ctdb_context *ctdb, uint32_t pnn,
 		DEBUG(DEBUG_ERR,("Wrong size of returned data when reading \"%s\" tunable from node %d. Expected %d bytes but received %d bytes\n",
 				 cd->tunable, pnn, (int)sizeof(uint32_t),
 				 (int)outdata.dsize));
+		cd->fatal = true;
 		return;
 	}
 
-	size = talloc_get_size(cd->out) / sizeof(uint32_t);
+	size = talloc_array_length(cd->out);
 	if (pnn >= size) {
 		DEBUG(DEBUG_ERR,("Got %s reply from node %d but nodemap only has %d entries\n",
 				 cd->tunable, pnn, size));
@@ -2264,21 +2264,56 @@ static void get_tunable_callback(struct ctdb_context *ctdb, uint32_t pnn,
 	cd->out[pnn] = *(uint32_t *)outdata.dptr;
 }
 
+static void get_tunable_fail_callback(struct ctdb_context *ctdb, uint32_t pnn,
+				       int32_t res, TDB_DATA outdata,
+				       void *callback)
+{
+	struct get_tunable_callback_data *cd =
+		(struct get_tunable_callback_data *)callback;
+
+	switch (res) {
+	case -ETIME:
+		DEBUG(DEBUG_ERR,
+		      ("Timed out getting tunable \"%s\" from node %d\n",
+		       cd->tunable, pnn));
+		cd->fatal = true;
+		break;
+	case -EINVAL:
+	case -1:
+		DEBUG(DEBUG_WARNING,
+		      ("Tunable \"%s\" not implemented on node %d\n",
+		       cd->tunable, pnn));
+		break;
+	default:
+		DEBUG(DEBUG_ERR,
+		      ("Unexpected error getting tunable \"%s\" from node %d\n",
+		       cd->tunable, pnn));
+		cd->fatal = true;
+	}
+}
+
 static uint32_t *get_tunable_from_nodes(struct ctdb_context *ctdb,
 					TALLOC_CTX *tmp_ctx,
 					struct ctdb_node_map *nodemap,
-					const char *tunable)
+					const char *tunable,
+					uint32_t default_value)
 {
 	TDB_DATA data;
 	struct ctdb_control_get_tunable *t;
 	uint32_t *nodes;
 	uint32_t *tvals;
 	struct get_tunable_callback_data callback_data;
+	int i;
 
-	tvals = talloc_zero_array(tmp_ctx, uint32_t, nodemap->num);
+	tvals = talloc_array(tmp_ctx, uint32_t, nodemap->num);
 	CTDB_NO_MEMORY_NULL(ctdb, tvals);
+	for (i=0; i<nodemap->num; i++) {
+		tvals[i] = default_value;
+	}
+		
 	callback_data.out = tvals;
 	callback_data.tunable = tunable;
+	callback_data.fatal = false;
 
 	data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(tunable) + 1;
 	data.dptr  = talloc_size(tmp_ctx, data.dsize);
@@ -2289,9 +2324,13 @@ static uint32_t *get_tunable_from_nodes(struct ctdb_context *ctdb,
 	if (ctdb_client_async_control(ctdb, CTDB_CONTROL_GET_TUNABLE,
 				      nodes, 0, TAKEOVER_TIMEOUT(),
 				      false, data,
-				      get_tunable_callback, NULL,
+				      get_tunable_callback,
+				      get_tunable_fail_callback,
 				      &callback_data) != 0) {
-		DEBUG(DEBUG_ERR, (__location__ " ctdb_control to get %s tunable failed\n", tunable));
+		if (callback_data.fatal) {
+			talloc_free(tvals);
+			tvals = NULL;
+		}
 	}
 	talloc_free(nodes);
 	talloc_free(data.dptr);
@@ -2299,6 +2338,98 @@ static uint32_t *get_tunable_from_nodes(struct ctdb_context *ctdb,
 	return tvals;
 }
 
+struct get_runstate_callback_data {
+	enum ctdb_runstate *out;
+	bool fatal;
+};
+
+static void get_runstate_callback(struct ctdb_context *ctdb, uint32_t pnn,
+				  int32_t res, TDB_DATA outdata,
+				  void *callback_data)
+{
+	struct get_runstate_callback_data *cd =
+		(struct get_runstate_callback_data *)callback_data;
+	int size;
+
+	if (res != 0) {
+		/* Already handled in fail callback */
+		return;
+	}
+
+	if (outdata.dsize != sizeof(uint32_t)) {
+		DEBUG(DEBUG_ERR,("Wrong size of returned data when getting runstate from node %d. Expected %d bytes but received %d bytes\n",
+				 pnn, (int)sizeof(uint32_t),
+				 (int)outdata.dsize));
+		cd->fatal = true;
+		return;
+	}
+
+	size = talloc_array_length(cd->out);
+	if (pnn >= size) {
+		DEBUG(DEBUG_ERR,("Got reply from node %d but nodemap only has %d entries\n",
+				 pnn, size));
+		return;
+	}
+
+	cd->out[pnn] = (enum ctdb_runstate)*(uint32_t *)outdata.dptr;
+}
+
+static void get_runstate_fail_callback(struct ctdb_context *ctdb, uint32_t pnn,
+				       int32_t res, TDB_DATA outdata,
+				       void *callback)
+{
+	struct get_runstate_callback_data *cd =
+		(struct get_runstate_callback_data *)callback;
+
+	switch (res) {
+	case -ETIME:
+		DEBUG(DEBUG_ERR,
+		      ("Timed out getting runstate from node %d\n", pnn));
+		cd->fatal = true;
+		break;
+	default:
+		DEBUG(DEBUG_WARNING,
+		      ("Error getting runstate from node %d - assuming runstates not supported\n",
+		       pnn));
+	}
+}
+
+static enum ctdb_runstate * get_runstate_from_nodes(struct ctdb_context *ctdb,
+						    TALLOC_CTX *tmp_ctx,
+						    struct ctdb_node_map *nodemap,
+						    enum ctdb_runstate default_value)
+{
+	uint32_t *nodes;
+	enum ctdb_runstate *rs;
+	struct get_runstate_callback_data callback_data;
+	int i;
+
+	rs = talloc_array(tmp_ctx, enum ctdb_runstate, nodemap->num);
+	CTDB_NO_MEMORY_NULL(ctdb, rs);
+	for (i=0; i<nodemap->num; i++) {
+		rs[i] = default_value;
+	}
+
+	callback_data.out = rs;
+	callback_data.fatal = false;
+
+	nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
+	if (ctdb_client_async_control(ctdb, CTDB_CONTROL_GET_RUNSTATE,
+				      nodes, 0, TAKEOVER_TIMEOUT(),
+				      true, tdb_null,
+				      get_runstate_callback,
+				      get_runstate_fail_callback,
+				      &callback_data) != 0) {
+		if (callback_data.fatal) {
+			free(rs);
+			rs = NULL;
+		}
+	}
+	talloc_free(nodes);
+
+	return rs;
+}
+
 /* Set internal flags for IP allocation:
  *   Clear ip flags
  *   Set NOIPTAKOVER ip flags from per-node NoIPTakeover tunable
@@ -2313,7 +2444,8 @@ set_ipflags_internal(struct ctdb_context *ctdb,
 		     TALLOC_CTX *tmp_ctx,
 		     struct ctdb_node_map *nodemap,
 		     uint32_t *tval_noiptakeover,
-		     uint32_t *tval_noiphostonalldisabled)
+		     uint32_t *tval_noiphostonalldisabled,
+		     enum ctdb_runstate *runstate)
 {
 	int i;
 	struct ctdb_ipflags *ipflags;
@@ -2328,6 +2460,11 @@ set_ipflags_internal(struct ctdb_context *ctdb,
 			ipflags[i].noiptakeover = true;
 		}
 
+		/* Can not host IPs on node not in RUNNING state */
+		if (runstate[i] != CTDB_RUNSTATE_RUNNING) {
+			ipflags[i].noiphost = true;
+			continue;
+		}
 		/* Can not host IPs on INACTIVE node */
 		if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
 			ipflags[i].noiphost = true;
@@ -2364,26 +2501,42 @@ static struct ctdb_ipflags *set_ipflags(struct ctdb_context *ctdb,
 	uint32_t *tval_noiptakeover;
 	uint32_t *tval_noiphostonalldisabled;
 	struct ctdb_ipflags *ipflags;
+	enum ctdb_runstate *runstate;
+
 
 	tval_noiptakeover = get_tunable_from_nodes(ctdb, tmp_ctx, nodemap,
-						   "NoIPTakeover");
+						   "NoIPTakeover", 0);
 	if (tval_noiptakeover == NULL) {
 		return NULL;
 	}
 
 	tval_noiphostonalldisabled =
 		get_tunable_from_nodes(ctdb, tmp_ctx, nodemap,
-				       "NoIPHostOnAllDisabled");
+				       "NoIPHostOnAllDisabled", 0);
 	if (tval_noiphostonalldisabled == NULL) {
+		/* Caller frees tmp_ctx */
+		return NULL;
+	}
+
+	/* Any nodes where CTDB_CONTROL_GET_RUNSTATE is not supported
+	 * will default to CTDB_RUNSTATE_RUNNING.  This ensures
+	 * reasonable behaviour on a mixed cluster during upgrade.
+	 */
+	runstate = get_runstate_from_nodes(ctdb, tmp_ctx, nodemap,
+					   CTDB_RUNSTATE_RUNNING);
+	if (runstate == NULL) {
+		/* Caller frees tmp_ctx */
 		return NULL;
 	}
 
 	ipflags = set_ipflags_internal(ctdb, tmp_ctx, nodemap,
 				       tval_noiptakeover,
-				       tval_noiphostonalldisabled);
+				       tval_noiphostonalldisabled,
+				       runstate);
 
 	talloc_free(tval_noiptakeover);
 	talloc_free(tval_noiphostonalldisabled);
+	talloc_free(runstate);
 
 	return ipflags;
 }
diff --git a/server/ctdb_tunables.c b/server/ctdb_tunables.c
index 84fb949..365c6ba 100644
--- a/server/ctdb_tunables.c
+++ b/server/ctdb_tunables.c
@@ -128,7 +128,7 @@ int32_t ctdb_control_get_tunable(struct ctdb_context *ctdb, TDB_DATA indata,
 	talloc_free(name);
 	
 	if (i == ARRAY_SIZE(tunable_map)) {
-		return -1;
+		return -EINVAL;
 	}
 
 	val = *(uint32_t *)(tunable_map[i].offset + (uint8_t*)&ctdb->tunable);
diff --git a/tests/src/ctdb_takeover_tests.c b/tests/src/ctdb_takeover_tests.c
index e804c9a..196f90d 100644
--- a/tests/src/ctdb_takeover_tests.c
+++ b/tests/src/ctdb_takeover_tests.c
@@ -353,6 +353,30 @@ static uint32_t *get_tunable_values(TALLOC_CTX *tmp_ctx,
 	return tvals;
 }
 
+static enum ctdb_runstate *get_runstate(TALLOC_CTX *tmp_ctx,
+					int numnodes)
+{
+	int i;
+	uint32_t *tvals;
+	enum ctdb_runstate *runstate =
+		talloc_zero_array(tmp_ctx, enum ctdb_runstate, numnodes);
+	char *t = getenv("CTDB_TEST_RUNSTATE");
+
+	if (t == NULL) {
+		for (i=0; i<numnodes; i++) {
+			runstate[i] = CTDB_RUNSTATE_RUNNING;
+		}
+	} else {
+		tvals = get_tunable_values(tmp_ctx, numnodes, "CTDB_TEST_RUNSTATE");
+		for (i=0; i<numnodes; i++) {
+			runstate[i] = (enum ctdb_runstate) tvals[i];
+		}
+		talloc_free(tvals);
+	}
+
+	return runstate;
+}
+
 void ctdb_test_init(const char nodestates[],
 		    struct ctdb_context **ctdb,
 		    struct ctdb_public_ip_list **all_ips,
@@ -365,6 +389,7 @@ void ctdb_test_init(const char nodestates[],
 	struct ctdb_node_map *nodemap;
 	uint32_t *tval_noiptakeover;


-- 
CTDB repository


More information about the samba-cvs mailing list