From: Ronnie Sahlberg Date: Wed, 28 Apr 2010 05:43:11 +0000 (+1000) Subject: The recent change to the recovery daemon to keep track of and X-Git-Tag: ctdb-1.9.1~81 X-Git-Url: http://git.samba.org/?p=sahlberg%2Fctdb.git;a=commitdiff_plain;h=e7069082e5f0380dcddee247db8754218ce18cab The recent change to the recovery daemon to keep track of and verify that all nodes agree on the most recent ip address assignments broke "ctdb moveip ..." since that call would never trigger a full takeover run and thus would immediately trigger an inconsistency. Add a new message to the recovery daemon where we can tell the recovery daemon to update its assignments. BZ62782 --- diff --git a/include/ctdb.h b/include/ctdb.h index 94198aac..540ca98a 100644 --- a/include/ctdb.h +++ b/include/ctdb.h @@ -75,6 +75,12 @@ struct ctdb_call_info { */ #define CTDB_SRVID_SET_NODE_FLAGS 0xF400000000000000LL +/* + a message ID to ask the recovery daemon to update the expected node + assignment for a public ip + */ +#define CTDB_SRVID_RECD_UPDATE_IP 0xF500000000000000LL + /* a message to tell the recovery daemon to fetch a set of records */ diff --git a/include/ctdb_private.h b/include/ctdb_private.h index 888b626e..d4c343b4 100644 --- a/include/ctdb_private.h +++ b/include/ctdb_private.h @@ -1639,5 +1639,7 @@ void ctdb_fault_setup(void); int verify_remote_ip_allocation(struct ctdb_context *ctdb, struct ctdb_all_public_ips *ips); +int update_ip_assignment_tree(struct ctdb_context *ctdb, + struct ctdb_public_ip *ip); #endif diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c index 5f34711f..f04d6091 100644 --- a/server/ctdb_recoverd.c +++ b/server/ctdb_recoverd.c @@ -1891,6 +1891,29 @@ static void reenable_ip_check(struct event_context *ev, struct timed_event *te, rec->ip_check_disable_ctx = NULL; } + +static void recd_update_ip_handler(struct ctdb_context *ctdb, uint64_t srvid, + TDB_DATA data, void *private_data) +{ + struct ctdb_recoverd *rec = talloc_get_type(private_data, struct ctdb_recoverd); + struct ctdb_public_ip *ip; + + if (rec->recmaster != rec->ctdb->pnn) { + DEBUG(DEBUG_INFO,("Not recmaster, ignore update ip message\n")); + return; + } + + if (data.dsize != sizeof(struct ctdb_public_ip)) { + DEBUG(DEBUG_ERR,(__location__ " Incorrect size of recd update ip message. Was %zd but expected %zd bytes\n", data.dsize, sizeof(struct ctdb_public_ip))); + return; + } + + ip = (struct ctdb_public_ip *)data.dptr; + + update_ip_assignment_tree(rec->ctdb, ip); +} + + static void disable_ip_check_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *private_data) { @@ -2862,6 +2885,9 @@ static void monitor_cluster(struct ctdb_context *ctdb) /* register a message port for disabling the ip check for a short while */ ctdb_set_message_handler(ctdb, CTDB_SRVID_DISABLE_IP_CHECK, disable_ip_check_handler, rec); + /* register a message port for updating the recovery daemons node assignment for an ip */ + ctdb_set_message_handler(ctdb, CTDB_SRVID_RECD_UPDATE_IP, recd_update_ip_handler, rec); + again: if (mem_ctx) { talloc_free(mem_ctx); diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c index 13e00392..b18c0300 100644 --- a/server/ctdb_takeover.c +++ b/server/ctdb_takeover.c @@ -2849,3 +2849,24 @@ int verify_remote_ip_allocation(struct ctdb_context *ctdb, struct ctdb_all_publi return 0; } + +int update_ip_assignment_tree(struct ctdb_context *ctdb, struct ctdb_public_ip *ip) +{ + struct ctdb_public_ip_list *tmp_ip; + + if (ctdb->ip_tree == NULL) { + DEBUG(DEBUG_ERR,("No ctdb->ip_tree yet. Failed to update ip assignment\n")); + return -1; + } + + tmp_ip = trbt_lookuparray32(ctdb->ip_tree, IP_KEYLEN, ip_key(&ip->addr)); + if (tmp_ip == NULL) { + DEBUG(DEBUG_ERR,(__location__ " Could not find record for address %s, update ip\n", ctdb_addr_to_str(&ip->addr))); + return -1; + } + + DEBUG(DEBUG_NOTICE,("Updated ip assignment tree for ip : %s from node %u to node %u\n", ctdb_addr_to_str(&ip->addr), tmp_ip->pnn, ip->pnn)); + tmp_ip->pnn = ip->pnn; + + return 0; +} diff --git a/tools/ctdb.c b/tools/ctdb.c index 09c849cd..51378462 100644 --- a/tools/ctdb.c +++ b/tools/ctdb.c @@ -1072,6 +1072,15 @@ static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn return -1; } + /* update the recovery daemon so it now knows to expect the new + node assignment for this ip. + */ + ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_RECD_UPDATE_IP, data); + if (ret != 0) { + DEBUG(DEBUG_ERR,("Failed to send message to update the ip on the recovery master.\n")); + return -1; + } + talloc_free(tmp_ctx); return 0; }