<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>
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,
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);
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;
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
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
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...
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
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")
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