ctdb-daemon: Deletion of IPs is deferred until the next takeover run
authorMartin Schwenke <martin@meltin.net>
Wed, 22 Jan 2014 06:12:09 +0000 (17:12 +1100)
committerStefan Metzmacher <metze@samba.org>
Thu, 28 Jul 2016 03:00:17 +0000 (05:00 +0200)
This drastically simplifies the code.  "ctdb reloadips" behaves the
same, since it causes a takeover run immediately after IPs are
deleted.  "ctdb delip" now needs to be followed with an explicit "ctdb
ipreallocate".

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/doc/ctdb.1.xml
ctdb/include/ctdb_private.h
ctdb/server/ctdb_control.c
ctdb/server/ctdb_takeover.c
ctdb/tests/complex/11_ctdb_delip_removes_ip.sh
ctdb/tests/simple/16_ctdb_config_add_ip.sh
ctdb/tests/simple/17_ctdb_config_delete_ip.sh
ctdb/tests/simple/20_delip_iface_gc.sh
ctdb/tests/simple/60_recoverd_missing_ip.sh

index 8a5278eb93817ec64b9bdc52a380dc0fb48bfc3e..7878c4c2b1504926356eb06abf04d9c029e7a0bd 100644 (file)
@@ -1044,12 +1044,19 @@ DB Statistics: locking.tdb
     <refsect2>
       <title>delip <parameter>IPADDR</parameter></title>
       <para>
-       This command is used to remove a public ip from a node during runtime.
-       If this public ip is currently hosted by the node it being removed from, the ip will first be failed over to another node, if possible, before it is removed.
-      </para>
-      <para>
-       Note that this only updates the runtime instance of ctdb. Any changes will be lost next time ctdb is restarted and the public addresses file is re-read.
-       If you want this change to be permanent you must also update the public addresses file manually.
+       This command flags IPADDR for deletion from a node at runtime.
+       It should be followed by a <command>ctdb
+       ipreallocate</command>.  If IPADDR is currently hosted by the
+       node it is being removed from, this ensures that the IP will
+       first be failed over to another node, if possible, and that it
+       is then actually removed.
+      </para>
+      <para>
+       Note that this only updates the runtime instance of CTDB.  Any
+       changes will be lost next time CTDB is restarted and the
+       public addresses file is re-read.  If you want this change to
+       be permanent you must also update the public addresses file
+       manually.
       </para>
     </refsect2>
 
index 40dea09a2b469b5901f22daed112b77fe2cef468..5d7275e5bb8da9d3c0acfcb46e14d88532ab51a8 100644 (file)
@@ -953,8 +953,7 @@ int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb,
 int32_t ctdb_control_add_public_address(struct ctdb_context *ctdb,
                                        TDB_DATA indata);
 int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb,
-                                       struct ctdb_req_control_old *c,
-                                       TDB_DATA recdata, bool *async_reply);
+                                       TDB_DATA recdata);
 
 int32_t ctdb_control_reload_public_ips(struct ctdb_context *ctdb,
                                       struct ctdb_req_control_old *c,
index 5b3e7c2190b7fa456b879c037aa7844bdc9894bb..92022cabfc97784f0c0569415d21958a98aa2f13 100644 (file)
@@ -467,8 +467,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                return ctdb_control_add_public_address(ctdb, indata);
 
        case CTDB_CONTROL_DEL_PUBLIC_IP:
-               return ctdb_control_del_public_address(ctdb, c, indata,
-                                                      async_reply);
+               return ctdb_control_del_public_address(ctdb, indata);
 
        case CTDB_CONTROL_GET_CAPABILITIES:
                return ctdb_control_get_capabilities(ctdb, outdata);
index 84dcd98ccbf1d4e1b71f95b9f2b37b0a889558c6..6d182ded7be1259ad444f57ca7ea643005c2690a 100644 (file)
@@ -2718,29 +2718,7 @@ int32_t ctdb_control_add_public_address(struct ctdb_context *ctdb, TDB_DATA inda
        return 0;
 }
 
-struct delete_ip_callback_state {
-       struct ctdb_req_control_old *c;
-};
-
-/*
-  called when releaseip event finishes for del_public_address
- */
-static void delete_ip_callback(struct ctdb_context *ctdb,
-                              int32_t status, TDB_DATA data,
-                              const char *errormsg,
-                              void *private_data)
-{
-       struct delete_ip_callback_state *state =
-               talloc_get_type(private_data, struct delete_ip_callback_state);
-
-       /* If release failed then fail. */
-       ctdb_request_control_reply(ctdb, state->c, NULL, status, errormsg);
-       talloc_free(private_data);
-}
-
-int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb,
-                                       struct ctdb_req_control_old *c,
-                                       TDB_DATA indata, bool *async_reply)
+int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
 {
        struct ctdb_addr_info_old *pub = (struct ctdb_addr_info_old *)indata.dptr;
        struct ctdb_vnn *vnn;
@@ -2767,49 +2745,13 @@ int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb,
        for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
                if (ctdb_same_ip(&vnn->public_address, &pub->addr)) {
                        if (vnn->pnn == ctdb->pnn) {
-                               struct delete_ip_callback_state *state;
-                               struct ctdb_public_ip *ip;
-                               TDB_DATA data;
-                               int ret;
-
+                               /* This IP is currently being hosted.
+                                * Defer the deletion until the next
+                                * takeover run. "ctdb reloadips" will
+                                * always cause a takeover run.  "ctdb
+                                * delip" will now need an explicit
+                                * "ctdb ipreallocated" afterwards. */
                                vnn->delete_pending = true;
-
-                               state = talloc(ctdb,
-                                              struct delete_ip_callback_state);
-                               CTDB_NO_MEMORY(ctdb, state);
-                               state->c = c;
-
-                               ip = talloc(state, struct ctdb_public_ip);
-                               if (ip == NULL) {
-                                       DEBUG(DEBUG_ERR,
-                                             (__location__ " Out of memory\n"));
-                                       talloc_free(state);
-                                       return -1;
-                               }
-                               ip->pnn = -1;
-                               ip->addr = pub->addr;
-
-                               data.dsize = sizeof(struct ctdb_public_ip);
-                               data.dptr = (unsigned char *)ip;
-
-                               ret = ctdb_daemon_send_control(ctdb,
-                                                              ctdb_get_pnn(ctdb),
-                                                              0,
-                                                              CTDB_CONTROL_RELEASE_IP,
-                                                              0, 0,
-                                                              data,
-                                                              delete_ip_callback,
-                                                              state);
-                               if (ret == -1) {
-                                       DEBUG(DEBUG_ERR,
-                                             (__location__ "Unable to send "
-                                              "CTDB_CONTROL_RELEASE_IP\n"));
-                                       talloc_free(state);
-                                       return -1;
-                               }
-
-                               state->c = talloc_steal(state, c);
-                               *async_reply = true;
                        } else {
                                /* This IP is not hosted on the
                                 * current node so just delete it
index d023e98da8f26c294f5d8d2d3273eaeb0b171943..d6a3b3c04ff9617cc9859389defb1065caf00905 100755 (executable)
@@ -30,6 +30,7 @@ try_command_on_node $test_node "ip addr show dev $iface | grep -E 'inet6?[[:spac
 
 echo "Attempting to remove ${test_ip} from node ${test_node}."
 try_command_on_node $test_node $CTDB delip $test_ip
+try_command_on_node $test_node $CTDB ipreallocate
 wait_until_ips_are_on_node '!' $test_node $test_ip
 
 timeout=60
index 55527ad4cb1f00c6c448871c63a964fa453455a6..d33ec040577897f3b5ea95d2ca639284d7df22f6 100755 (executable)
@@ -26,6 +26,7 @@ get_test_ip_mask_and_iface
 
 echo "Deleting IP $test_ip from all nodes"
 delete_ip_from_all_nodes $test_ip
+try_command_on_node -v $test_node $CTDB ipreallocate
 wait_until_ips_are_on_node '!' $test_node $test_ip
 
 # Debugging...
index 80d2699429b347863cec3b1b134c7810cd14a2d0..cac22153213a394afdcb7bc54b2e76a1e546fae6 100755 (executable)
@@ -25,4 +25,5 @@ select_test_node_and_ips
 
 echo "Deleting IP ${test_ip} from node ${test_node}"
 try_command_on_node $test_node $CTDB delip $test_ip
+try_command_on_node $test_node $CTDB ipreallocate
 wait_until_ips_are_on_node '!' $test_node $test_ip
index 23d1d6babfde81a50711cfff1b843c89c9b06719..8ad001fb460a3447edefbcb3215e3abccb4ff030 100755 (executable)
@@ -48,6 +48,7 @@ for i in $ifaces ; do
        echo "  $ip"
        try_command_on_node $test_node "$CTDB delip $ip"
     done
+    try_command_on_node $test_node "$CTDB ipreallocate"
 
     try_command_on_node $test_node "$CTDB ifaces -X"
     info=$(awk -F'|' -v iface="$i" '$2 == iface { print $0 }' <<<"$out")
index 36271d19d9eb7bfb812a06d36069e2090838e009..cf68b19a515a32c915f75b41cd7269c23a9a2644 100755 (executable)
@@ -31,6 +31,7 @@ get_test_ip_mask_and_iface
 
 echo "Deleting IP $test_ip from all nodes"
 delete_ip_from_all_nodes $test_ip
+try_command_on_node -v $test_node $CTDB ipreallocate
 wait_until_ips_are_on_node ! $test_node $test_ip
 
 try_command_on_node -v all $CTDB ip