1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

ctdb-takeover: NoIPHostOnAllDisabled is global across cluster

Instead of gathering the value from all nodes, just use the value on
the recovery master and have it affect all nodes.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
This commit is contained in:
Martin Schwenke 2016-12-10 20:03:38 +11:00 committed by Amitay Isaacs
parent 9b456bc730
commit 3d80fdd580
7 changed files with 34 additions and 223 deletions

View File

@ -1236,118 +1236,6 @@ ctdb_fetch_remote_public_ips(struct ctdb_context *ctdb,
return public_ips;
}
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,
int32_t res, TDB_DATA outdata,
void *callback)
{
struct get_tunable_callback_data *cd =
(struct get_tunable_callback_data *)callback;
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 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_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));
return;
}
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_old *nodemap,
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_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);
t = (struct ctdb_control_get_tunable *)data.dptr;
t->length = strlen(tunable)+1;
memcpy(t->name, tunable, t->length);
nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
if (ctdb_client_async_control(ctdb, CTDB_CONTROL_GET_TUNABLE,
nodes, 0, TAKEOVER_TIMEOUT(),
false, data,
get_tunable_callback,
get_tunable_fail_callback,
&callback_data) != 0) {
if (callback_data.fatal) {
talloc_free(tvals);
tvals = NULL;
}
}
talloc_free(nodes);
talloc_free(data.dptr);
return tvals;
}
static struct ctdb_node_map *
ctdb_node_map_old_to_new(TALLOC_CTX *mem_ctx,
const struct ctdb_node_map_old *old)
@ -1373,26 +1261,15 @@ static bool set_ipflags(struct ctdb_context *ctdb,
struct ipalloc_state *ipalloc_state,
struct ctdb_node_map_old *nodemap)
{
uint32_t *tval_noiphostonalldisabled;
struct ctdb_node_map *new;
tval_noiphostonalldisabled =
get_tunable_from_nodes(ctdb, ipalloc_state, nodemap,
"NoIPHostOnAllDisabled", 0);
if (tval_noiphostonalldisabled == NULL) {
/* Caller frees tmp_ctx */
return false;
}
new = ctdb_node_map_old_to_new(ipalloc_state, nodemap);
if (new == NULL) {
return false;
}
ipalloc_set_node_flags(ipalloc_state, new,
tval_noiphostonalldisabled);
ipalloc_set_node_flags(ipalloc_state, new);
talloc_free(tval_noiphostonalldisabled);
talloc_free(new);
return true;
@ -1562,11 +1439,13 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map_old *nodem
goto ipreallocated;
}
ipalloc_state = ipalloc_state_init(tmp_ctx, ctdb->num_nodes,
determine_algorithm(&ctdb->tunable),
(ctdb->tunable.no_ip_takeover != 0),
(ctdb->tunable.no_ip_failback != 0),
force_rebalance_nodes);
ipalloc_state = ipalloc_state_init(
tmp_ctx, ctdb->num_nodes,
determine_algorithm(&ctdb->tunable),
(ctdb->tunable.no_ip_takeover != 0),
(ctdb->tunable.no_ip_failback != 0),
(ctdb->tunable.no_ip_host_on_all_disabled != 0),
force_rebalance_nodes);
if (ipalloc_state == NULL) {
talloc_free(tmp_ctx);
return -1;

View File

@ -40,6 +40,7 @@ ipalloc_state_init(TALLOC_CTX *mem_ctx,
enum ipalloc_algorithm algorithm,
bool no_ip_takeover,
bool no_ip_failback,
bool no_ip_host_on_all_disabled,
uint32_t *force_rebalance_nodes)
{
struct ipalloc_state *ipalloc_state =
@ -63,6 +64,7 @@ ipalloc_state_init(TALLOC_CTX *mem_ctx,
ipalloc_state->algorithm = algorithm;
ipalloc_state->no_ip_takeover = no_ip_takeover;
ipalloc_state->no_ip_failback = no_ip_failback;
ipalloc_state->no_ip_host_on_all_disabled = no_ip_host_on_all_disabled;
ipalloc_state->force_rebalance_nodes = force_rebalance_nodes;
return ipalloc_state;
@ -211,33 +213,25 @@ static bool all_nodes_are_disabled(struct ctdb_node_map *nodemap)
* Set NOIPHOST ip flags for disabled nodes
*/
void ipalloc_set_node_flags(struct ipalloc_state *ipalloc_state,
struct ctdb_node_map *nodemap,
uint32_t *tval_noiphostonalldisabled)
struct ctdb_node_map *nodemap)
{
int i;
bool all_disabled = all_nodes_are_disabled(nodemap);
for (i=0;i<nodemap->num;i++) {
/* Can not host IPs on INACTIVE node */
if (nodemap->node[i].flags & NODE_FLAGS_INACTIVE) {
ipalloc_state->noiphost[i] = true;
}
}
if (all_nodes_are_disabled(nodemap)) {
/* If all nodes are disabled, can not host IPs on node
* with NoIPHostOnAllDisabled set
/* If node is disabled then it can only host IPs if
* all nodes are disabled and NoIPHostOnAllDisabled is
* unset
*/
for (i=0;i<nodemap->num;i++) {
if (tval_noiphostonalldisabled[i] != 0) {
ipalloc_state->noiphost[i] = true;
}
}
} else {
/* If some nodes are not disabled, then can not host
* IPs on DISABLED node
*/
for (i=0;i<nodemap->num;i++) {
if (nodemap->node[i].flags & NODE_FLAGS_DISABLED) {
if (nodemap->node[i].flags & NODE_FLAGS_DISABLED) {
if (!(all_disabled &&
ipalloc_state->no_ip_host_on_all_disabled == 0)) {
ipalloc_state->noiphost[i] = true;
}
}

View File

@ -51,11 +51,11 @@ struct ipalloc_state * ipalloc_state_init(TALLOC_CTX *mem_ctx,
enum ipalloc_algorithm algorithm,
bool no_ip_takeover,
bool no_ip_failback,
bool no_ip_host_on_all_disabled,
uint32_t *force_rebalance_nodes);
void ipalloc_set_node_flags(struct ipalloc_state *ipalloc_state,
struct ctdb_node_map *nodemap,
uint32_t *tval_noiphostonalldisabled);
struct ctdb_node_map *nodemap);
void ipalloc_set_public_ips(struct ipalloc_state *ipalloc_state,
struct ctdb_public_ip_list *known_ips,

View File

@ -38,6 +38,7 @@ struct ipalloc_state {
enum ipalloc_algorithm algorithm;
bool no_ip_failback;
bool no_ip_takeover;
bool no_ip_host_on_all_disabled;
uint32_t *force_rebalance_nodes;
};

View File

@ -158,7 +158,7 @@ static void ctdb_test_init(TALLOC_CTX *mem_ctx,
const char *t;
struct ctdb_node_map *nodemap;
uint32_t noiptakeover;
uint32_t *tval_noiptakeoverondisabled;
uint32_t noiphostonalldisabled;
ctdb_sock_addr sa_zero = { .ip = { 0 } };
enum ipalloc_algorithm algorithm;
@ -202,10 +202,19 @@ static void ctdb_test_init(TALLOC_CTX *mem_ctx,
noiptakeover = 0;
}
t = getenv("CTDB_SET_NoIPHostOnAllDisabled");
if (t != NULL) {
noiphostonalldisabled = (uint32_t) strtol(t, NULL, 0);
} else {
noiphostonalldisabled = 0;
}
*ipalloc_state = ipalloc_state_init(mem_ctx, nodemap->num,
algorithm,
(noiptakeover != 0),
false, NULL);
false,
(noiphostonalldisabled != 0),
NULL);
assert(*ipalloc_state != NULL);
read_ctdb_public_ip_info(mem_ctx, nodemap->num,
@ -214,13 +223,7 @@ static void ctdb_test_init(TALLOC_CTX *mem_ctx,
ipalloc_set_public_ips(*ipalloc_state, known, avail);
tval_noiptakeoverondisabled =
get_tunable_values(mem_ctx, nodemap->num,
"CTDB_SET_NoIPHostOnAllDisabled");
assert(tval_noiptakeoverondisabled != NULL);
ipalloc_set_node_flags(*ipalloc_state, nodemap,
tval_noiptakeoverondisabled);
ipalloc_set_node_flags(*ipalloc_state, nodemap);
}
/* IP layout is read from stdin. See comment for ctdb_test_init() for

View File

@ -1,33 +0,0 @@
#!/bin/sh
. "${TEST_SCRIPTS_DIR}/unit.sh"
define_test "3 nodes, all IPs assigned, 2->3 unhealthy, NoIPHostOnAllDisabled on 2"
export CTDB_TEST_LOGLEVEL=ERR
required_result <<EOF
192.168.21.254 2
192.168.21.253 2
192.168.21.252 2
192.168.20.254 2
192.168.20.253 2
192.168.20.252 2
192.168.20.251 2
192.168.20.250 2
192.168.20.249 2
EOF
export CTDB_SET_NoIPHostOnAllDisabled=1,1,0
simple_test 2,2,2 <<EOF
192.168.21.254 2
192.168.21.253 2
192.168.21.252 2
192.168.20.254 2
192.168.20.253 2
192.168.20.252 2
192.168.20.251 2
192.168.20.250 2
192.168.20.249 2
EOF

View File

@ -1,33 +0,0 @@
#!/bin/sh
. "${TEST_SCRIPTS_DIR}/unit.sh"
define_test "3 nodes, no IPs assigned, 3->2 unhealthy, NoIPHostOnAllDisabled on 2 others"
export CTDB_TEST_LOGLEVEL=ERR
required_result <<EOF
192.168.21.254 0
192.168.21.253 0
192.168.21.252 0
192.168.20.254 0
192.168.20.253 0
192.168.20.252 0
192.168.20.251 0
192.168.20.250 0
192.168.20.249 0
EOF
export CTDB_SET_NoIPHostOnAllDisabled=0,1,1
simple_test 2,2,2 <<EOF
192.168.21.254 2
192.168.21.253 2
192.168.21.252 2
192.168.20.254 2
192.168.20.253 2
192.168.20.252 2
192.168.20.251 2
192.168.20.250 2
192.168.20.249 2
EOF