add a new message to ask the recovery daemon to temporarily disable checking ip addre...
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Tue, 6 Oct 2009 01:11:32 +0000 (12:11 +1100)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Tue, 6 Oct 2009 01:11:32 +0000 (12:11 +1100)
This is useful when we are moving addresses using moveip in the cluster since otherwise if we collide with the recovery daemons own check we could cause a recovery

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

index bf689dc8abc2df22f1677da8ae7c1b9829e3fdb3..23d73fbf1da55a5a2582ad7104eb888545e08f42 100644 (file)
@@ -101,7 +101,10 @@ struct ctdb_call_info {
  */
 #define CTDB_SRVID_TAKEOVER_RUN 0xFB00000000000000LL
 
-
+/* A message id to ask the recovery daemon to temporarily disable the
+   public ip checks
+*/
+#define CTDB_SRVID_DISABLE_IP_CHECK  0xFC00000000000000LL
 
 /* used on the domain socket, send a pdu to the local daemon */
 #define CTDB_CURRENT_NODE     0xF0000001
index 7e81e20e002fcd57469233bc6adc76dcb70725f7..2be53f84daef919065518d6e3c572b5d1fb941df 100644 (file)
@@ -63,6 +63,7 @@ struct ctdb_recoverd {
        struct vacuum_info *vacuum_info;
        TALLOC_CTX *ip_reallocate_ctx;
        struct ip_reallocate_list *reallocate_callers;
+       TALLOC_CTX *ip_check_disable_ctx;
 };
 
 #define CONTROL_TIMEOUT() timeval_current_ofs(ctdb->tunable.recover_timeout, 0)
@@ -1685,6 +1686,46 @@ static void reload_nodes_handler(struct ctdb_context *ctdb, uint64_t srvid,
        reload_nodes_file(rec->ctdb);
 }
 
+
+static void reenable_ip_check(struct event_context *ev, struct timed_event *te, 
+                             struct timeval yt, void *p)
+{
+       struct ctdb_recoverd *rec = talloc_get_type(p, struct ctdb_recoverd);
+
+       talloc_free(rec->ip_check_disable_ctx);
+       rec->ip_check_disable_ctx = NULL;
+}
+
+static void disable_ip_check_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);
+       uint32_t timeout;
+
+       if (rec->ip_check_disable_ctx != NULL) {
+               talloc_free(rec->ip_check_disable_ctx);
+               rec->ip_check_disable_ctx = NULL;
+       }
+
+       if (data.dsize != sizeof(uint32_t)) {
+               DEBUG(DEBUG_ERR,(__location__ " Wrong size for data :%lu expexting %lu\n", data.dsize, sizeof(uint32_t)));
+               return;
+       }
+       if (data.dptr == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " No data recaived\n"));
+               return;
+       }
+
+       timeout = *((uint32_t *)data.dptr);
+       DEBUG(DEBUG_NOTICE,("Disabling ip check for %u seconds\n", timeout));
+
+       rec->ip_check_disable_ctx = talloc_new(rec);
+       CTDB_NO_MEMORY_VOID(ctdb, rec->ip_check_disable_ctx);
+
+       event_add_timed(ctdb->ev, rec->ip_check_disable_ctx, timeval_current_ofs(timeout, 0), reenable_ip_check, rec);
+}
+
+
 /*
   handler for ip reallocate, just add it to the list of callers and 
   handle this later in the monitor_cluster loop so we do not recurse
@@ -2531,6 +2572,9 @@ static void monitor_cluster(struct ctdb_context *ctdb)
        /* register a message port for performing a takeover run */
        ctdb_set_message_handler(ctdb, CTDB_SRVID_TAKEOVER_RUN, ip_reallocate_handler, rec);
 
+       /* 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);
+
 again:
        if (mem_ctx) {
                talloc_free(mem_ctx);
@@ -2762,9 +2806,11 @@ again:
         * have addresses we shouldnt have.
         */ 
        if (ctdb->do_checkpublicip) {
-               if (verify_ip_allocation(ctdb, pnn) != 0) {
-                       DEBUG(DEBUG_ERR, (__location__ " Public IPs were inconsistent.\n"));
-                       goto again;
+               if (rec->ip_check_disable_ctx == NULL) {
+                       if (verify_ip_allocation(ctdb, pnn) != 0) {
+                               DEBUG(DEBUG_ERR, (__location__ " Public IPs were inconsistent.\n"));
+                               goto again;
+                       }
                }
        }
 
index dfac74d0d4c3bdb534fee426e5fa15bc7d696a58..6ae42953ff9cda4d186036ed9a6f72dd4878601b 100644 (file)
@@ -862,10 +862,22 @@ static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn
        struct ctdb_public_ip ip;
        int i, ret;
        uint32_t *nodes;
+       uint32_t disable_time;
        TDB_DATA data;
        struct ctdb_node_map *nodemap=NULL;
        TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 
+       disable_time = 30;
+       data.dptr  = (uint8_t*)&disable_time;
+       data.dsize = sizeof(disable_time);
+       ret = ctdb_send_message(ctdb, CTDB_BROADCAST_CONNECTED, CTDB_SRVID_DISABLE_IP_CHECK, data);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,("Failed to send message to disable ipcheck\n"));
+               return -1;
+       }
+
+
+
        /* read the public ip list from the node */
        ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), pnn, ctdb, &ips);
        if (ret != 0) {