4 Copyright (C) Ronnie Sahlberg 2007
5 Copyright (C) Andrew Tridgell 2007
6 Copyright (C) Martin Schwenke 2011
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "system/network.h"
23 #include "system/filesys.h"
24 #include "system/time.h"
25 #include "system/wait.h"
30 #include "lib/util/dlinklist.h"
31 #include "lib/util/debug.h"
32 #include "lib/util/samba_util.h"
33 #include "lib/util/sys_rw.h"
34 #include "lib/util/util_process.h"
36 #include "protocol/protocol_util.h"
38 #include "ctdb_private.h"
39 #include "ctdb_client.h"
41 #include "common/reqid.h"
42 #include "common/system.h"
43 #include "common/system_socket.h"
44 #include "common/common.h"
45 #include "common/logging.h"
47 #include "server/ctdb_config.h"
49 #include "server/ipalloc.h"
51 #define TAKEOVER_TIMEOUT() timeval_current_ofs(ctdb->tunable.takeover_timeout,0)
53 #define CTDB_ARP_INTERVAL 1
54 #define CTDB_ARP_REPEAT 3
56 struct ctdb_interface {
57 struct ctdb_interface *prev, *next;
63 struct vnn_interface {
64 struct vnn_interface *prev, *next;
65 struct ctdb_interface *iface;
68 /* state associated with a public ip address */
70 struct ctdb_vnn *prev, *next;
72 struct ctdb_interface *iface;
73 struct vnn_interface *ifaces;
74 ctdb_sock_addr public_address;
75 uint8_t public_netmask_bits;
78 * The node number that is serving this public address - set
79 * to CTDB_UNKNOWN_PNN if node is serving it
83 /* List of clients to tickle for this public address */
84 struct ctdb_tcp_array *tcp_array;
86 /* whether we need to update the other nodes with changes to our list
87 of connected clients */
88 bool tcp_update_needed;
90 /* a context to hang sending gratious arp events off */
91 TALLOC_CTX *takeover_ctx;
93 /* Set to true any time an update to this VNN is in flight.
94 This helps to avoid races. */
95 bool update_in_flight;
97 /* If CTDB_CONTROL_DEL_PUBLIC_IP is received for this IP
98 * address then this flag is set. It will be deleted in the
99 * release IP callback. */
103 static const char *iface_string(const struct ctdb_interface *iface)
105 return (iface != NULL ? iface->name : "__none__");
108 static const char *ctdb_vnn_iface_string(const struct ctdb_vnn *vnn)
110 return iface_string(vnn->iface);
113 static struct ctdb_interface *ctdb_find_iface(struct ctdb_context *ctdb,
116 static struct ctdb_interface *
117 ctdb_add_local_iface(struct ctdb_context *ctdb, const char *iface)
119 struct ctdb_interface *i;
121 if (strlen(iface) > CTDB_IFACE_SIZE) {
122 DEBUG(DEBUG_ERR, ("Interface name too long \"%s\"\n", iface));
126 /* Verify that we don't have an entry for this ip yet */
127 i = ctdb_find_iface(ctdb, iface);
132 /* create a new structure for this interface */
133 i = talloc_zero(ctdb, struct ctdb_interface);
135 DEBUG(DEBUG_ERR, (__location__ " out of memory\n"));
138 i->name = talloc_strdup(i, iface);
139 if (i->name == NULL) {
140 DEBUG(DEBUG_ERR, (__location__ " out of memory\n"));
147 DLIST_ADD(ctdb->ifaces, i);
152 static bool vnn_has_interface(struct ctdb_vnn *vnn,
153 const struct ctdb_interface *iface)
155 struct vnn_interface *i;
157 for (i = vnn->ifaces; i != NULL; i = i->next) {
158 if (iface == i->iface) {
166 /* If any interfaces now have no possible IPs then delete them. This
167 * implementation is naive (i.e. simple) rather than clever
168 * (i.e. complex). Given that this is run on delip and that operation
169 * is rare, this doesn't need to be efficient - it needs to be
170 * foolproof. One alternative is reference counting, where the logic
171 * is distributed and can, therefore, be broken in multiple places.
172 * Another alternative is to build a red-black tree of interfaces that
173 * can have addresses (by walking ctdb->vnn once) and then walking
174 * ctdb->ifaces once and deleting those not in the tree. Let's go to
175 * one of those if the naive implementation causes problems... :-)
177 static void ctdb_remove_orphaned_ifaces(struct ctdb_context *ctdb,
178 struct ctdb_vnn *vnn)
180 struct ctdb_interface *i, *next;
182 /* For each interface, check if there's an IP using it. */
183 for (i = ctdb->ifaces; i != NULL; i = next) {
188 /* Only consider interfaces named in the given VNN. */
189 if (!vnn_has_interface(vnn, i)) {
193 /* Search for a vnn with this interface. */
195 for (tv=ctdb->vnn; tv; tv=tv->next) {
196 if (vnn_has_interface(tv, i)) {
203 /* None of the VNNs are using this interface. */
204 DLIST_REMOVE(ctdb->ifaces, i);
211 static struct ctdb_interface *ctdb_find_iface(struct ctdb_context *ctdb,
214 struct ctdb_interface *i;
216 for (i=ctdb->ifaces;i;i=i->next) {
217 if (strcmp(i->name, iface) == 0) {
225 static struct ctdb_interface *ctdb_vnn_best_iface(struct ctdb_context *ctdb,
226 struct ctdb_vnn *vnn)
228 struct vnn_interface *i;
229 struct ctdb_interface *cur = NULL;
230 struct ctdb_interface *best = NULL;
232 for (i = vnn->ifaces; i != NULL; i = i->next) {
245 if (cur->references < best->references) {
254 static int32_t ctdb_vnn_assign_iface(struct ctdb_context *ctdb,
255 struct ctdb_vnn *vnn)
257 struct ctdb_interface *best = NULL;
260 DEBUG(DEBUG_INFO, (__location__ " public address '%s' "
261 "still assigned to iface '%s'\n",
262 ctdb_addr_to_str(&vnn->public_address),
263 ctdb_vnn_iface_string(vnn)));
267 best = ctdb_vnn_best_iface(ctdb, vnn);
269 DEBUG(DEBUG_ERR, (__location__ " public address '%s' "
270 "cannot assign to iface any iface\n",
271 ctdb_addr_to_str(&vnn->public_address)));
277 vnn->pnn = ctdb->pnn;
279 DEBUG(DEBUG_INFO, (__location__ " public address '%s' "
280 "now assigned to iface '%s' refs[%d]\n",
281 ctdb_addr_to_str(&vnn->public_address),
282 ctdb_vnn_iface_string(vnn),
287 static void ctdb_vnn_unassign_iface(struct ctdb_context *ctdb,
288 struct ctdb_vnn *vnn)
290 DEBUG(DEBUG_INFO, (__location__ " public address '%s' "
291 "now unassigned (old iface '%s' refs[%d])\n",
292 ctdb_addr_to_str(&vnn->public_address),
293 ctdb_vnn_iface_string(vnn),
294 vnn->iface?vnn->iface->references:0));
296 vnn->iface->references--;
299 if (vnn->pnn == ctdb->pnn) {
300 vnn->pnn = CTDB_UNKNOWN_PNN;
304 static bool ctdb_vnn_available(struct ctdb_context *ctdb,
305 struct ctdb_vnn *vnn)
308 struct vnn_interface *i;
310 /* Nodes that are not RUNNING can not host IPs */
311 if (ctdb->runstate != CTDB_RUNSTATE_RUNNING) {
315 flags = ctdb->nodes[ctdb->pnn]->flags;
316 if ((flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED)) != 0) {
320 if (vnn->delete_pending) {
324 if (vnn->iface && vnn->iface->link_up) {
328 for (i = vnn->ifaces; i != NULL; i = i->next) {
329 if (i->iface->link_up) {
337 struct ctdb_takeover_arp {
338 struct ctdb_context *ctdb;
341 struct ctdb_tcp_array *tcparray;
342 struct ctdb_vnn *vnn;
347 lists of tcp endpoints
349 struct ctdb_tcp_list {
350 struct ctdb_tcp_list *prev, *next;
351 struct ctdb_client *client;
352 struct ctdb_connection connection;
356 send a gratuitous arp
358 static void ctdb_control_send_arp(struct tevent_context *ev,
359 struct tevent_timer *te,
360 struct timeval t, void *private_data)
362 struct ctdb_takeover_arp *arp = talloc_get_type(private_data,
363 struct ctdb_takeover_arp);
365 struct ctdb_tcp_array *tcparray;
368 /* IP address might have been released between sends */
369 if (arp->vnn->iface == NULL) {
370 DBG_INFO("Cancelling ARP send for released IP %s\n",
371 ctdb_addr_to_str(&arp->vnn->public_address));
376 iface = ctdb_vnn_iface_string(arp->vnn);
377 ret = ctdb_sys_send_arp(&arp->addr, iface);
379 DBG_ERR("Failed to send ARP on interface %s: %s\n",
380 iface, strerror(ret));
383 tcparray = arp->tcparray;
387 for (i=0;i<tcparray->num;i++) {
388 struct ctdb_connection *tcon;
391 tcon = &tcparray->connections[i];
392 ret = ctdb_connection_to_buf(buf,
398 strlcpy(buf, "UNKNOWN", sizeof(buf));
400 D_INFO("Send TCP tickle ACK: %s\n", buf);
401 ret = ctdb_sys_send_tcp(
406 DBG_ERR("Failed to send TCP tickle ACK: %s\n",
414 if (arp->count == CTDB_ARP_REPEAT) {
419 tevent_add_timer(arp->ctdb->ev, arp->vnn->takeover_ctx,
420 timeval_current_ofs(CTDB_ARP_INTERVAL, 100000),
421 ctdb_control_send_arp, arp);
424 static int32_t ctdb_announce_vnn_iface(struct ctdb_context *ctdb,
425 struct ctdb_vnn *vnn)
427 struct ctdb_takeover_arp *arp;
428 struct ctdb_tcp_array *tcparray;
430 if (!vnn->takeover_ctx) {
431 vnn->takeover_ctx = talloc_new(vnn);
432 if (!vnn->takeover_ctx) {
437 arp = talloc_zero(vnn->takeover_ctx, struct ctdb_takeover_arp);
443 arp->addr = vnn->public_address;
446 tcparray = vnn->tcp_array;
448 /* add all of the known tcp connections for this IP to the
449 list of tcp connections to send tickle acks for */
450 arp->tcparray = talloc_steal(arp, tcparray);
452 vnn->tcp_array = NULL;
453 vnn->tcp_update_needed = true;
456 tevent_add_timer(arp->ctdb->ev, vnn->takeover_ctx,
457 timeval_zero(), ctdb_control_send_arp, arp);
462 struct ctdb_do_takeip_state {
463 struct ctdb_req_control_old *c;
464 struct ctdb_vnn *vnn;
468 called when takeip event finishes
470 static void ctdb_do_takeip_callback(struct ctdb_context *ctdb, int status,
473 struct ctdb_do_takeip_state *state =
474 talloc_get_type(private_data, struct ctdb_do_takeip_state);
479 if (status == -ETIMEDOUT) {
482 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
483 ctdb_addr_to_str(&state->vnn->public_address),
484 ctdb_vnn_iface_string(state->vnn)));
485 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
491 if (ctdb->do_checkpublicip) {
493 ret = ctdb_announce_vnn_iface(ctdb, state->vnn);
495 ctdb_request_control_reply(ctdb, state->c, NULL, -1, NULL);
502 data.dptr = (uint8_t *)ctdb_addr_to_str(&state->vnn->public_address);
503 data.dsize = strlen((char *)data.dptr) + 1;
504 DEBUG(DEBUG_INFO,(__location__ " sending TAKE_IP for '%s'\n", data.dptr));
506 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_TAKE_IP, data);
509 /* the control succeeded */
510 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
515 static int ctdb_takeip_destructor(struct ctdb_do_takeip_state *state)
517 state->vnn->update_in_flight = false;
522 take over an ip address
524 static int32_t ctdb_do_takeip(struct ctdb_context *ctdb,
525 struct ctdb_req_control_old *c,
526 struct ctdb_vnn *vnn)
529 struct ctdb_do_takeip_state *state;
531 if (vnn->update_in_flight) {
532 DEBUG(DEBUG_NOTICE,("Takeover of IP %s/%u rejected "
533 "update for this IP already in flight\n",
534 ctdb_addr_to_str(&vnn->public_address),
535 vnn->public_netmask_bits));
539 ret = ctdb_vnn_assign_iface(ctdb, vnn);
541 DEBUG(DEBUG_ERR,("Takeover of IP %s/%u failed to "
542 "assign a usable interface\n",
543 ctdb_addr_to_str(&vnn->public_address),
544 vnn->public_netmask_bits));
548 state = talloc(vnn, struct ctdb_do_takeip_state);
549 CTDB_NO_MEMORY(ctdb, state);
554 vnn->update_in_flight = true;
555 talloc_set_destructor(state, ctdb_takeip_destructor);
557 DEBUG(DEBUG_NOTICE,("Takeover of IP %s/%u on interface %s\n",
558 ctdb_addr_to_str(&vnn->public_address),
559 vnn->public_netmask_bits,
560 ctdb_vnn_iface_string(vnn)));
562 ret = ctdb_event_script_callback(ctdb,
564 ctdb_do_takeip_callback,
568 ctdb_vnn_iface_string(vnn),
569 ctdb_addr_to_str(&vnn->public_address),
570 vnn->public_netmask_bits);
573 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
574 ctdb_addr_to_str(&vnn->public_address),
575 ctdb_vnn_iface_string(vnn)));
580 state->c = talloc_steal(ctdb, c);
584 struct ctdb_do_updateip_state {
585 struct ctdb_req_control_old *c;
586 struct ctdb_interface *old;
587 struct ctdb_vnn *vnn;
591 called when updateip event finishes
593 static void ctdb_do_updateip_callback(struct ctdb_context *ctdb, int status,
596 struct ctdb_do_updateip_state *state =
597 talloc_get_type(private_data, struct ctdb_do_updateip_state);
600 if (status == -ETIMEDOUT) {
604 ("Failed update of IP %s from interface %s to %s\n",
605 ctdb_addr_to_str(&state->vnn->public_address),
606 iface_string(state->old),
607 ctdb_vnn_iface_string(state->vnn)));
610 * All we can do is reset the old interface
611 * and let the next run fix it
613 ctdb_vnn_unassign_iface(ctdb, state->vnn);
614 state->vnn->iface = state->old;
615 state->vnn->iface->references++;
617 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
622 /* the control succeeded */
623 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
628 static int ctdb_updateip_destructor(struct ctdb_do_updateip_state *state)
630 state->vnn->update_in_flight = false;
635 update (move) an ip address
637 static int32_t ctdb_do_updateip(struct ctdb_context *ctdb,
638 struct ctdb_req_control_old *c,
639 struct ctdb_vnn *vnn)
642 struct ctdb_do_updateip_state *state;
643 struct ctdb_interface *old = vnn->iface;
644 const char *old_name = iface_string(old);
645 const char *new_name;
647 if (vnn->update_in_flight) {
648 DEBUG(DEBUG_NOTICE,("Update of IP %s/%u rejected "
649 "update for this IP already in flight\n",
650 ctdb_addr_to_str(&vnn->public_address),
651 vnn->public_netmask_bits));
655 ctdb_vnn_unassign_iface(ctdb, vnn);
656 ret = ctdb_vnn_assign_iface(ctdb, vnn);
658 DEBUG(DEBUG_ERR,("Update of IP %s/%u failed to "
659 "assign a usable interface (old iface '%s')\n",
660 ctdb_addr_to_str(&vnn->public_address),
661 vnn->public_netmask_bits,
666 if (old == vnn->iface) {
667 /* A benign update from one interface onto itself.
668 * no need to run the eventscripts in this case, just return
671 ctdb_request_control_reply(ctdb, c, NULL, 0, NULL);
675 state = talloc(vnn, struct ctdb_do_updateip_state);
676 CTDB_NO_MEMORY(ctdb, state);
682 vnn->update_in_flight = true;
683 talloc_set_destructor(state, ctdb_updateip_destructor);
685 new_name = ctdb_vnn_iface_string(vnn);
686 DEBUG(DEBUG_NOTICE,("Update of IP %s/%u from "
687 "interface %s to %s\n",
688 ctdb_addr_to_str(&vnn->public_address),
689 vnn->public_netmask_bits,
693 ret = ctdb_event_script_callback(ctdb,
695 ctdb_do_updateip_callback,
697 CTDB_EVENT_UPDATE_IP,
701 ctdb_addr_to_str(&vnn->public_address),
702 vnn->public_netmask_bits);
705 ("Failed update IP %s from interface %s to %s\n",
706 ctdb_addr_to_str(&vnn->public_address),
707 old_name, new_name));
712 state->c = talloc_steal(ctdb, c);
717 Find the vnn of the node that has a public ip address
718 returns -1 if the address is not known as a public address
720 static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
722 struct ctdb_vnn *vnn;
724 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
725 if (ctdb_same_ip(&vnn->public_address, addr)) {
734 take over an ip address
736 int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
737 struct ctdb_req_control_old *c,
742 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
743 struct ctdb_vnn *vnn;
744 bool have_ip = false;
745 bool do_updateip = false;
746 bool do_takeip = false;
747 struct ctdb_interface *best_iface = NULL;
749 if (pip->pnn != ctdb->pnn) {
750 DEBUG(DEBUG_ERR,(__location__" takeoverip called for an ip '%s' "
751 "with pnn %d, but we're node %d\n",
752 ctdb_addr_to_str(&pip->addr),
753 pip->pnn, ctdb->pnn));
757 /* update out vnn list */
758 vnn = find_public_ip_vnn(ctdb, &pip->addr);
760 DEBUG(DEBUG_INFO,("takeoverip called for an ip '%s' that is not a public address\n",
761 ctdb_addr_to_str(&pip->addr)));
765 if (ctdb_config.failover_disabled == 0 && ctdb->do_checkpublicip) {
766 have_ip = ctdb_sys_have_ip(&pip->addr);
768 best_iface = ctdb_vnn_best_iface(ctdb, vnn);
769 if (best_iface == NULL) {
770 DEBUG(DEBUG_ERR,("takeoverip of IP %s/%u failed to find"
771 "a usable interface (old %s, have_ip %d)\n",
772 ctdb_addr_to_str(&vnn->public_address),
773 vnn->public_netmask_bits,
774 ctdb_vnn_iface_string(vnn),
779 if (vnn->pnn != ctdb->pnn && have_ip && vnn->pnn != CTDB_UNKNOWN_PNN) {
780 DEBUG(DEBUG_CRIT,(__location__ " takeoverip of IP %s is known to the kernel, "
781 "and we have it on iface[%s], but it was assigned to node %d"
782 "and we are node %d, banning ourself\n",
783 ctdb_addr_to_str(&vnn->public_address),
784 ctdb_vnn_iface_string(vnn), vnn->pnn, ctdb->pnn));
789 if (vnn->pnn == CTDB_UNKNOWN_PNN && have_ip) {
790 /* This will cause connections to be reset and
791 * reestablished. However, this is a very unusual
792 * situation and doing this will completely repair the
793 * inconsistency in the VNN.
797 " Doing updateip for IP %s already on an interface\n",
798 ctdb_addr_to_str(&vnn->public_address)));
803 if (vnn->iface != best_iface) {
804 if (!vnn->iface->link_up) {
806 } else if (vnn->iface->references > (best_iface->references + 1)) {
807 /* only move when the rebalance gains something */
815 ctdb_vnn_unassign_iface(ctdb, vnn);
822 ret = ctdb_do_takeip(ctdb, c, vnn);
826 } else if (do_updateip) {
827 ret = ctdb_do_updateip(ctdb, c, vnn);
833 * The interface is up and the kernel known the ip
836 DEBUG(DEBUG_INFO,("Redundant takeover of IP %s/%u on interface %s (ip already held)\n",
837 ctdb_addr_to_str(&pip->addr),
838 vnn->public_netmask_bits,
839 ctdb_vnn_iface_string(vnn)));
843 /* tell ctdb_control.c that we will be replying asynchronously */
849 static void do_delete_ip(struct ctdb_context *ctdb, struct ctdb_vnn *vnn)
851 DLIST_REMOVE(ctdb->vnn, vnn);
852 ctdb_vnn_unassign_iface(ctdb, vnn);
853 ctdb_remove_orphaned_ifaces(ctdb, vnn);
857 static struct ctdb_vnn *release_ip_post(struct ctdb_context *ctdb,
858 struct ctdb_vnn *vnn,
859 ctdb_sock_addr *addr)
863 /* Send a message to all clients of this node telling them
864 * that the cluster has been reconfigured and they should
865 * close any connections on this IP address
867 data.dptr = (uint8_t *)ctdb_addr_to_str(addr);
868 data.dsize = strlen((char *)data.dptr)+1;
869 DEBUG(DEBUG_INFO, ("Sending RELEASE_IP message for %s\n", data.dptr));
870 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data);
872 ctdb_vnn_unassign_iface(ctdb, vnn);
874 /* Process the IP if it has been marked for deletion */
875 if (vnn->delete_pending) {
876 do_delete_ip(ctdb, vnn);
883 struct release_ip_callback_state {
884 struct ctdb_req_control_old *c;
885 ctdb_sock_addr *addr;
886 struct ctdb_vnn *vnn;
891 called when releaseip event finishes
893 static void release_ip_callback(struct ctdb_context *ctdb, int status,
896 struct release_ip_callback_state *state =
897 talloc_get_type(private_data, struct release_ip_callback_state);
899 if (status == -ETIMEDOUT) {
903 if (ctdb_config.failover_disabled == 0 && ctdb->do_checkpublicip) {
904 if (ctdb_sys_have_ip(state->addr)) {
906 ("IP %s still hosted during release IP callback, failing\n",
907 ctdb_addr_to_str(state->addr)));
908 ctdb_request_control_reply(ctdb, state->c,
915 state->vnn->pnn = state->target_pnn;
916 state->vnn = release_ip_post(ctdb, state->vnn, state->addr);
918 /* the control succeeded */
919 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
923 static int ctdb_releaseip_destructor(struct release_ip_callback_state *state)
925 if (state->vnn != NULL) {
926 state->vnn->update_in_flight = false;
932 release an ip address
934 int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
935 struct ctdb_req_control_old *c,
940 struct release_ip_callback_state *state;
941 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
942 struct ctdb_vnn *vnn;
945 /* update our vnn list */
946 vnn = find_public_ip_vnn(ctdb, &pip->addr);
948 DEBUG(DEBUG_INFO,("releaseip called for an ip '%s' that is not a public address\n",
949 ctdb_addr_to_str(&pip->addr)));
953 /* stop any previous arps */
954 talloc_free(vnn->takeover_ctx);
955 vnn->takeover_ctx = NULL;
957 /* RELEASE_IP controls are sent to all nodes that should not
958 * be hosting a particular IP. This serves 2 purposes. The
959 * first is to help resolve any inconsistencies. If a node
960 * does unexpectedly host an IP then it will be released. The
961 * 2nd is to use a "redundant release" to tell non-takeover
962 * nodes where an IP is moving to. This is how "ctdb ip" can
963 * report the (likely) location of an IP by only asking the
964 * local node. Redundant releases need to update the PNN but
965 * are otherwise ignored.
967 if (ctdb_config.failover_disabled == 0 && ctdb->do_checkpublicip) {
968 if (!ctdb_sys_have_ip(&pip->addr)) {
969 DEBUG(DEBUG_DEBUG,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
970 ctdb_addr_to_str(&pip->addr),
971 vnn->public_netmask_bits,
972 ctdb_vnn_iface_string(vnn)));
974 ctdb_vnn_unassign_iface(ctdb, vnn);
978 if (vnn->iface == NULL) {
979 DEBUG(DEBUG_DEBUG,("Redundant release of IP %s/%u (ip not held)\n",
980 ctdb_addr_to_str(&pip->addr),
981 vnn->public_netmask_bits));
987 /* There is a potential race between take_ip and us because we
988 * update the VNN via a callback that run when the
989 * eventscripts have been run. Avoid the race by allowing one
990 * update to be in flight at a time.
992 if (vnn->update_in_flight) {
993 DEBUG(DEBUG_NOTICE,("Release of IP %s/%u rejected "
994 "update for this IP already in flight\n",
995 ctdb_addr_to_str(&vnn->public_address),
996 vnn->public_netmask_bits));
1000 iface = ctdb_vnn_iface_string(vnn);
1002 DEBUG(DEBUG_NOTICE,("Release of IP %s/%u on interface %s node:%d\n",
1003 ctdb_addr_to_str(&pip->addr),
1004 vnn->public_netmask_bits,
1008 state = talloc(ctdb, struct release_ip_callback_state);
1009 if (state == NULL) {
1010 ctdb_set_error(ctdb, "Out of memory at %s:%d",
1011 __FILE__, __LINE__);
1016 state->addr = talloc(state, ctdb_sock_addr);
1017 if (state->addr == NULL) {
1018 ctdb_set_error(ctdb, "Out of memory at %s:%d",
1019 __FILE__, __LINE__);
1023 *state->addr = pip->addr;
1024 state->target_pnn = pip->pnn;
1027 vnn->update_in_flight = true;
1028 talloc_set_destructor(state, ctdb_releaseip_destructor);
1030 ret = ctdb_event_script_callback(ctdb,
1031 state, release_ip_callback, state,
1032 CTDB_EVENT_RELEASE_IP,
1035 ctdb_addr_to_str(&pip->addr),
1036 vnn->public_netmask_bits);
1038 DEBUG(DEBUG_ERR,(__location__ " Failed to release IP %s on interface %s\n",
1039 ctdb_addr_to_str(&pip->addr),
1040 ctdb_vnn_iface_string(vnn)));
1045 /* tell the control that we will be reply asynchronously */
1046 *async_reply = true;
1047 state->c = talloc_steal(state, c);
1051 static int ctdb_add_public_address(struct ctdb_context *ctdb,
1052 ctdb_sock_addr *addr,
1053 unsigned mask, const char *ifaces,
1056 struct ctdb_vnn *vnn;
1060 /* Verify that we don't have an entry for this IP yet */
1061 for (vnn = ctdb->vnn; vnn != NULL; vnn = vnn->next) {
1062 if (ctdb_same_sockaddr(addr, &vnn->public_address)) {
1063 D_ERR("Duplicate public IP address '%s'\n",
1064 ctdb_addr_to_str(addr));
1069 /* Create a new VNN structure for this IP address */
1070 vnn = talloc_zero(ctdb, struct ctdb_vnn);
1072 DBG_ERR("Memory allocation error\n");
1075 tmp = talloc_strdup(vnn, ifaces);
1077 DBG_ERR("Memory allocation error\n");
1081 for (iface = strtok(tmp, ","); iface; iface = strtok(NULL, ",")) {
1082 struct vnn_interface *vnn_iface;
1083 struct ctdb_interface *i;
1085 if (!ctdb_sys_check_iface_exists(iface)) {
1086 D_ERR("Unknown interface %s for public address %s\n",
1088 ctdb_addr_to_str(addr));
1093 i = ctdb_add_local_iface(ctdb, iface);
1095 D_ERR("Failed to add interface '%s' "
1096 "for public address %s\n",
1098 ctdb_addr_to_str(addr));
1103 vnn_iface = talloc_zero(vnn, struct vnn_interface);
1104 if (vnn_iface == NULL) {
1105 DBG_ERR("Memory allocation error\n");
1110 vnn_iface->iface = i;
1111 DLIST_ADD_END(vnn->ifaces, vnn_iface);
1114 vnn->public_address = *addr;
1115 vnn->public_netmask_bits = mask;
1118 DLIST_ADD(ctdb->vnn, vnn);
1124 setup the public address lists from a file
1126 int ctdb_set_public_addresses(struct ctdb_context *ctdb, bool check_addresses)
1133 /* If no public addresses file given then try the default */
1134 if (ctdb->public_addresses_file == NULL) {
1135 const char *b = getenv("CTDB_BASE");
1137 DBG_ERR("CTDB_BASE not set\n");
1140 ctdb->public_addresses_file = talloc_asprintf(
1141 ctdb, "%s/%s", b, "public_addresses");
1142 if (ctdb->public_addresses_file == NULL) {
1143 DBG_ERR("Out of memory\n");
1148 /* If the file doesn't exist then warn and do nothing */
1149 ok = file_exist(ctdb->public_addresses_file);
1151 D_WARNING("Not loading public addresses, no file %s\n",
1152 ctdb->public_addresses_file);
1156 lines = file_lines_load(ctdb->public_addresses_file, &nlines, 0, ctdb);
1157 if (lines == NULL) {
1158 ctdb_set_error(ctdb, "Failed to load public address list '%s'\n", ctdb->public_addresses_file);
1161 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
1165 for (i=0;i<nlines;i++) {
1167 ctdb_sock_addr addr;
1168 const char *addrstr;
1174 while ((*line == ' ') || (*line == '\t')) {
1180 if (strcmp(line, "") == 0) {
1183 tok = strtok(line, " \t");
1186 tok = strtok(NULL, " \t");
1188 D_ERR("No interface specified at line %u "
1189 "of public addresses file\n", i+1);
1195 if (addrstr == NULL) {
1196 D_ERR("Badly formed line %u in public address list\n",
1202 ret = ctdb_sock_addr_mask_from_string(addrstr, &addr, &mask);
1204 D_ERR("Badly formed line %u in public address list\n",
1210 if (ctdb_add_public_address(ctdb, &addr, mask, ifaces, check_addresses)) {
1211 DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
1218 D_NOTICE("Loaded public addresses from %s\n",
1219 ctdb->public_addresses_file);
1226 destroy a ctdb_tcp_list structure
1228 static int ctdb_tcp_list_destructor(struct ctdb_tcp_list *tcp)
1230 struct ctdb_client *client = tcp->client;
1231 struct ctdb_connection *conn = &tcp->connection;
1232 char conn_str[132] = { 0, };
1235 ret = ctdb_connection_to_buf(conn_str,
1241 strlcpy(conn_str, "UNKNOWN", sizeof(conn_str));
1244 D_DEBUG("removing client TCP connection %s "
1245 "(client_id %u pid %d)\n",
1246 conn_str, client->client_id, client->pid);
1248 DLIST_REMOVE(client->tcp_list, tcp);
1251 * We don't call ctdb_remove_connection(vnn, conn) here
1252 * as we want the caller to decide if it's called
1253 * directly (local only) or indirectly via a
1254 * CTDB_CONTROL_TCP_REMOVE broadcast
1261 called by a client to inform us of a TCP connection that it is managing
1262 that should tickled with an ACK when IP takeover is done
1264 int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
1267 struct ctdb_client *client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
1268 struct ctdb_connection *tcp_sock = NULL;
1269 struct ctdb_tcp_list *tcp;
1270 struct ctdb_connection t;
1273 struct ctdb_vnn *vnn;
1274 ctdb_sock_addr src_addr;
1275 ctdb_sock_addr dst_addr;
1277 /* If we don't have public IPs, tickles are useless */
1278 if (ctdb->vnn == NULL) {
1282 tcp_sock = (struct ctdb_connection *)indata.dptr;
1284 ctdb_canonicalize_ip_inplace(&tcp_sock->src);
1285 src_addr = tcp_sock->src;
1287 ctdb_canonicalize_ip_inplace(&tcp_sock->dst);
1288 dst_addr = tcp_sock->dst;
1290 vnn = find_public_ip_vnn(ctdb, &dst_addr);
1292 char *src_addr_str = NULL;
1293 char *dst_addr_str = NULL;
1295 switch (dst_addr.sa.sa_family) {
1297 if (ntohl(dst_addr.ip.sin_addr.s_addr) == INADDR_LOOPBACK) {
1305 DEBUG(DEBUG_ERR,(__location__ " Unknown family type %d\n",
1306 dst_addr.sa.sa_family));
1310 src_addr_str = ctdb_sock_addr_to_string(client, &src_addr, false);
1311 dst_addr_str = ctdb_sock_addr_to_string(client, &dst_addr, false);
1313 "Could not register TCP connection from "
1314 "%s to %s (not a public address) (port %u) "
1315 "(client_id %u pid %u).\n",
1318 ctdb_sock_addr_port(&dst_addr),
1319 client_id, client->pid));
1320 TALLOC_FREE(src_addr_str);
1321 TALLOC_FREE(dst_addr_str);
1325 if (vnn->pnn != ctdb->pnn) {
1326 DEBUG(DEBUG_ERR,("Attempt to register tcp client for IP %s we don't hold - failing (client_id %u pid %u)\n",
1327 ctdb_addr_to_str(&dst_addr),
1328 client_id, client->pid));
1329 /* failing this call will tell smbd to die */
1333 tcp = talloc(client, struct ctdb_tcp_list);
1334 CTDB_NO_MEMORY(ctdb, tcp);
1335 tcp->client = client;
1337 tcp->connection.src = tcp_sock->src;
1338 tcp->connection.dst = tcp_sock->dst;
1340 DLIST_ADD(client->tcp_list, tcp);
1341 talloc_set_destructor(tcp, ctdb_tcp_list_destructor);
1343 t.src = tcp_sock->src;
1344 t.dst = tcp_sock->dst;
1346 data.dptr = (uint8_t *)&t;
1347 data.dsize = sizeof(t);
1349 switch (dst_addr.sa.sa_family) {
1351 DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
1352 (unsigned)ntohs(tcp_sock->dst.ip.sin_port),
1353 ctdb_addr_to_str(&tcp_sock->src),
1354 (unsigned)ntohs(tcp_sock->src.ip.sin_port), client_id, client->pid));
1357 DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
1358 (unsigned)ntohs(tcp_sock->dst.ip6.sin6_port),
1359 ctdb_addr_to_str(&tcp_sock->src),
1360 (unsigned)ntohs(tcp_sock->src.ip6.sin6_port), client_id, client->pid));
1363 DEBUG(DEBUG_ERR,(__location__ " Unknown family %d\n",
1364 dst_addr.sa.sa_family));
1368 /* tell all nodes about this tcp connection */
1369 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
1370 CTDB_CONTROL_TCP_ADD,
1371 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1373 DEBUG(DEBUG_ERR,(__location__ " Failed to send CTDB_CONTROL_TCP_ADD\n"));
1380 static bool ctdb_client_remove_tcp(struct ctdb_client *client,
1381 const struct ctdb_connection *conn)
1383 struct ctdb_tcp_list *tcp = NULL;
1384 struct ctdb_tcp_list *tcp_next = NULL;
1387 for (tcp = client->tcp_list; tcp != NULL; tcp = tcp_next) {
1390 tcp_next = tcp->next;
1392 same = ctdb_connection_same(conn, &tcp->connection);
1405 called by a client to inform us of a TCP connection that was disconnected
1407 int32_t ctdb_control_tcp_client_disconnected(struct ctdb_context *ctdb,
1411 struct ctdb_client *client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
1412 struct ctdb_connection *tcp_sock = NULL;
1415 char conn_str[132] = { 0, };
1418 tcp_sock = (struct ctdb_connection *)indata.dptr;
1420 ctdb_canonicalize_ip_inplace(&tcp_sock->src);
1421 ctdb_canonicalize_ip_inplace(&tcp_sock->dst);
1423 ret = ctdb_connection_to_buf(conn_str,
1429 strlcpy(conn_str, "UNKNOWN", sizeof(conn_str));
1432 found = ctdb_client_remove_tcp(client, tcp_sock);
1434 DBG_DEBUG("TCP connection %s not found "
1435 "(client_id %u pid %u).\n",
1436 conn_str, client_id, client->pid);
1440 D_INFO("deregistered TCP connection %s "
1441 "(client_id %u pid %u)\n",
1442 conn_str, client_id, client->pid);
1444 data.dptr = (uint8_t *)tcp_sock;
1445 data.dsize = sizeof(*tcp_sock);
1447 /* tell all nodes about this tcp connection is gone */
1448 ret = ctdb_daemon_send_control(ctdb,
1449 CTDB_BROADCAST_CONNECTED,
1451 CTDB_CONTROL_TCP_REMOVE,
1453 CTDB_CTRL_FLAG_NOREPLY,
1458 DBG_ERR("Failed to send CTDB_CONTROL_TCP_REMOVE: %s\n",
1467 find a tcp address on a list
1469 static struct ctdb_connection *ctdb_tcp_find(struct ctdb_tcp_array *array,
1470 struct ctdb_connection *tcp)
1474 if (array == NULL) {
1478 for (i=0;i<array->num;i++) {
1479 if (ctdb_same_sockaddr(&array->connections[i].src, &tcp->src) &&
1480 ctdb_same_sockaddr(&array->connections[i].dst, &tcp->dst)) {
1481 return &array->connections[i];
1490 called by a daemon to inform us of a TCP connection that one of its
1491 clients managing that should tickled with an ACK when IP takeover is
1494 int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata, bool tcp_update_needed)
1496 struct ctdb_connection *p = (struct ctdb_connection *)indata.dptr;
1497 struct ctdb_tcp_array *tcparray;
1498 struct ctdb_connection tcp;
1499 struct ctdb_vnn *vnn;
1501 /* If we don't have public IPs, tickles are useless */
1502 if (ctdb->vnn == NULL) {
1506 vnn = find_public_ip_vnn(ctdb, &p->dst);
1508 DEBUG(DEBUG_INFO,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
1509 ctdb_addr_to_str(&p->dst)));
1515 tcparray = vnn->tcp_array;
1517 /* If this is the first tickle */
1518 if (tcparray == NULL) {
1519 tcparray = talloc(vnn, struct ctdb_tcp_array);
1520 CTDB_NO_MEMORY(ctdb, tcparray);
1521 vnn->tcp_array = tcparray;
1524 tcparray->connections = talloc_size(tcparray, sizeof(struct ctdb_connection));
1525 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1527 tcparray->connections[tcparray->num].src = p->src;
1528 tcparray->connections[tcparray->num].dst = p->dst;
1531 if (tcp_update_needed) {
1532 vnn->tcp_update_needed = true;
1538 /* Do we already have this tickle ?*/
1541 if (ctdb_tcp_find(tcparray, &tcp) != NULL) {
1542 DEBUG(DEBUG_DEBUG,("Already had tickle info for %s:%u for vnn:%u\n",
1543 ctdb_addr_to_str(&tcp.dst),
1544 ntohs(tcp.dst.ip.sin_port),
1549 /* A new tickle, we must add it to the array */
1550 tcparray->connections = talloc_realloc(tcparray, tcparray->connections,
1551 struct ctdb_connection,
1553 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1555 tcparray->connections[tcparray->num].src = p->src;
1556 tcparray->connections[tcparray->num].dst = p->dst;
1559 DEBUG(DEBUG_INFO,("Added tickle info for %s:%u from vnn %u\n",
1560 ctdb_addr_to_str(&tcp.dst),
1561 ntohs(tcp.dst.ip.sin_port),
1564 if (tcp_update_needed) {
1565 vnn->tcp_update_needed = true;
1572 static void ctdb_remove_connection(struct ctdb_vnn *vnn, struct ctdb_connection *conn)
1574 struct ctdb_connection *tcpp;
1580 /* if the array is empty we can't remove it
1581 and we don't need to do anything
1583 if (vnn->tcp_array == NULL) {
1584 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesn't exist (array is empty) %s:%u\n",
1585 ctdb_addr_to_str(&conn->dst),
1586 ntohs(conn->dst.ip.sin_port)));
1591 /* See if we know this connection
1592 if we don't know this connection then we don't need to do anything
1594 tcpp = ctdb_tcp_find(vnn->tcp_array, conn);
1596 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesn't exist %s:%u\n",
1597 ctdb_addr_to_str(&conn->dst),
1598 ntohs(conn->dst.ip.sin_port)));
1603 /* We need to remove this entry from the array.
1604 Instead of allocating a new array and copying data to it
1605 we cheat and just copy the last entry in the existing array
1606 to the entry that is to be removed and just shring the
1609 *tcpp = vnn->tcp_array->connections[vnn->tcp_array->num - 1];
1610 vnn->tcp_array->num--;
1612 /* If we deleted the last entry we also need to remove the entire array
1614 if (vnn->tcp_array->num == 0) {
1615 talloc_free(vnn->tcp_array);
1616 vnn->tcp_array = NULL;
1619 vnn->tcp_update_needed = true;
1621 DEBUG(DEBUG_INFO,("Removed tickle info for %s:%u\n",
1622 ctdb_addr_to_str(&conn->src),
1623 ntohs(conn->src.ip.sin_port)));
1628 called by a daemon to inform us of a TCP connection that one of its
1629 clients used are no longer needed in the tickle database
1631 int32_t ctdb_control_tcp_remove(struct ctdb_context *ctdb, TDB_DATA indata)
1633 struct ctdb_vnn *vnn;
1634 struct ctdb_connection *conn = (struct ctdb_connection *)indata.dptr;
1636 /* If we don't have public IPs, tickles are useless */
1637 if (ctdb->vnn == NULL) {
1641 vnn = find_public_ip_vnn(ctdb, &conn->dst);
1644 (__location__ " unable to find public address %s\n",
1645 ctdb_addr_to_str(&conn->dst)));
1649 ctdb_remove_connection(vnn, conn);
1655 static void ctdb_send_set_tcp_tickles_for_all(struct ctdb_context *ctdb,
1659 Called when another daemon starts - causes all tickles for all
1660 public addresses we are serving to be sent to the new node on the
1661 next check. This actually causes the tickles to be sent to the
1662 other node immediately. In case there is an error, the periodic
1663 timer will send the updates on timer event. This is simple and
1664 doesn't require careful error handling.
1666 int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t pnn)
1668 DEBUG(DEBUG_INFO, ("Received startup control from node %lu\n",
1669 (unsigned long) pnn));
1671 ctdb_send_set_tcp_tickles_for_all(ctdb, true);
1677 called when a client structure goes away - hook to remove
1678 elements from the tcp_list in all daemons
1680 void ctdb_takeover_client_destructor_hook(struct ctdb_client *client)
1682 while (client->tcp_list) {
1683 struct ctdb_vnn *vnn;
1684 struct ctdb_tcp_list *tcp = client->tcp_list;
1685 struct ctdb_connection *conn = &tcp->connection;
1687 vnn = find_public_ip_vnn(client->ctdb,
1690 /* If the IP address is hosted on this node then
1691 * remove the connection. */
1692 if (vnn != NULL && vnn->pnn == client->ctdb->pnn) {
1693 ctdb_remove_connection(vnn, conn);
1696 /* Otherwise this function has been called because the
1697 * server IP address has been released to another node
1698 * and the client has exited. This means that we
1699 * should not delete the connection information. The
1700 * takeover node processes connections too. */
1703 * The destructor removes from the list
1710 void ctdb_release_all_ips(struct ctdb_context *ctdb)
1712 struct ctdb_vnn *vnn, *next;
1715 if (ctdb_config.failover_disabled == 1) {
1719 for (vnn = ctdb->vnn; vnn != NULL; vnn = next) {
1720 /* vnn can be freed below in release_ip_post() */
1723 if (!ctdb_sys_have_ip(&vnn->public_address)) {
1724 ctdb_vnn_unassign_iface(ctdb, vnn);
1728 /* Don't allow multiple releases at once. Some code,
1729 * particularly ctdb_tickle_sentenced_connections() is
1731 if (vnn->update_in_flight) {
1732 DEBUG(DEBUG_WARNING,
1734 " Not releasing IP %s/%u on interface %s, an update is already in progress\n",
1735 ctdb_addr_to_str(&vnn->public_address),
1736 vnn->public_netmask_bits,
1737 ctdb_vnn_iface_string(vnn)));
1740 vnn->update_in_flight = true;
1742 DEBUG(DEBUG_INFO,("Release of IP %s/%u on interface %s node:-1\n",
1743 ctdb_addr_to_str(&vnn->public_address),
1744 vnn->public_netmask_bits,
1745 ctdb_vnn_iface_string(vnn)));
1747 ctdb_event_script_args(ctdb, CTDB_EVENT_RELEASE_IP, "%s %s %u",
1748 ctdb_vnn_iface_string(vnn),
1749 ctdb_addr_to_str(&vnn->public_address),
1750 vnn->public_netmask_bits);
1751 /* releaseip timeouts are converted to success, so to
1752 * detect failures just check if the IP address is
1755 if (ctdb_sys_have_ip(&vnn->public_address)) {
1758 " IP address %s not released\n",
1759 ctdb_addr_to_str(&vnn->public_address)));
1760 vnn->update_in_flight = false;
1764 vnn = release_ip_post(ctdb, vnn, &vnn->public_address);
1766 vnn->update_in_flight = false;
1771 DEBUG(DEBUG_NOTICE,(__location__ " Released %d public IPs\n", count));
1776 get list of public IPs
1778 int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb,
1779 struct ctdb_req_control_old *c, TDB_DATA *outdata)
1782 struct ctdb_public_ip_list_old *ips;
1783 struct ctdb_vnn *vnn;
1784 bool only_available = false;
1786 if (c->flags & CTDB_PUBLIC_IP_FLAGS_ONLY_AVAILABLE) {
1787 only_available = true;
1790 /* count how many public ip structures we have */
1792 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1796 len = offsetof(struct ctdb_public_ip_list_old, ips) +
1797 num*sizeof(struct ctdb_public_ip);
1798 ips = talloc_zero_size(outdata, len);
1799 CTDB_NO_MEMORY(ctdb, ips);
1802 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1803 if (only_available && !ctdb_vnn_available(ctdb, vnn)) {
1806 ips->ips[i].pnn = vnn->pnn;
1807 ips->ips[i].addr = vnn->public_address;
1811 len = offsetof(struct ctdb_public_ip_list_old, ips) +
1812 i*sizeof(struct ctdb_public_ip);
1814 outdata->dsize = len;
1815 outdata->dptr = (uint8_t *)ips;
1821 int32_t ctdb_control_get_public_ip_info(struct ctdb_context *ctdb,
1822 struct ctdb_req_control_old *c,
1827 ctdb_sock_addr *addr;
1828 struct ctdb_public_ip_info_old *info;
1829 struct ctdb_vnn *vnn;
1830 struct vnn_interface *iface;
1832 addr = (ctdb_sock_addr *)indata.dptr;
1834 vnn = find_public_ip_vnn(ctdb, addr);
1836 DEBUG(DEBUG_ERR,(__location__ " Could not get public ip info, "
1837 "'%s'not a public address\n",
1838 ctdb_addr_to_str(addr)));
1842 /* count how many public ip structures we have */
1844 for (iface = vnn->ifaces; iface != NULL; iface = iface->next) {
1848 len = offsetof(struct ctdb_public_ip_info_old, ifaces) +
1849 num*sizeof(struct ctdb_iface);
1850 info = talloc_zero_size(outdata, len);
1851 CTDB_NO_MEMORY(ctdb, info);
1853 info->ip.addr = vnn->public_address;
1854 info->ip.pnn = vnn->pnn;
1855 info->active_idx = 0xFFFFFFFF;
1858 for (iface = vnn->ifaces; iface != NULL; iface = iface->next) {
1859 struct ctdb_interface *cur;
1862 if (vnn->iface == cur) {
1863 info->active_idx = i;
1865 strncpy(info->ifaces[i].name, cur->name,
1866 sizeof(info->ifaces[i].name));
1867 info->ifaces[i].name[sizeof(info->ifaces[i].name)-1] = '\0';
1868 info->ifaces[i].link_state = cur->link_up;
1869 info->ifaces[i].references = cur->references;
1874 len = offsetof(struct ctdb_public_ip_info_old, ifaces) +
1875 i*sizeof(struct ctdb_iface);
1877 outdata->dsize = len;
1878 outdata->dptr = (uint8_t *)info;
1883 int32_t ctdb_control_get_ifaces(struct ctdb_context *ctdb,
1884 struct ctdb_req_control_old *c,
1888 struct ctdb_iface_list_old *ifaces;
1889 struct ctdb_interface *cur;
1891 /* count how many public ip structures we have */
1893 for (cur=ctdb->ifaces;cur;cur=cur->next) {
1897 len = offsetof(struct ctdb_iface_list_old, ifaces) +
1898 num*sizeof(struct ctdb_iface);
1899 ifaces = talloc_zero_size(outdata, len);
1900 CTDB_NO_MEMORY(ctdb, ifaces);
1903 for (cur=ctdb->ifaces;cur;cur=cur->next) {
1904 strncpy(ifaces->ifaces[i].name, cur->name,
1905 sizeof(ifaces->ifaces[i].name));
1906 ifaces->ifaces[i].name[sizeof(ifaces->ifaces[i].name)-1] = '\0';
1907 ifaces->ifaces[i].link_state = cur->link_up;
1908 ifaces->ifaces[i].references = cur->references;
1912 len = offsetof(struct ctdb_iface_list_old, ifaces) +
1913 i*sizeof(struct ctdb_iface);
1915 outdata->dsize = len;
1916 outdata->dptr = (uint8_t *)ifaces;
1921 int32_t ctdb_control_set_iface_link(struct ctdb_context *ctdb,
1922 struct ctdb_req_control_old *c,
1925 struct ctdb_iface *info;
1926 struct ctdb_interface *iface;
1927 bool link_up = false;
1929 info = (struct ctdb_iface *)indata.dptr;
1931 if (info->name[CTDB_IFACE_SIZE] != '\0') {
1932 int len = strnlen(info->name, CTDB_IFACE_SIZE);
1933 DEBUG(DEBUG_ERR, (__location__ " name[%*.*s] not terminated\n",
1934 len, len, info->name));
1938 switch (info->link_state) {
1946 DEBUG(DEBUG_ERR, (__location__ " link_state[%u] invalid\n",
1947 (unsigned int)info->link_state));
1951 if (info->references != 0) {
1952 DEBUG(DEBUG_ERR, (__location__ " references[%u] should be 0\n",
1953 (unsigned int)info->references));
1957 iface = ctdb_find_iface(ctdb, info->name);
1958 if (iface == NULL) {
1962 if (link_up == iface->link_up) {
1967 ("iface[%s] has changed it's link status %s => %s\n",
1969 iface->link_up?"up":"down",
1970 link_up?"up":"down"));
1972 iface->link_up = link_up;
1978 called by a daemon to inform us of the entire list of TCP tickles for
1979 a particular public address.
1980 this control should only be sent by the node that is currently serving
1981 that public address.
1983 int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata)
1985 struct ctdb_tickle_list_old *list = (struct ctdb_tickle_list_old *)indata.dptr;
1986 struct ctdb_tcp_array *tcparray;
1987 struct ctdb_vnn *vnn;
1989 /* We must at least have tickles.num or else we can't verify the size
1990 of the received data blob
1992 if (indata.dsize < offsetof(struct ctdb_tickle_list_old, connections)) {
1993 DEBUG(DEBUG_ERR,("Bad indata in ctdb_tickle_list. Not enough data for the tickle.num field\n"));
1997 /* verify that the size of data matches what we expect */
1998 if (indata.dsize < offsetof(struct ctdb_tickle_list_old, connections)
1999 + sizeof(struct ctdb_connection) * list->num) {
2000 DEBUG(DEBUG_ERR,("Bad indata in ctdb_tickle_list\n"));
2004 DEBUG(DEBUG_INFO, ("Received tickle update for public address %s\n",
2005 ctdb_addr_to_str(&list->addr)));
2007 vnn = find_public_ip_vnn(ctdb, &list->addr);
2009 DEBUG(DEBUG_INFO,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n",
2010 ctdb_addr_to_str(&list->addr)));
2015 if (vnn->pnn == ctdb->pnn) {
2017 ("Ignoring redundant set tcp tickle list, this node hosts '%s'\n",
2018 ctdb_addr_to_str(&list->addr)));
2022 /* remove any old ticklelist we might have */
2023 talloc_free(vnn->tcp_array);
2024 vnn->tcp_array = NULL;
2026 tcparray = talloc(vnn, struct ctdb_tcp_array);
2027 CTDB_NO_MEMORY(ctdb, tcparray);
2029 tcparray->num = list->num;
2031 tcparray->connections = talloc_array(tcparray, struct ctdb_connection, tcparray->num);
2032 CTDB_NO_MEMORY(ctdb, tcparray->connections);
2034 memcpy(tcparray->connections, &list->connections[0],
2035 sizeof(struct ctdb_connection)*tcparray->num);
2037 /* We now have a new fresh tickle list array for this vnn */
2038 vnn->tcp_array = tcparray;
2044 called to return the full list of tickles for the puclic address associated
2045 with the provided vnn
2047 int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata)
2049 ctdb_sock_addr *addr = (ctdb_sock_addr *)indata.dptr;
2050 struct ctdb_tickle_list_old *list;
2051 struct ctdb_tcp_array *tcparray;
2052 unsigned int num, i;
2053 struct ctdb_vnn *vnn;
2056 vnn = find_public_ip_vnn(ctdb, addr);
2058 DEBUG(DEBUG_ERR,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n",
2059 ctdb_addr_to_str(addr)));
2064 port = ctdb_addr_to_port(addr);
2066 tcparray = vnn->tcp_array;
2068 if (tcparray != NULL) {
2070 /* All connections */
2071 num = tcparray->num;
2073 /* Count connections for port */
2074 for (i = 0; i < tcparray->num; i++) {
2075 if (port == ctdb_addr_to_port(&tcparray->connections[i].dst)) {
2082 outdata->dsize = offsetof(struct ctdb_tickle_list_old, connections)
2083 + sizeof(struct ctdb_connection) * num;
2085 outdata->dptr = talloc_size(outdata, outdata->dsize);
2086 CTDB_NO_MEMORY(ctdb, outdata->dptr);
2087 list = (struct ctdb_tickle_list_old *)outdata->dptr;
2097 for (i = 0; i < tcparray->num; i++) {
2099 port == ctdb_addr_to_port(&tcparray->connections[i].dst)) {
2100 list->connections[num] = tcparray->connections[i];
2110 set the list of all tcp tickles for a public address
2112 static int ctdb_send_set_tcp_tickles_for_ip(struct ctdb_context *ctdb,
2113 ctdb_sock_addr *addr,
2114 struct ctdb_tcp_array *tcparray)
2118 struct ctdb_tickle_list_old *list;
2121 num = tcparray->num;
2126 data.dsize = offsetof(struct ctdb_tickle_list_old, connections) +
2127 sizeof(struct ctdb_connection) * num;
2128 data.dptr = talloc_size(ctdb, data.dsize);
2129 CTDB_NO_MEMORY(ctdb, data.dptr);
2131 list = (struct ctdb_tickle_list_old *)data.dptr;
2135 memcpy(&list->connections[0], tcparray->connections, sizeof(struct ctdb_connection) * num);
2138 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_ALL, 0,
2139 CTDB_CONTROL_SET_TCP_TICKLE_LIST,
2140 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
2142 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set tcp tickles failed\n"));
2146 talloc_free(data.dptr);
2151 static void ctdb_send_set_tcp_tickles_for_all(struct ctdb_context *ctdb,
2154 struct ctdb_vnn *vnn;
2157 for (vnn = ctdb->vnn; vnn != NULL; vnn = vnn->next) {
2158 /* we only send out updates for public addresses that
2161 if (ctdb->pnn != vnn->pnn) {
2165 /* We only send out the updates if we need to */
2166 if (!force && !vnn->tcp_update_needed) {
2170 ret = ctdb_send_set_tcp_tickles_for_ip(ctdb,
2171 &vnn->public_address,
2174 D_ERR("Failed to send the tickle update for ip %s\n",
2175 ctdb_addr_to_str(&vnn->public_address));
2176 vnn->tcp_update_needed = true;
2178 D_INFO("Sent tickle update for ip %s\n",
2179 ctdb_addr_to_str(&vnn->public_address));
2180 vnn->tcp_update_needed = false;
2187 perform tickle updates if required
2189 static void ctdb_update_tcp_tickles(struct tevent_context *ev,
2190 struct tevent_timer *te,
2191 struct timeval t, void *private_data)
2193 struct ctdb_context *ctdb = talloc_get_type(
2194 private_data, struct ctdb_context);
2196 ctdb_send_set_tcp_tickles_for_all(ctdb, false);
2198 tevent_add_timer(ctdb->ev, ctdb->tickle_update_context,
2199 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
2200 ctdb_update_tcp_tickles, ctdb);
2204 start periodic update of tcp tickles
2206 void ctdb_start_tcp_tickle_update(struct ctdb_context *ctdb)
2208 ctdb->tickle_update_context = talloc_new(ctdb);
2210 tevent_add_timer(ctdb->ev, ctdb->tickle_update_context,
2211 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
2212 ctdb_update_tcp_tickles, ctdb);
2218 struct control_gratious_arp {
2219 struct ctdb_context *ctdb;
2220 ctdb_sock_addr addr;
2226 send a control_gratuitous arp
2228 static void send_gratious_arp(struct tevent_context *ev,
2229 struct tevent_timer *te,
2230 struct timeval t, void *private_data)
2233 struct control_gratious_arp *arp = talloc_get_type(private_data,
2234 struct control_gratious_arp);
2236 ret = ctdb_sys_send_arp(&arp->addr, arp->iface);
2238 DBG_ERR("Failed to send gratuitous ARP on iface %s: %s\n",
2239 arp->iface, strerror(ret));
2244 if (arp->count == CTDB_ARP_REPEAT) {
2249 tevent_add_timer(arp->ctdb->ev, arp,
2250 timeval_current_ofs(CTDB_ARP_INTERVAL, 0),
2251 send_gratious_arp, arp);
2258 int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indata)
2260 struct ctdb_addr_info_old *gratious_arp = (struct ctdb_addr_info_old *)indata.dptr;
2261 struct control_gratious_arp *arp;
2263 /* verify the size of indata */
2264 if (indata.dsize < offsetof(struct ctdb_addr_info_old, iface)) {
2265 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_gratious_arp structure. Got %u require %u bytes\n",
2266 (unsigned)indata.dsize,
2267 (unsigned)offsetof(struct ctdb_addr_info_old, iface)));
2271 ( offsetof(struct ctdb_addr_info_old, iface)
2272 + gratious_arp->len ) ){
2274 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
2275 "but should be %u bytes\n",
2276 (unsigned)indata.dsize,
2277 (unsigned)(offsetof(struct ctdb_addr_info_old, iface)+gratious_arp->len)));
2282 arp = talloc(ctdb, struct control_gratious_arp);
2283 CTDB_NO_MEMORY(ctdb, arp);
2286 arp->addr = gratious_arp->addr;
2287 arp->iface = talloc_strdup(arp, gratious_arp->iface);
2288 CTDB_NO_MEMORY(ctdb, arp->iface);
2291 tevent_add_timer(arp->ctdb->ev, arp,
2292 timeval_zero(), send_gratious_arp, arp);
2297 int32_t ctdb_control_add_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
2299 struct ctdb_addr_info_old *pub = (struct ctdb_addr_info_old *)indata.dptr;
2302 /* verify the size of indata */
2303 if (indata.dsize < offsetof(struct ctdb_addr_info_old, iface)) {
2304 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_addr_info structure\n"));
2308 ( offsetof(struct ctdb_addr_info_old, iface)
2311 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
2312 "but should be %u bytes\n",
2313 (unsigned)indata.dsize,
2314 (unsigned)(offsetof(struct ctdb_addr_info_old, iface)+pub->len)));
2318 DEBUG(DEBUG_NOTICE,("Add IP %s\n", ctdb_addr_to_str(&pub->addr)));
2320 ret = ctdb_add_public_address(ctdb, &pub->addr, pub->mask, &pub->iface[0], true);
2323 DEBUG(DEBUG_ERR,(__location__ " Failed to add public address\n"));
2330 int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
2332 struct ctdb_addr_info_old *pub = (struct ctdb_addr_info_old *)indata.dptr;
2333 struct ctdb_vnn *vnn;
2335 /* verify the size of indata */
2336 if (indata.dsize < offsetof(struct ctdb_addr_info_old, iface)) {
2337 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_addr_info structure\n"));
2341 ( offsetof(struct ctdb_addr_info_old, iface)
2344 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
2345 "but should be %u bytes\n",
2346 (unsigned)indata.dsize,
2347 (unsigned)(offsetof(struct ctdb_addr_info_old, iface)+pub->len)));
2351 DEBUG(DEBUG_NOTICE,("Delete IP %s\n", ctdb_addr_to_str(&pub->addr)));
2353 /* walk over all public addresses until we find a match */
2354 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
2355 if (ctdb_same_ip(&vnn->public_address, &pub->addr)) {
2356 if (vnn->pnn == ctdb->pnn) {
2357 /* This IP is currently being hosted.
2358 * Defer the deletion until the next
2359 * takeover run. "ctdb reloadips" will
2360 * always cause a takeover run. "ctdb
2361 * delip" will now need an explicit
2362 * "ctdb ipreallocated" afterwards. */
2363 vnn->delete_pending = true;
2365 /* This IP is not hosted on the
2366 * current node so just delete it
2368 do_delete_ip(ctdb, vnn);
2375 DEBUG(DEBUG_ERR,("Delete IP of unknown public IP address %s\n",
2376 ctdb_addr_to_str(&pub->addr)));
2381 struct ipreallocated_callback_state {
2382 struct ctdb_req_control_old *c;
2385 static void ctdb_ipreallocated_callback(struct ctdb_context *ctdb,
2386 int status, void *p)
2388 struct ipreallocated_callback_state *state =
2389 talloc_get_type(p, struct ipreallocated_callback_state);
2393 (" \"ipreallocated\" event script failed (status %d)\n",
2395 if (status == -ETIMEDOUT) {
2396 ctdb_ban_self(ctdb);
2400 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
2404 /* A control to run the ipreallocated event */
2405 int32_t ctdb_control_ipreallocated(struct ctdb_context *ctdb,
2406 struct ctdb_req_control_old *c,
2410 struct ipreallocated_callback_state *state;
2412 state = talloc(ctdb, struct ipreallocated_callback_state);
2413 CTDB_NO_MEMORY(ctdb, state);
2415 DEBUG(DEBUG_INFO,(__location__ " Running \"ipreallocated\" event\n"));
2417 ret = ctdb_event_script_callback(ctdb, state,
2418 ctdb_ipreallocated_callback, state,
2419 CTDB_EVENT_IPREALLOCATED,
2423 DEBUG(DEBUG_ERR,("Failed to run \"ipreallocated\" event \n"));
2428 /* tell the control that we will be reply asynchronously */
2429 state->c = talloc_steal(state, c);
2430 *async_reply = true;
2436 struct ctdb_reloadips_handle {
2437 struct ctdb_context *ctdb;
2438 struct ctdb_req_control_old *c;
2442 struct tevent_fd *fde;
2445 static int ctdb_reloadips_destructor(struct ctdb_reloadips_handle *h)
2447 if (h == h->ctdb->reload_ips) {
2448 h->ctdb->reload_ips = NULL;
2451 ctdb_request_control_reply(h->ctdb, h->c, NULL, h->status, NULL);
2454 ctdb_kill(h->ctdb, h->child, SIGKILL);
2458 static void ctdb_reloadips_timeout_event(struct tevent_context *ev,
2459 struct tevent_timer *te,
2460 struct timeval t, void *private_data)
2462 struct ctdb_reloadips_handle *h = talloc_get_type(private_data, struct ctdb_reloadips_handle);
2467 static void ctdb_reloadips_child_handler(struct tevent_context *ev,
2468 struct tevent_fd *fde,
2469 uint16_t flags, void *private_data)
2471 struct ctdb_reloadips_handle *h = talloc_get_type(private_data, struct ctdb_reloadips_handle);
2476 ret = sys_read(h->fd[0], &res, 1);
2477 if (ret < 1 || res != 0) {
2478 DEBUG(DEBUG_ERR, (__location__ " Reloadips child process returned error\n"));
2486 static int ctdb_reloadips_child(struct ctdb_context *ctdb)
2488 TALLOC_CTX *mem_ctx = talloc_new(NULL);
2489 struct ctdb_public_ip_list_old *ips;
2490 struct ctdb_vnn *vnn;
2491 struct client_async_data *async_data;
2492 struct timeval timeout;
2494 struct ctdb_client_control_state *state;
2499 CTDB_NO_MEMORY(ctdb, mem_ctx);
2501 /* Read IPs from local node */
2502 ret = ctdb_ctrl_get_public_ips(ctdb, TAKEOVER_TIMEOUT(),
2503 CTDB_CURRENT_NODE, mem_ctx, &ips);
2506 ("Unable to fetch public IPs from local node\n"));
2507 talloc_free(mem_ctx);
2511 /* Read IPs file - this is safe since this is a child process */
2513 if (ctdb_set_public_addresses(ctdb, false) != 0) {
2514 DEBUG(DEBUG_ERR,("Failed to re-read public addresses file\n"));
2515 talloc_free(mem_ctx);
2519 async_data = talloc_zero(mem_ctx, struct client_async_data);
2520 CTDB_NO_MEMORY(ctdb, async_data);
2522 /* Compare IPs between node and file for IPs to be deleted */
2523 for (i = 0; i < ips->num; i++) {
2525 for (vnn = ctdb->vnn; vnn; vnn = vnn->next) {
2526 if (ctdb_same_ip(&vnn->public_address,
2527 &ips->ips[i].addr)) {
2528 /* IP is still in file */
2534 /* Delete IP ips->ips[i] */
2535 struct ctdb_addr_info_old *pub;
2538 ("IP %s no longer configured, deleting it\n",
2539 ctdb_addr_to_str(&ips->ips[i].addr)));
2541 pub = talloc_zero(mem_ctx, struct ctdb_addr_info_old);
2542 CTDB_NO_MEMORY(ctdb, pub);
2544 pub->addr = ips->ips[i].addr;
2548 timeout = TAKEOVER_TIMEOUT();
2550 data.dsize = offsetof(struct ctdb_addr_info_old,
2552 data.dptr = (uint8_t *)pub;
2554 state = ctdb_control_send(ctdb, CTDB_CURRENT_NODE, 0,
2555 CTDB_CONTROL_DEL_PUBLIC_IP,
2556 0, data, async_data,
2558 if (state == NULL) {
2561 " failed sending CTDB_CONTROL_DEL_PUBLIC_IP\n"));
2565 ctdb_client_async_add(async_data, state);
2569 /* Compare IPs between node and file for IPs to be added */
2571 for (vnn = ctdb->vnn; vnn; vnn = vnn->next) {
2572 for (i = 0; i < ips->num; i++) {
2573 if (ctdb_same_ip(&vnn->public_address,
2574 &ips->ips[i].addr)) {
2575 /* IP already on node */
2579 if (i == ips->num) {
2580 /* Add IP ips->ips[i] */
2581 struct ctdb_addr_info_old *pub;
2582 const char *ifaces = NULL;
2584 struct vnn_interface *iface = NULL;
2587 ("New IP %s configured, adding it\n",
2588 ctdb_addr_to_str(&vnn->public_address)));
2590 uint32_t pnn = ctdb_get_pnn(ctdb);
2592 data.dsize = sizeof(pnn);
2593 data.dptr = (uint8_t *)&pnn;
2595 ret = ctdb_client_send_message(
2597 CTDB_BROADCAST_CONNECTED,
2598 CTDB_SRVID_REBALANCE_NODE,
2601 DEBUG(DEBUG_WARNING,
2602 ("Failed to send message to force node reallocation - IPs may be unbalanced\n"));
2608 ifaces = vnn->ifaces->iface->name;
2609 iface = vnn->ifaces->next;
2610 while (iface != NULL) {
2611 ifaces = talloc_asprintf(vnn, "%s,%s", ifaces,
2612 iface->iface->name);
2613 iface = iface->next;
2616 len = strlen(ifaces) + 1;
2617 pub = talloc_zero_size(mem_ctx,
2618 offsetof(struct ctdb_addr_info_old, iface) + len);
2619 CTDB_NO_MEMORY(ctdb, pub);
2621 pub->addr = vnn->public_address;
2622 pub->mask = vnn->public_netmask_bits;
2624 memcpy(&pub->iface[0], ifaces, pub->len);
2626 timeout = TAKEOVER_TIMEOUT();
2628 data.dsize = offsetof(struct ctdb_addr_info_old,
2630 data.dptr = (uint8_t *)pub;
2632 state = ctdb_control_send(ctdb, CTDB_CURRENT_NODE, 0,
2633 CTDB_CONTROL_ADD_PUBLIC_IP,
2634 0, data, async_data,
2636 if (state == NULL) {
2639 " failed sending CTDB_CONTROL_ADD_PUBLIC_IP\n"));
2643 ctdb_client_async_add(async_data, state);
2647 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
2648 DEBUG(DEBUG_ERR,(__location__ " Add/delete IPs failed\n"));
2652 talloc_free(mem_ctx);
2656 talloc_free(mem_ctx);
2660 /* This control is sent to force the node to re-read the public addresses file
2661 and drop any addresses we should nnot longer host, and add new addresses
2662 that we are now able to host
2664 int32_t ctdb_control_reload_public_ips(struct ctdb_context *ctdb, struct ctdb_req_control_old *c, bool *async_reply)
2666 struct ctdb_reloadips_handle *h;
2667 pid_t parent = getpid();
2669 if (ctdb->reload_ips != NULL) {
2670 talloc_free(ctdb->reload_ips);
2671 ctdb->reload_ips = NULL;
2674 h = talloc(ctdb, struct ctdb_reloadips_handle);
2675 CTDB_NO_MEMORY(ctdb, h);
2680 if (pipe(h->fd) == -1) {
2681 DEBUG(DEBUG_ERR,("Failed to create pipe for ctdb_freeze_lock\n"));
2686 h->child = ctdb_fork(ctdb);
2687 if (h->child == (pid_t)-1) {
2688 DEBUG(DEBUG_ERR, ("Failed to fork a child for reloadips\n"));
2696 if (h->child == 0) {
2697 signed char res = 0;
2701 prctl_set_comment("ctdb_reloadips");
2702 if (switch_from_server_to_client(ctdb) != 0) {
2703 DEBUG(DEBUG_CRIT,("ERROR: Failed to switch reloadips child into client mode\n"));
2706 res = ctdb_reloadips_child(ctdb);
2708 DEBUG(DEBUG_ERR,("Failed to reload ips on local node\n"));
2712 sys_write(h->fd[1], &res, 1);
2713 ctdb_wait_for_process_to_exit(parent);
2717 h->c = talloc_steal(h, c);
2720 set_close_on_exec(h->fd[0]);
2722 talloc_set_destructor(h, ctdb_reloadips_destructor);
2725 h->fde = tevent_add_fd(ctdb->ev, h, h->fd[0], TEVENT_FD_READ,
2726 ctdb_reloadips_child_handler, (void *)h);
2727 tevent_fd_set_auto_close(h->fde);
2729 tevent_add_timer(ctdb->ev, h, timeval_current_ofs(120, 0),
2730 ctdb_reloadips_timeout_event, h);
2732 /* we reply later */
2733 *async_reply = true;