The recent change to the recovery daemon to keep track of and
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 28 Apr 2010 05:43:11 +0000 (15:43 +1000)
committerMichael Adam <obnox@samba.org>
Mon, 26 Aug 2013 11:34:21 +0000 (13:34 +0200)
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
(cherry picked from commit e7069082e5f0380dcddee247db8754218ce18cab)

include/ctdb.h
include/ctdb_private.h
server/ctdb_recoverd.c
server/ctdb_takeover.c
tools/ctdb.c

index 7f0ff2fc4c6012cdaf803fb88c425cfb4e771241..ff798c8e72e45861e6f88f5b0f4fe92112146901 100644 (file)
@@ -76,6 +76,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
  */
index beaf125f2eb6c86e0309eda0775b1c1e2a290197..e381c5b9fba3f87c8b5eac93c3e6433fdb75aa6f 100644 (file)
@@ -1683,6 +1683,8 @@ 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);
 
 /**
  * structure to pass to a schedule_for_deletion_control
index 7dcc29a6c6cca195b1c55c2259169e2dd0c0f023..f91bcd0a1a2d37e5204807c22885509ea47b1015 100644 (file)
@@ -1899,6 +1899,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)
 {
@@ -2870,6 +2893,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);
index c06c595bfaabd4bb54d9685d0438031464f259c7..62f54d88168f7ad4ca3a70f5a12ca998863685b7 100644 (file)
@@ -2854,3 +2854,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;
+}
index 28fa676c42f104457633eb338eb23d940257c3c0..ada9b47e5e1675c235b30bdcf3237429f3c0870b 100644 (file)
@@ -1092,6 +1092,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;
 }