ctdb-daemon: When releasing an IP, update PNN in callback
authorMartin Schwenke <martin@meltin.net>
Fri, 19 Aug 2016 06:38:50 +0000 (16:38 +1000)
committerAmitay Isaacs <amitay@samba.org>
Sun, 21 Aug 2016 20:45:32 +0000 (22:45 +0200)
When an error occurs so an IP address is not released then the PNN in
the VNN is currently incorrectly updated.

Instead, update the PNN in the callback when the release is
successful.  Also, explicitly update the PNN on redundant releases.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12158

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Autobuild-User(master): Amitay Isaacs <amitay@samba.org>
Autobuild-Date(master): Sun Aug 21 22:45:33 CEST 2016 on sn-devel-144

ctdb/server/ctdb_takeover.c

index 1883c30181573cfd15228d54d135eb3a81a59df1..ff096ce1a3d98cc4e2dada846ae90ba7351931c9 100644 (file)
@@ -870,6 +870,7 @@ struct release_ip_callback_state {
        struct ctdb_req_control_old *c;
        ctdb_sock_addr *addr;
        struct ctdb_vnn *vnn;
+       uint32_t target_pnn;
 };
 
 /*
@@ -897,6 +898,7 @@ static void release_ip_callback(struct ctdb_context *ctdb, int status,
                }
        }
 
+       state->vnn->pnn = state->target_pnn;
        state->vnn = release_ip_post(ctdb, state->vnn, state->addr);
 
        /* the control succeeded */
@@ -933,16 +935,20 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
                        ctdb_addr_to_str(&pip->addr)));
                return 0;
        }
-       vnn->pnn = pip->pnn;
 
        /* stop any previous arps */
        talloc_free(vnn->takeover_ctx);
        vnn->takeover_ctx = NULL;
 
-       /* Some ctdb tool commands (e.g. moveip) send
-        * lazy multicast to drop an IP from any node that isn't the
-        * intended new node.  The following causes makes ctdbd ignore
-        * a release for any address it doesn't host.
+       /* RELEASE_IP controls are sent to all nodes that should not
+        * be hosting a particular IP.  This serves 2 purposes.  The
+        * first is to help resolve any inconsistencies.  If a node
+        * does unexpectly host an IP then it will be released.  The
+        * 2nd is to use a "redundant release" to tell non-takeover
+        * nodes where an IP is moving to.  This is how "ctdb ip" can
+        * report the (likely) location of an IP by only asking the
+        * local node.  Redundant releases need to update the PNN but
+        * are otherwise ignored.
         */
        if (ctdb->tunable.disable_ip_failover == 0 && ctdb->do_checkpublicip) {
                if (!ctdb_sys_have_ip(&pip->addr)) {
@@ -950,6 +956,7 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
                                ctdb_addr_to_str(&pip->addr),
                                vnn->public_netmask_bits,
                                ctdb_vnn_iface_string(vnn)));
+                       vnn->pnn = pip->pnn;
                        ctdb_vnn_unassign_iface(ctdb, vnn);
                        return 0;
                }
@@ -958,6 +965,7 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
                        DEBUG(DEBUG_DEBUG,("Redundant release of IP %s/%u (ip not held)\n",
                                           ctdb_addr_to_str(&pip->addr),
                                           vnn->public_netmask_bits));
+                       vnn->pnn = pip->pnn;
                        return 0;
                }
        }
@@ -1001,6 +1009,7 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
                return -1;
        }
        *state->addr = pip->addr;
+       state->target_pnn = pip->pnn;
        state->vnn   = vnn;
 
        vnn->update_in_flight = true;