[SCM] CTDB repository - branch 1.2.40 updated - ctdb-1.9.1-541-ga02fa85
Ronnie Sahlberg
sahlberg at samba.org
Mon Feb 27 14:59:33 MST 2012
The branch, 1.2.40 has been updated
via a02fa85678cc5061042ab6d448b8a3f5993f2d70 (commit)
via 710bbbbb0c7b949cc4f93f64c3a02c24fbda1f71 (commit)
from 7bbd5f6c68f0a816249eddbbc64f34bd929c43d3 (commit)
http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=1.2.40
- Log -----------------------------------------------------------------
commit a02fa85678cc5061042ab6d448b8a3f5993f2d70
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date: Tue Feb 28 06:44:08 2012 +1100
Add a tunable variable to control how long we defer after a ctdb addip until we force a rebalance and try to failback addresses onto this node
commit 710bbbbb0c7b949cc4f93f64c3a02c24fbda1f71
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date: Mon Feb 27 19:16:08 2012 +1100
When adding ips to nodes, set up a deferred rebalance for the whole node to trigger after 60 seconds in case the normal ipreallocated is not sufficient to trigger rebalance.
S1035306
-----------------------------------------------------------------------
Summary of changes:
include/ctdb_private.h | 2 +
include/ctdb_protocol.h | 5 ++++
server/ctdb_recoverd.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
server/ctdb_takeover.c | 40 +++++++++++++++++++++++++++++++++
server/ctdb_tunables.c | 3 +-
tools/ctdb.c | 45 +++++++++++++++++++++++++++++++++++--
6 files changed, 147 insertions(+), 4 deletions(-)
Changeset truncated at 500 lines:
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index 4edb647..7d0a6d8 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -122,6 +122,7 @@ struct ctdb_tunable {
uint32_t vacuum_fast_path_count;
uint32_t lcp2_public_ip_assignment;
uint32_t allow_client_db_attach;
+ uint32_t deferred_rebalance_on_node_add;
};
/*
@@ -1448,6 +1449,7 @@ bool lcp2_failback(struct ctdb_context *ctdb,
struct ctdb_public_ip_list *all_ips,
uint32_t *lcp2_imbalances,
bool *newly_healthy);
+void lcp2_forcerebalance(struct ctdb_context *ctdb, uint32_t pnn);
void ctdb_takeover_run_core(struct ctdb_context *ctdb,
struct ctdb_node_map *nodemap,
struct ctdb_public_ip_list **all_ips_p);
diff --git a/include/ctdb_protocol.h b/include/ctdb_protocol.h
index f4019ab..efcc2cf 100644
--- a/include/ctdb_protocol.h
+++ b/include/ctdb_protocol.h
@@ -130,6 +130,11 @@ struct ctdb_call_info {
*/
#define CTDB_SRVID_TAKEOVER_RUN 0xFB00000000000000LL
+/* request recovery daemon to rebalance ips for a node.
+ input is uint32_t for the node id.
+*/
+#define CTDB_SRVID_REBALANCE_NODE 0xFB01000000000000LL
+
/* A message id to ask the recovery daemon to temporarily disable the
public ip checks
*/
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index ce2aad8..bf19089 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -65,6 +65,7 @@ struct ctdb_recoverd {
struct ip_reallocate_list *reallocate_callers;
TALLOC_CTX *ip_check_disable_ctx;
struct ctdb_control_get_ifaces *ifaces;
+ TALLOC_CTX *deferred_rebalance_ctx;
};
#define CONTROL_TIMEOUT() timeval_current_ofs(ctdb->tunable.recover_timeout, 0)
@@ -1942,6 +1943,57 @@ static void reenable_ip_check(struct event_context *ev, struct timed_event *te,
}
+static void ctdb_rebalance_timeout(struct event_context *ev, struct timed_event *te,
+ struct timeval t, void *p)
+{
+ struct ctdb_recoverd *rec = talloc_get_type(p, struct ctdb_recoverd);
+ struct ctdb_context *ctdb = rec->ctdb;
+ int ret;
+
+ DEBUG(DEBUG_NOTICE,("Rebalance all nodes that have had ip assignment changes.\n"));
+
+ ret = ctdb_takeover_run(ctdb, rec->nodemap);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, (__location__ " Unable to setup public takeover addresses. ctdb_takeover_run() failed.\n"));
+ rec->need_takeover_run = true;
+ }
+
+ talloc_free(rec->deferred_rebalance_ctx);
+ rec->deferred_rebalance_ctx = NULL;
+}
+
+
+static void recd_node_rebalance_handler(struct ctdb_context *ctdb, uint64_t srvid,
+ TDB_DATA data, void *private_data)
+{
+ uint32_t pnn;
+ struct ctdb_recoverd *rec = talloc_get_type(private_data, struct ctdb_recoverd);
+
+ if (data.dsize != sizeof(uint32_t)) {
+ DEBUG(DEBUG_ERR,(__location__ " Incorrect size of node rebalance message. Was %zd but expected %zd bytes\n", data.dsize, sizeof(uint32_t)));
+ return;
+ }
+
+ if (ctdb->tunable.deferred_rebalance_on_node_add == 0) {
+ return;
+ }
+
+ pnn = *(uint32_t *)&data.dptr[0];
+
+ lcp2_forcerebalance(ctdb, pnn);
+ DEBUG(DEBUG_NOTICE,("Received message to perform node rebalancing for node %d\n", pnn));
+
+ if (rec->deferred_rebalance_ctx != NULL) {
+ talloc_free(rec->deferred_rebalance_ctx);
+ }
+ rec->deferred_rebalance_ctx = talloc_new(rec);
+ event_add_timed(ctdb->ev, rec->deferred_rebalance_ctx,
+ timeval_current_ofs(ctdb->tunable.deferred_rebalance_on_node_add, 0),
+ ctdb_rebalance_timeout, rec);
+}
+
+
+
static void recd_update_ip_handler(struct ctdb_context *ctdb, uint64_t srvid,
TDB_DATA data, void *private_data)
{
@@ -3478,6 +3530,10 @@ static void monitor_cluster(struct ctdb_context *ctdb)
/* register a message port for updating the recovery daemons node assignment for an ip */
ctdb_client_set_message_handler(ctdb, CTDB_SRVID_RECD_UPDATE_IP, recd_update_ip_handler, rec);
+ /* register a message port for forcing a rebalance of a node next
+ reallocation */
+ ctdb_client_set_message_handler(ctdb, CTDB_SRVID_REBALANCE_NODE, recd_node_rebalance_handler, rec);
+
for (;;) {
TALLOC_CTX *mem_ctx = talloc_new(ctdb);
struct timeval start;
diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c
index 9cbafaf..3dc1e46 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -1475,6 +1475,32 @@ bool basic_failback(struct ctdb_context *ctdb,
return false;
}
+struct ctdb_rebalancenodes {
+ struct ctdb_rebalancenodes *next;
+ uint32_t pnn;
+};
+static struct ctdb_rebalancenodes *force_rebalance_list = NULL;
+
+
+/* set this flag to force the node to be rebalanced even if it just didnt
+ become healthy again.
+*/
+void lcp2_forcerebalance(struct ctdb_context *ctdb, uint32_t pnn)
+{
+ struct ctdb_rebalancenodes *rebalance;
+
+ for (rebalance = force_rebalance_list; rebalance; rebalance = rebalance->next) {
+ if (rebalance->pnn == pnn) {
+ return;
+ }
+ }
+
+ rebalance = talloc(ctdb, struct ctdb_rebalancenodes);
+ rebalance->pnn = pnn;
+ rebalance->next = force_rebalance_list;
+ force_rebalance_list = rebalance;
+}
+
/* Do necessary LCP2 initialisation. Bury it in a function here so
* that we can unit test it.
* Not static, so we can easily link it into a unit test.
@@ -1507,6 +1533,20 @@ void lcp2_init(struct ctdb_context * tmp_ctx,
(*newly_healthy)[tmp_ip->pnn] = false;
}
}
+
+ /* 3rd step: if a node is forced to re-balance then
+ we allow failback onto the node */
+ while (force_rebalance_list != NULL) {
+ struct ctdb_rebalancenodes *next = force_rebalance_list->next;
+
+ if (force_rebalance_list->pnn <= nodemap->num) {
+ (*newly_healthy)[force_rebalance_list->pnn] = true;
+ }
+
+ DEBUG(DEBUG_ERR,("During ipreallocation, forced rebalance of node %d\n", force_rebalance_list->pnn));
+ talloc_free(force_rebalance_list);
+ force_rebalance_list = next;
+ }
}
/* Allocate any unassigned addresses using the LCP2 algorithm to find
diff --git a/server/ctdb_tunables.c b/server/ctdb_tunables.c
index ef86051..eb90f51 100644
--- a/server/ctdb_tunables.c
+++ b/server/ctdb_tunables.c
@@ -69,7 +69,8 @@ static const struct {
{ "AllowUnhealthyDBRead", 0, offsetof(struct ctdb_tunable, allow_unhealthy_db_read) },
{ "StatHistoryInterval", 1, offsetof(struct ctdb_tunable, stat_history_interval) },
{ "DeferredAttachTO", 120, offsetof(struct ctdb_tunable, deferred_attach_timeout) },
- { "AllowClientDBAttach", 1, offsetof(struct ctdb_tunable, allow_client_db_attach) }
+ { "AllowClientDBAttach", 1, offsetof(struct ctdb_tunable, allow_client_db_attach) },
+ { "DeferredRebalanceOnNodeAdd", 300, offsetof(struct ctdb_tunable, deferred_rebalance_on_node_add) }
};
/*
diff --git a/tools/ctdb.c b/tools/ctdb.c
index fa3cf1b..c3f8a7a 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -1325,6 +1325,44 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
return 0;
}
+static int rebalance_node(struct ctdb_context *ctdb, uint32_t pnn)
+{
+ uint32_t recmaster;
+ TDB_DATA data;
+
+ if (ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), pnn, &recmaster) != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", pnn));
+ return -1;
+ }
+
+ data.dptr = (uint8_t *)&pnn;
+ data.dsize = sizeof(uint32_t);
+ if (ctdb_client_send_message(ctdb, recmaster, CTDB_SRVID_REBALANCE_NODE, data) != 0) {
+ DEBUG(DEBUG_ERR,("Failed to send message to force node reallocation\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ rebalance a node by setting it to allow failback and triggering a
+ takeover run
+ */
+static int control_rebalancenode(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ switch (options.pnn) {
+ case CTDB_BROADCAST_ALL:
+ case CTDB_CURRENT_NODE:
+ DEBUG(DEBUG_ERR,("You must specify a node number with -n <pnn> for the node to rebalance\n"));
+ return -1;
+ }
+
+ return rebalance_node(ctdb, options.pnn);
+}
+
+
static int rebalance_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
{
struct ctdb_public_ip ip;
@@ -1763,12 +1801,12 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
return ret;
}
- if (rebalance_ip(ctdb, &addr) != 0) {
- DEBUG(DEBUG_ERR,("Error when trying to reassign ip\n"));
+ if (rebalance_node(ctdb, options.pnn) != 0) {
+ DEBUG(DEBUG_ERR,("Error when trying to rebalance node\n"));
return -1;
}
- talloc_free(tmp_ctx);
+ talloc_free(tmp_ctx);
return 0;
}
@@ -5108,6 +5146,7 @@ static const struct {
{ "readkey", control_readkey, true, false, "read the content off a database key", "<tdb-file> <key>" },
{ "writekey", control_writekey, true, false, "write to a database key", "<tdb-file> <key> <value>" },
{ "checktcpport", control_chktcpport, false, true, "check if a service is bound to a specific tcp port or not", "<port>" },
+ { "rebalancenode", control_rebalancenode, false, false, "release a node by allowing it to takeover ips", "<pnn>"},
};
/*
--
CTDB repository
More information about the samba-cvs
mailing list