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/util_file.h"
34 #include "lib/util/sys_rw.h"
35 #include "lib/util/util_process.h"
37 #include "protocol/protocol_util.h"
39 #include "ctdb_private.h"
40 #include "ctdb_client.h"
42 #include "common/reqid.h"
43 #include "common/system.h"
44 #include "common/system_socket.h"
45 #include "common/common.h"
46 #include "common/logging.h"
47 #include "common/path.h"
49 #include "conf/ctdb_config.h"
51 #include "server/ipalloc.h"
53 #define TAKEOVER_TIMEOUT() timeval_current_ofs(ctdb->tunable.takeover_timeout,0)
55 #define CTDB_ARP_INTERVAL 1
56 #define CTDB_ARP_REPEAT 3
58 struct ctdb_interface
{
59 struct ctdb_interface
*prev
, *next
;
65 struct vnn_interface
{
66 struct vnn_interface
*prev
, *next
;
67 struct ctdb_interface
*iface
;
70 /* state associated with a public ip address */
72 struct ctdb_vnn
*prev
, *next
;
74 struct ctdb_interface
*iface
;
75 struct vnn_interface
*ifaces
;
76 ctdb_sock_addr public_address
;
77 uint8_t public_netmask_bits
;
81 * The node number that is serving this public address - set
82 * to CTDB_UNKNOWN_PNN if no node is serving it
86 /* List of clients to tickle for this public address */
87 struct ctdb_tcp_array
*tcp_array
;
89 /* whether we need to update the other nodes with changes to our list
90 of connected clients */
91 bool tcp_update_needed
;
93 /* a context to hang sending gratious arp events off */
94 TALLOC_CTX
*takeover_ctx
;
96 /* Set to true any time an update to this VNN is in flight.
97 This helps to avoid races. */
98 bool update_in_flight
;
100 /* If CTDB_CONTROL_DEL_PUBLIC_IP is received for this IP
101 * address then this flag is set. It will be deleted in the
102 * release IP callback. */
106 static const char *iface_string(const struct ctdb_interface
*iface
)
108 return (iface
!= NULL
? iface
->name
: "__none__");
111 static const char *ctdb_vnn_iface_string(const struct ctdb_vnn
*vnn
)
113 return iface_string(vnn
->iface
);
116 static const char *ctdb_vnn_address_string(const struct ctdb_vnn
*vnn
)
121 static struct ctdb_interface
*ctdb_find_iface(struct ctdb_context
*ctdb
,
124 static struct ctdb_interface
*
125 ctdb_add_local_iface(struct ctdb_context
*ctdb
, const char *iface
)
127 struct ctdb_interface
*i
;
129 if (strlen(iface
) > CTDB_IFACE_SIZE
) {
130 DEBUG(DEBUG_ERR
, ("Interface name too long \"%s\"\n", iface
));
134 /* Verify that we don't have an entry for this ip yet */
135 i
= ctdb_find_iface(ctdb
, iface
);
140 /* create a new structure for this interface */
141 i
= talloc_zero(ctdb
, struct ctdb_interface
);
143 DEBUG(DEBUG_ERR
, (__location__
" out of memory\n"));
146 i
->name
= talloc_strdup(i
, iface
);
147 if (i
->name
== NULL
) {
148 DEBUG(DEBUG_ERR
, (__location__
" out of memory\n"));
155 DLIST_ADD(ctdb
->ifaces
, i
);
160 static bool vnn_has_interface(struct ctdb_vnn
*vnn
,
161 const struct ctdb_interface
*iface
)
163 struct vnn_interface
*i
;
165 for (i
= vnn
->ifaces
; i
!= NULL
; i
= i
->next
) {
166 if (iface
== i
->iface
) {
174 /* If any interfaces now have no possible IPs then delete them. This
175 * implementation is naive (i.e. simple) rather than clever
176 * (i.e. complex). Given that this is run on delip and that operation
177 * is rare, this doesn't need to be efficient - it needs to be
178 * foolproof. One alternative is reference counting, where the logic
179 * is distributed and can, therefore, be broken in multiple places.
180 * Another alternative is to build a red-black tree of interfaces that
181 * can have addresses (by walking ctdb->vnn once) and then walking
182 * ctdb->ifaces once and deleting those not in the tree. Let's go to
183 * one of those if the naive implementation causes problems... :-)
185 static void ctdb_remove_orphaned_ifaces(struct ctdb_context
*ctdb
,
186 struct ctdb_vnn
*vnn
)
188 struct ctdb_interface
*i
, *next
;
190 /* For each interface, check if there's an IP using it. */
191 for (i
= ctdb
->ifaces
; i
!= NULL
; i
= next
) {
196 /* Only consider interfaces named in the given VNN. */
197 if (!vnn_has_interface(vnn
, i
)) {
201 /* Search for a vnn with this interface. */
203 for (tv
=ctdb
->vnn
; tv
; tv
=tv
->next
) {
204 if (vnn_has_interface(tv
, i
)) {
211 /* None of the VNNs are using this interface. */
212 DLIST_REMOVE(ctdb
->ifaces
, i
);
219 static struct ctdb_interface
*ctdb_find_iface(struct ctdb_context
*ctdb
,
222 struct ctdb_interface
*i
;
224 for (i
=ctdb
->ifaces
;i
;i
=i
->next
) {
225 if (strcmp(i
->name
, iface
) == 0) {
233 static struct ctdb_interface
*ctdb_vnn_best_iface(struct ctdb_context
*ctdb
,
234 struct ctdb_vnn
*vnn
)
236 struct vnn_interface
*i
;
237 struct ctdb_interface
*cur
= NULL
;
238 struct ctdb_interface
*best
= NULL
;
240 for (i
= vnn
->ifaces
; i
!= NULL
; i
= i
->next
) {
253 if (cur
->references
< best
->references
) {
262 static int32_t ctdb_vnn_assign_iface(struct ctdb_context
*ctdb
,
263 struct ctdb_vnn
*vnn
)
265 struct ctdb_interface
*best
= NULL
;
268 DBG_INFO("public address '%s' still assigned to iface '%s'\n",
269 ctdb_vnn_address_string(vnn
),
270 ctdb_vnn_iface_string(vnn
));
274 best
= ctdb_vnn_best_iface(ctdb
, vnn
);
276 DBG_ERR("public address '%s' cannot assign to iface any iface\n",
277 ctdb_vnn_address_string(vnn
));
283 vnn
->pnn
= ctdb
->pnn
;
285 DBG_INFO("public address '%s' now assigned to iface '%s' refs[%d]\n",
286 ctdb_vnn_address_string(vnn
),
287 ctdb_vnn_iface_string(vnn
),
292 static void ctdb_vnn_unassign_iface(struct ctdb_context
*ctdb
,
293 struct ctdb_vnn
*vnn
)
295 DBG_INFO("public address '%s' "
296 "now unassigned (old iface '%s' refs[%d])\n",
297 ctdb_vnn_address_string(vnn
),
298 ctdb_vnn_iface_string(vnn
),
299 vnn
->iface
!= NULL
? vnn
->iface
->references
: 0);
301 vnn
->iface
->references
--;
304 if (vnn
->pnn
== ctdb
->pnn
) {
305 vnn
->pnn
= CTDB_UNKNOWN_PNN
;
309 static bool ctdb_vnn_available(struct ctdb_context
*ctdb
,
310 struct ctdb_vnn
*vnn
)
313 struct vnn_interface
*i
;
315 /* Nodes that are not RUNNING can not host IPs */
316 if (ctdb
->runstate
!= CTDB_RUNSTATE_RUNNING
) {
320 flags
= ctdb
->nodes
[ctdb
->pnn
]->flags
;
321 if ((flags
& (NODE_FLAGS_INACTIVE
|NODE_FLAGS_DISABLED
)) != 0) {
325 if (vnn
->delete_pending
) {
329 if (vnn
->iface
&& vnn
->iface
->link_up
) {
333 for (i
= vnn
->ifaces
; i
!= NULL
; i
= i
->next
) {
334 if (i
->iface
->link_up
) {
342 struct ctdb_takeover_arp
{
343 struct ctdb_context
*ctdb
;
346 struct ctdb_tcp_array
*tcparray
;
347 struct ctdb_vnn
*vnn
;
352 lists of tcp endpoints
354 struct ctdb_tcp_list
{
355 struct ctdb_tcp_list
*prev
, *next
;
356 struct ctdb_client
*client
;
357 struct ctdb_connection connection
;
361 send a gratuitous arp
363 static void ctdb_control_send_arp(struct tevent_context
*ev
,
364 struct tevent_timer
*te
,
365 struct timeval t
, void *private_data
)
367 struct ctdb_takeover_arp
*arp
= talloc_get_type(private_data
,
368 struct ctdb_takeover_arp
);
370 struct ctdb_tcp_array
*tcparray
;
373 /* IP address might have been released between sends */
374 if (arp
->vnn
->iface
== NULL
) {
375 DBG_INFO("Cancelling ARP send for released IP %s\n",
376 ctdb_vnn_address_string(arp
->vnn
));
381 iface
= ctdb_vnn_iface_string(arp
->vnn
);
382 ret
= ctdb_sys_send_arp(&arp
->addr
, iface
);
384 DBG_ERR("Failed to send ARP on interface %s: %s\n",
385 iface
, strerror(ret
));
388 tcparray
= arp
->tcparray
;
392 for (i
=0;i
<tcparray
->num
;i
++) {
393 struct ctdb_connection
*tcon
;
396 tcon
= &tcparray
->connections
[i
];
397 ret
= ctdb_connection_to_buf(buf
,
403 strlcpy(buf
, "UNKNOWN", sizeof(buf
));
405 D_INFO("Send TCP tickle ACK: %s\n", buf
);
406 ret
= ctdb_sys_send_tcp(
411 DBG_ERR("Failed to send TCP tickle ACK: %s\n",
419 if (arp
->count
== CTDB_ARP_REPEAT
) {
424 tevent_add_timer(arp
->ctdb
->ev
, arp
->vnn
->takeover_ctx
,
425 timeval_current_ofs(CTDB_ARP_INTERVAL
, 100000),
426 ctdb_control_send_arp
, arp
);
429 static int32_t ctdb_announce_vnn_iface(struct ctdb_context
*ctdb
,
430 struct ctdb_vnn
*vnn
)
432 struct ctdb_takeover_arp
*arp
;
433 struct ctdb_tcp_array
*tcparray
;
435 if (!vnn
->takeover_ctx
) {
436 vnn
->takeover_ctx
= talloc_new(vnn
);
437 if (!vnn
->takeover_ctx
) {
442 arp
= talloc_zero(vnn
->takeover_ctx
, struct ctdb_takeover_arp
);
448 arp
->addr
= vnn
->public_address
;
451 tcparray
= vnn
->tcp_array
;
453 /* add all of the known tcp connections for this IP to the
454 list of tcp connections to send tickle acks for */
455 arp
->tcparray
= talloc_steal(arp
, tcparray
);
457 vnn
->tcp_array
= NULL
;
458 vnn
->tcp_update_needed
= true;
461 tevent_add_timer(arp
->ctdb
->ev
, vnn
->takeover_ctx
,
462 timeval_zero(), ctdb_control_send_arp
, arp
);
467 struct ctdb_do_takeip_state
{
468 struct ctdb_req_control_old
*c
;
469 struct ctdb_vnn
*vnn
;
473 called when takeip event finishes
475 static void ctdb_do_takeip_callback(struct ctdb_context
*ctdb
, int status
,
478 struct ctdb_do_takeip_state
*state
=
479 talloc_get_type(private_data
, struct ctdb_do_takeip_state
);
484 if (status
== -ETIMEDOUT
) {
487 DBG_ERR("Failed to takeover IP %s on interface %s\n",
488 ctdb_vnn_address_string(state
->vnn
),
489 ctdb_vnn_iface_string(state
->vnn
));
490 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, status
, NULL
);
496 if (ctdb
->do_checkpublicip
) {
498 ret
= ctdb_announce_vnn_iface(ctdb
, state
->vnn
);
500 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, -1, NULL
);
507 data
.dptr
= (uint8_t *)discard_const(
508 ctdb_vnn_address_string(state
->vnn
));
509 data
.dsize
= strlen((char *)data
.dptr
) + 1;
510 DEBUG(DEBUG_INFO
,(__location__
" sending TAKE_IP for '%s'\n", data
.dptr
));
512 ctdb_daemon_send_message(ctdb
, ctdb
->pnn
, CTDB_SRVID_TAKE_IP
, data
);
515 /* the control succeeded */
516 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, 0, NULL
);
521 static int ctdb_takeip_destructor(struct ctdb_do_takeip_state
*state
)
523 state
->vnn
->update_in_flight
= false;
528 take over an ip address
530 static int32_t ctdb_do_takeip(struct ctdb_context
*ctdb
,
531 struct ctdb_req_control_old
*c
,
532 struct ctdb_vnn
*vnn
)
535 struct ctdb_do_takeip_state
*state
;
537 if (vnn
->update_in_flight
) {
538 D_NOTICE("Takeover of IP %s/%u rejected "
539 "update for this IP already in flight\n",
540 ctdb_vnn_address_string(vnn
),
541 vnn
->public_netmask_bits
);
545 ret
= ctdb_vnn_assign_iface(ctdb
, vnn
);
547 D_ERR("Takeover of IP %s/%u failed to "
548 "assign a usable interface\n",
549 ctdb_vnn_address_string(vnn
),
550 vnn
->public_netmask_bits
);
554 state
= talloc(vnn
, struct ctdb_do_takeip_state
);
555 CTDB_NO_MEMORY(ctdb
, state
);
560 vnn
->update_in_flight
= true;
561 talloc_set_destructor(state
, ctdb_takeip_destructor
);
563 D_NOTICE("Takeover of IP %s/%u on interface %s\n",
564 ctdb_vnn_address_string(vnn
),
565 vnn
->public_netmask_bits
,
566 ctdb_vnn_iface_string(vnn
));
568 ret
= ctdb_event_script_callback(ctdb
,
570 ctdb_do_takeip_callback
,
574 ctdb_vnn_iface_string(vnn
),
575 ctdb_vnn_address_string(vnn
),
576 vnn
->public_netmask_bits
);
579 DBG_ERR("Failed to takeover IP %s on interface %s\n",
580 ctdb_vnn_address_string(vnn
),
581 ctdb_vnn_iface_string(vnn
));
586 state
->c
= talloc_steal(ctdb
, c
);
590 struct ctdb_do_updateip_state
{
591 struct ctdb_req_control_old
*c
;
592 struct ctdb_interface
*old
;
593 struct ctdb_vnn
*vnn
;
597 called when updateip event finishes
599 static void ctdb_do_updateip_callback(struct ctdb_context
*ctdb
, int status
,
602 struct ctdb_do_updateip_state
*state
=
603 talloc_get_type(private_data
, struct ctdb_do_updateip_state
);
606 if (status
== -ETIMEDOUT
) {
609 D_ERR("Failed update of IP %s from interface %s to %s\n",
610 ctdb_vnn_address_string(state
->vnn
),
611 iface_string(state
->old
),
612 ctdb_vnn_iface_string(state
->vnn
));
615 * All we can do is reset the old interface
616 * and let the next run fix it
618 ctdb_vnn_unassign_iface(ctdb
, state
->vnn
);
619 state
->vnn
->iface
= state
->old
;
620 state
->vnn
->iface
->references
++;
622 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, status
, NULL
);
627 /* the control succeeded */
628 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, 0, NULL
);
633 static int ctdb_updateip_destructor(struct ctdb_do_updateip_state
*state
)
635 state
->vnn
->update_in_flight
= false;
640 update (move) an ip address
642 static int32_t ctdb_do_updateip(struct ctdb_context
*ctdb
,
643 struct ctdb_req_control_old
*c
,
644 struct ctdb_vnn
*vnn
)
647 struct ctdb_do_updateip_state
*state
;
648 struct ctdb_interface
*old
= vnn
->iface
;
649 const char *old_name
= iface_string(old
);
650 const char *new_name
;
652 if (vnn
->update_in_flight
) {
653 D_NOTICE("Update of IP %s/%u rejected "
654 "update for this IP already in flight\n",
655 ctdb_vnn_address_string(vnn
),
656 vnn
->public_netmask_bits
);
660 ctdb_vnn_unassign_iface(ctdb
, vnn
);
661 ret
= ctdb_vnn_assign_iface(ctdb
, vnn
);
663 D_ERR("Update of IP %s/%u failed to "
664 "assign a usable interface (old iface '%s')\n",
665 ctdb_vnn_address_string(vnn
),
666 vnn
->public_netmask_bits
,
671 if (old
== vnn
->iface
) {
672 /* A benign update from one interface onto itself.
673 * no need to run the eventscripts in this case, just return
676 ctdb_request_control_reply(ctdb
, c
, NULL
, 0, NULL
);
680 state
= talloc(vnn
, struct ctdb_do_updateip_state
);
681 CTDB_NO_MEMORY(ctdb
, state
);
687 vnn
->update_in_flight
= true;
688 talloc_set_destructor(state
, ctdb_updateip_destructor
);
690 new_name
= ctdb_vnn_iface_string(vnn
);
691 D_NOTICE("Update of IP %s/%u from "
692 "interface %s to %s\n",
693 ctdb_vnn_address_string(vnn
),
694 vnn
->public_netmask_bits
,
698 ret
= ctdb_event_script_callback(ctdb
,
700 ctdb_do_updateip_callback
,
702 CTDB_EVENT_UPDATE_IP
,
706 ctdb_vnn_address_string(vnn
),
707 vnn
->public_netmask_bits
);
709 D_ERR("Failed update IP %s from interface %s to %s\n",
710 ctdb_vnn_address_string(vnn
),
717 state
->c
= talloc_steal(ctdb
, c
);
722 * Find vnn that has public IP addr, return NULL if not found
724 static struct ctdb_vnn
*find_public_ip_vnn(struct ctdb_context
*ctdb
,
725 ctdb_sock_addr
*addr
)
727 struct ctdb_vnn
*vnn
= NULL
;
729 for (vnn
= ctdb
->vnn
; vnn
!= NULL
; vnn
= vnn
->next
) {
730 if (ctdb_same_ip(&vnn
->public_address
, addr
)) {
739 take over an ip address
741 int32_t ctdb_control_takeover_ip(struct ctdb_context
*ctdb
,
742 struct ctdb_req_control_old
*c
,
747 struct ctdb_public_ip
*pip
= (struct ctdb_public_ip
*)indata
.dptr
;
748 struct ctdb_vnn
*vnn
;
749 bool have_ip
= false;
750 bool do_updateip
= false;
751 bool do_takeip
= false;
752 struct ctdb_interface
*best_iface
= NULL
;
754 if (pip
->pnn
!= ctdb
->pnn
) {
755 DEBUG(DEBUG_ERR
,(__location__
" takeoverip called for an ip '%s' "
756 "with pnn %d, but we're node %d\n",
757 ctdb_addr_to_str(&pip
->addr
),
758 pip
->pnn
, ctdb
->pnn
));
762 /* update out vnn list */
763 vnn
= find_public_ip_vnn(ctdb
, &pip
->addr
);
765 DEBUG(DEBUG_INFO
,("takeoverip called for an ip '%s' that is not a public address\n",
766 ctdb_addr_to_str(&pip
->addr
)));
770 if (ctdb_config
.failover_disabled
== 0 && ctdb
->do_checkpublicip
) {
771 have_ip
= ctdb_sys_have_ip(&pip
->addr
);
773 best_iface
= ctdb_vnn_best_iface(ctdb
, vnn
);
774 if (best_iface
== NULL
) {
775 D_ERR("takeoverip of IP %s/%u failed to find"
776 "a usable interface (old %s, have_ip %d)\n",
777 ctdb_vnn_address_string(vnn
),
778 vnn
->public_netmask_bits
,
779 ctdb_vnn_iface_string(vnn
),
784 if (vnn
->pnn
!= ctdb
->pnn
&& have_ip
&& vnn
->pnn
!= CTDB_UNKNOWN_PNN
) {
785 DBG_ERR("takeoverip of IP %s is known to the kernel, "
786 "and we have it on iface[%s], "
787 "but it was assigned to node %d"
788 "and we are node %d, banning ourself\n",
789 ctdb_vnn_address_string(vnn
),
790 ctdb_vnn_iface_string(vnn
),
797 if (vnn
->pnn
== CTDB_UNKNOWN_PNN
&& have_ip
) {
798 /* This will cause connections to be reset and
799 * reestablished. However, this is a very unusual
800 * situation and doing this will completely repair the
801 * inconsistency in the VNN.
804 "Doing updateip for IP %s already on an interface\n",
805 ctdb_vnn_address_string(vnn
));
810 if (vnn
->iface
!= best_iface
) {
811 if (!vnn
->iface
->link_up
) {
813 } else if (vnn
->iface
->references
> (best_iface
->references
+ 1)) {
814 /* only move when the rebalance gains something */
822 ctdb_vnn_unassign_iface(ctdb
, vnn
);
829 ret
= ctdb_do_takeip(ctdb
, c
, vnn
);
833 } else if (do_updateip
) {
834 ret
= ctdb_do_updateip(ctdb
, c
, vnn
);
840 * The interface is up and the kernel known the ip
843 DEBUG(DEBUG_INFO
,("Redundant takeover of IP %s/%u on interface %s (ip already held)\n",
844 ctdb_addr_to_str(&pip
->addr
),
845 vnn
->public_netmask_bits
,
846 ctdb_vnn_iface_string(vnn
)));
850 /* tell ctdb_control.c that we will be replying asynchronously */
856 static void do_delete_ip(struct ctdb_context
*ctdb
, struct ctdb_vnn
*vnn
)
858 DLIST_REMOVE(ctdb
->vnn
, vnn
);
859 ctdb_vnn_unassign_iface(ctdb
, vnn
);
860 ctdb_remove_orphaned_ifaces(ctdb
, vnn
);
864 static struct ctdb_vnn
*release_ip_post(struct ctdb_context
*ctdb
,
865 struct ctdb_vnn
*vnn
,
866 ctdb_sock_addr
*addr
)
870 /* Send a message to all clients of this node telling them
871 * that the cluster has been reconfigured and they should
872 * close any connections on this IP address
874 data
.dptr
= (uint8_t *)ctdb_addr_to_str(addr
);
875 data
.dsize
= strlen((char *)data
.dptr
)+1;
876 DEBUG(DEBUG_INFO
, ("Sending RELEASE_IP message for %s\n", data
.dptr
));
877 ctdb_daemon_send_message(ctdb
, ctdb
->pnn
, CTDB_SRVID_RELEASE_IP
, data
);
879 ctdb_vnn_unassign_iface(ctdb
, vnn
);
881 /* Process the IP if it has been marked for deletion */
882 if (vnn
->delete_pending
) {
883 do_delete_ip(ctdb
, vnn
);
890 struct release_ip_callback_state
{
891 struct ctdb_req_control_old
*c
;
892 ctdb_sock_addr
*addr
;
893 struct ctdb_vnn
*vnn
;
898 called when releaseip event finishes
900 static void release_ip_callback(struct ctdb_context
*ctdb
, int status
,
903 struct release_ip_callback_state
*state
=
904 talloc_get_type(private_data
, struct release_ip_callback_state
);
906 if (status
== -ETIMEDOUT
) {
910 if (ctdb_config
.failover_disabled
== 0 && ctdb
->do_checkpublicip
) {
911 if (ctdb_sys_have_ip(state
->addr
)) {
913 ("IP %s still hosted during release IP callback, failing\n",
914 ctdb_addr_to_str(state
->addr
)));
915 ctdb_request_control_reply(ctdb
, state
->c
,
922 state
->vnn
->pnn
= state
->target_pnn
;
923 state
->vnn
= release_ip_post(ctdb
, state
->vnn
, state
->addr
);
925 /* the control succeeded */
926 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, 0, NULL
);
930 static int ctdb_releaseip_destructor(struct release_ip_callback_state
*state
)
932 if (state
->vnn
!= NULL
) {
933 state
->vnn
->update_in_flight
= false;
939 release an ip address
941 int32_t ctdb_control_release_ip(struct ctdb_context
*ctdb
,
942 struct ctdb_req_control_old
*c
,
947 struct release_ip_callback_state
*state
;
948 struct ctdb_public_ip
*pip
= (struct ctdb_public_ip
*)indata
.dptr
;
949 struct ctdb_vnn
*vnn
;
952 /* update our vnn list */
953 vnn
= find_public_ip_vnn(ctdb
, &pip
->addr
);
955 DEBUG(DEBUG_INFO
,("releaseip called for an ip '%s' that is not a public address\n",
956 ctdb_addr_to_str(&pip
->addr
)));
960 /* stop any previous arps */
961 talloc_free(vnn
->takeover_ctx
);
962 vnn
->takeover_ctx
= NULL
;
964 /* RELEASE_IP controls are sent to all nodes that should not
965 * be hosting a particular IP. This serves 2 purposes. The
966 * first is to help resolve any inconsistencies. If a node
967 * does unexpectedly host an IP then it will be released. The
968 * 2nd is to use a "redundant release" to tell non-takeover
969 * nodes where an IP is moving to. This is how "ctdb ip" can
970 * report the (likely) location of an IP by only asking the
971 * local node. Redundant releases need to update the PNN but
972 * are otherwise ignored.
974 if (ctdb_config
.failover_disabled
== 0 && ctdb
->do_checkpublicip
) {
975 if (!ctdb_sys_have_ip(&pip
->addr
)) {
976 DEBUG(DEBUG_DEBUG
,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
977 ctdb_addr_to_str(&pip
->addr
),
978 vnn
->public_netmask_bits
,
979 ctdb_vnn_iface_string(vnn
)));
981 ctdb_vnn_unassign_iface(ctdb
, vnn
);
985 if (vnn
->iface
== NULL
) {
986 DEBUG(DEBUG_DEBUG
,("Redundant release of IP %s/%u (ip not held)\n",
987 ctdb_addr_to_str(&pip
->addr
),
988 vnn
->public_netmask_bits
));
994 /* There is a potential race between take_ip and us because we
995 * update the VNN via a callback that run when the
996 * eventscripts have been run. Avoid the race by allowing one
997 * update to be in flight at a time.
999 if (vnn
->update_in_flight
) {
1000 D_NOTICE("Release of IP %s/%u rejected "
1001 "update for this IP already in flight\n",
1002 ctdb_vnn_address_string(vnn
),
1003 vnn
->public_netmask_bits
);
1007 iface
= ctdb_vnn_iface_string(vnn
);
1009 DEBUG(DEBUG_NOTICE
,("Release of IP %s/%u on interface %s node:%d\n",
1010 ctdb_addr_to_str(&pip
->addr
),
1011 vnn
->public_netmask_bits
,
1015 state
= talloc(ctdb
, struct release_ip_callback_state
);
1016 if (state
== NULL
) {
1017 ctdb_set_error(ctdb
, "Out of memory at %s:%d",
1018 __FILE__
, __LINE__
);
1023 state
->addr
= talloc(state
, ctdb_sock_addr
);
1024 if (state
->addr
== NULL
) {
1025 ctdb_set_error(ctdb
, "Out of memory at %s:%d",
1026 __FILE__
, __LINE__
);
1030 *state
->addr
= pip
->addr
;
1031 state
->target_pnn
= pip
->pnn
;
1034 vnn
->update_in_flight
= true;
1035 talloc_set_destructor(state
, ctdb_releaseip_destructor
);
1037 ret
= ctdb_event_script_callback(ctdb
,
1038 state
, release_ip_callback
, state
,
1039 CTDB_EVENT_RELEASE_IP
,
1042 ctdb_addr_to_str(&pip
->addr
),
1043 vnn
->public_netmask_bits
);
1045 DEBUG(DEBUG_ERR
,(__location__
" Failed to release IP %s on interface %s\n",
1046 ctdb_addr_to_str(&pip
->addr
),
1047 ctdb_vnn_iface_string(vnn
)));
1052 /* tell the control that we will be reply asynchronously */
1053 *async_reply
= true;
1054 state
->c
= talloc_steal(state
, c
);
1058 static int ctdb_add_public_address(struct ctdb_context
*ctdb
,
1059 ctdb_sock_addr
*addr
,
1060 unsigned mask
, const char *ifaces
)
1062 struct ctdb_vnn
*vnn
;
1066 /* Verify that we don't have an entry for this IP yet */
1067 for (vnn
= ctdb
->vnn
; vnn
!= NULL
; vnn
= vnn
->next
) {
1068 if (ctdb_same_sockaddr(addr
, &vnn
->public_address
)) {
1069 D_ERR("Duplicate public IP address '%s'\n",
1070 ctdb_addr_to_str(addr
));
1075 /* Create a new VNN structure for this IP address */
1076 vnn
= talloc_zero(ctdb
, struct ctdb_vnn
);
1078 DBG_ERR("Memory allocation error\n");
1082 vnn
->name
= ctdb_sock_addr_to_string(vnn
, addr
, false);
1083 if (vnn
->name
== NULL
) {
1084 DBG_ERR("Memory allocation error\n");
1089 tmp
= talloc_strdup(vnn
, ifaces
);
1091 DBG_ERR("Memory allocation error\n");
1095 for (iface
= strtok(tmp
, ","); iface
; iface
= strtok(NULL
, ",")) {
1096 struct vnn_interface
*vnn_iface
;
1097 struct ctdb_interface
*i
;
1099 if (!ctdb_sys_check_iface_exists(iface
)) {
1100 D_ERR("Unknown interface %s for public address %s\n",
1102 ctdb_vnn_address_string(vnn
));
1107 i
= ctdb_add_local_iface(ctdb
, iface
);
1109 D_ERR("Failed to add interface '%s' "
1110 "for public address %s\n",
1112 ctdb_vnn_address_string(vnn
));
1117 vnn_iface
= talloc_zero(vnn
, struct vnn_interface
);
1118 if (vnn_iface
== NULL
) {
1119 DBG_ERR("Memory allocation error\n");
1124 vnn_iface
->iface
= i
;
1125 DLIST_ADD_END(vnn
->ifaces
, vnn_iface
);
1128 vnn
->public_address
= *addr
;
1129 vnn
->public_netmask_bits
= mask
;
1132 DLIST_ADD(ctdb
->vnn
, vnn
);
1138 setup the public address lists from a file
1140 int ctdb_set_public_addresses(struct ctdb_context
*ctdb
)
1147 /* If no public addresses file given then try the default */
1148 if (ctdb
->public_addresses_file
== NULL
) {
1149 ctdb
->public_addresses_file
= path_etcdir_append(
1150 ctdb
, "public_addresses");
1151 if (ctdb
->public_addresses_file
== NULL
) {
1152 DBG_ERR("Out of memory\n");
1157 /* If the file doesn't exist then warn and do nothing */
1158 ok
= file_exist(ctdb
->public_addresses_file
);
1160 D_WARNING("Not loading public addresses, no file %s\n",
1161 ctdb
->public_addresses_file
);
1165 lines
= file_lines_load(ctdb
->public_addresses_file
, &nlines
, 0, ctdb
);
1166 if (lines
== NULL
) {
1167 ctdb_set_error(ctdb
, "Failed to load public address list '%s'\n", ctdb
->public_addresses_file
);
1170 while (nlines
> 0 && strcmp(lines
[nlines
-1], "") == 0) {
1174 for (i
=0;i
<nlines
;i
++) {
1176 ctdb_sock_addr addr
;
1177 const char *addrstr
;
1183 while ((*line
== ' ') || (*line
== '\t')) {
1189 if (strcmp(line
, "") == 0) {
1192 tok
= strtok(line
, " \t");
1195 tok
= strtok(NULL
, " \t");
1197 D_ERR("No interface specified at line %u "
1198 "of public addresses file\n", i
+1);
1204 if (addrstr
== NULL
) {
1205 D_ERR("Badly formed line %u in public address list\n",
1211 ret
= ctdb_sock_addr_mask_from_string(addrstr
, &addr
, &mask
);
1213 D_ERR("Badly formed line %u in public address list\n",
1219 if (ctdb_add_public_address(ctdb
, &addr
, mask
, ifaces
)) {
1220 DEBUG(DEBUG_CRIT
,("Failed to add line %u to the public address list\n", i
+1));
1227 D_NOTICE("Loaded public addresses from %s\n",
1228 ctdb
->public_addresses_file
);
1235 destroy a ctdb_tcp_list structure
1237 static int ctdb_tcp_list_destructor(struct ctdb_tcp_list
*tcp
)
1239 struct ctdb_client
*client
= tcp
->client
;
1240 struct ctdb_connection
*conn
= &tcp
->connection
;
1241 char conn_str
[132] = { 0, };
1244 ret
= ctdb_connection_to_buf(conn_str
,
1250 strlcpy(conn_str
, "UNKNOWN", sizeof(conn_str
));
1253 D_DEBUG("removing client TCP connection %s "
1254 "(client_id %u pid %d)\n",
1255 conn_str
, client
->client_id
, client
->pid
);
1257 DLIST_REMOVE(client
->tcp_list
, tcp
);
1260 * We don't call ctdb_remove_connection(vnn, conn) here
1261 * as we want the caller to decide if it's called
1262 * directly (local only) or indirectly via a
1263 * CTDB_CONTROL_TCP_REMOVE broadcast
1270 called by a client to inform us of a TCP connection that it is managing
1271 that should tickled with an ACK when IP takeover is done
1273 int32_t ctdb_control_tcp_client(struct ctdb_context
*ctdb
, uint32_t client_id
,
1276 struct ctdb_client
*client
= reqid_find(ctdb
->idr
, client_id
, struct ctdb_client
);
1277 struct ctdb_connection
*tcp_sock
= NULL
;
1278 struct ctdb_tcp_list
*tcp
;
1279 struct ctdb_connection t
;
1282 struct ctdb_vnn
*vnn
;
1283 char conn_str
[132] = { 0, };
1285 /* If we don't have public IPs, tickles are useless */
1286 if (ctdb
->vnn
== NULL
) {
1290 tcp_sock
= (struct ctdb_connection
*)indata
.dptr
;
1292 ctdb_canonicalize_ip_inplace(&tcp_sock
->src
);
1293 ctdb_canonicalize_ip_inplace(&tcp_sock
->dst
);
1295 ret
= ctdb_connection_to_buf(conn_str
,
1301 strlcpy(conn_str
, "UNKNOWN", sizeof(conn_str
));
1304 vnn
= find_public_ip_vnn(ctdb
, &tcp_sock
->dst
);
1306 D_ERR("Could not register TCP connection %s - "
1307 "not a public address (client_id %u pid %u)\n",
1308 conn_str
, client_id
, client
->pid
);
1312 if (vnn
->pnn
!= ctdb
->pnn
) {
1313 D_ERR("Attempt to register tcp client for IP %s we don't hold - "
1314 "failing (client_id %u pid %u)\n",
1315 ctdb_addr_to_str(&tcp_sock
->dst
),
1316 client_id
, client
->pid
);
1317 /* failing this call will tell smbd to die */
1321 tcp
= talloc(client
, struct ctdb_tcp_list
);
1322 CTDB_NO_MEMORY(ctdb
, tcp
);
1323 tcp
->client
= client
;
1325 tcp
->connection
.src
= tcp_sock
->src
;
1326 tcp
->connection
.dst
= tcp_sock
->dst
;
1328 DLIST_ADD(client
->tcp_list
, tcp
);
1329 talloc_set_destructor(tcp
, ctdb_tcp_list_destructor
);
1331 t
.src
= tcp_sock
->src
;
1332 t
.dst
= tcp_sock
->dst
;
1334 data
.dptr
= (uint8_t *)&t
;
1335 data
.dsize
= sizeof(t
);
1337 D_INFO("Registered TCP connection %s (client_id %u pid %u)\n",
1338 conn_str
, client_id
, client
->pid
);
1340 /* tell all nodes about this tcp connection */
1341 ret
= ctdb_daemon_send_control(ctdb
, CTDB_BROADCAST_CONNECTED
, 0,
1342 CTDB_CONTROL_TCP_ADD
,
1343 0, CTDB_CTRL_FLAG_NOREPLY
, data
, NULL
, NULL
);
1345 DEBUG(DEBUG_ERR
,(__location__
" Failed to send CTDB_CONTROL_TCP_ADD\n"));
1352 static bool ctdb_client_remove_tcp(struct ctdb_client
*client
,
1353 const struct ctdb_connection
*conn
)
1355 struct ctdb_tcp_list
*tcp
= NULL
;
1356 struct ctdb_tcp_list
*tcp_next
= NULL
;
1359 for (tcp
= client
->tcp_list
; tcp
!= NULL
; tcp
= tcp_next
) {
1362 tcp_next
= tcp
->next
;
1364 same
= ctdb_connection_same(conn
, &tcp
->connection
);
1377 called by a client to inform us of a TCP connection that was disconnected
1379 int32_t ctdb_control_tcp_client_disconnected(struct ctdb_context
*ctdb
,
1383 struct ctdb_client
*client
= reqid_find(ctdb
->idr
, client_id
, struct ctdb_client
);
1384 struct ctdb_connection
*tcp_sock
= NULL
;
1387 char conn_str
[132] = { 0, };
1390 tcp_sock
= (struct ctdb_connection
*)indata
.dptr
;
1392 ctdb_canonicalize_ip_inplace(&tcp_sock
->src
);
1393 ctdb_canonicalize_ip_inplace(&tcp_sock
->dst
);
1395 ret
= ctdb_connection_to_buf(conn_str
,
1401 strlcpy(conn_str
, "UNKNOWN", sizeof(conn_str
));
1404 found
= ctdb_client_remove_tcp(client
, tcp_sock
);
1406 DBG_DEBUG("TCP connection %s not found "
1407 "(client_id %u pid %u).\n",
1408 conn_str
, client_id
, client
->pid
);
1412 D_INFO("deregistered TCP connection %s "
1413 "(client_id %u pid %u)\n",
1414 conn_str
, client_id
, client
->pid
);
1416 data
.dptr
= (uint8_t *)tcp_sock
;
1417 data
.dsize
= sizeof(*tcp_sock
);
1419 /* tell all nodes about this tcp connection is gone */
1420 ret
= ctdb_daemon_send_control(ctdb
,
1421 CTDB_BROADCAST_CONNECTED
,
1423 CTDB_CONTROL_TCP_REMOVE
,
1425 CTDB_CTRL_FLAG_NOREPLY
,
1430 DBG_ERR("Failed to send CTDB_CONTROL_TCP_REMOVE: %s\n",
1439 called by a client to inform us of a TCP connection was passed to a different
1440 "client" (typically with multichannel to another smbd process).
1442 int32_t ctdb_control_tcp_client_passed(struct ctdb_context
*ctdb
,
1446 struct ctdb_client
*client
= reqid_find(ctdb
->idr
, client_id
, struct ctdb_client
);
1447 struct ctdb_connection
*tcp_sock
= NULL
;
1449 char conn_str
[132] = { 0, };
1452 tcp_sock
= (struct ctdb_connection
*)indata
.dptr
;
1454 ctdb_canonicalize_ip_inplace(&tcp_sock
->src
);
1455 ctdb_canonicalize_ip_inplace(&tcp_sock
->dst
);
1457 ret
= ctdb_connection_to_buf(conn_str
,
1463 strlcpy(conn_str
, "UNKNOWN", sizeof(conn_str
));
1466 found
= ctdb_client_remove_tcp(client
, tcp_sock
);
1468 DBG_DEBUG("TCP connection from %s not found "
1469 "(client_id %u pid %u).\n",
1470 conn_str
, client_id
, client
->pid
);
1474 D_INFO("TCP connection from %s "
1475 "(client_id %u pid %u) passed to another client\n",
1476 conn_str
, client_id
, client
->pid
);
1479 * We don't call CTDB_CONTROL_TCP_REMOVE
1480 * nor ctdb_remove_connection() as the connection
1481 * is still alive, but handled by another client
1488 find a tcp address on a list
1490 static struct ctdb_connection
*ctdb_tcp_find(struct ctdb_tcp_array
*array
,
1491 struct ctdb_connection
*tcp
)
1495 if (array
== NULL
) {
1499 for (i
=0;i
<array
->num
;i
++) {
1500 if (ctdb_same_sockaddr(&array
->connections
[i
].src
, &tcp
->src
) &&
1501 ctdb_same_sockaddr(&array
->connections
[i
].dst
, &tcp
->dst
)) {
1502 return &array
->connections
[i
];
1511 called by a daemon to inform us of a TCP connection that one of its
1512 clients managing that should tickled with an ACK when IP takeover is
1515 int32_t ctdb_control_tcp_add(struct ctdb_context
*ctdb
,
1517 bool tcp_update_needed
)
1519 struct ctdb_connection
*p
= (struct ctdb_connection
*)indata
.dptr
;
1520 struct ctdb_tcp_array
*tcparray
;
1521 struct ctdb_vnn
*vnn
;
1522 char conn_str
[132] = { 0, };
1525 /* If we don't have public IPs, tickles are useless */
1526 if (ctdb
->vnn
== NULL
) {
1530 ret
= ctdb_connection_to_buf(conn_str
,
1536 strlcpy(conn_str
, "UNKNOWN", sizeof(conn_str
));
1539 vnn
= find_public_ip_vnn(ctdb
, &p
->dst
);
1541 DBG_INFO("Attempt to add connection %s "
1542 "but destination is not a public address\n",
1548 tcparray
= vnn
->tcp_array
;
1550 /* If this is the first tickle */
1551 if (tcparray
== NULL
) {
1552 tcparray
= talloc(vnn
, struct ctdb_tcp_array
);
1553 CTDB_NO_MEMORY(ctdb
, tcparray
);
1554 vnn
->tcp_array
= tcparray
;
1557 tcparray
->connections
= talloc_size(tcparray
,
1558 sizeof(struct ctdb_connection
));
1559 CTDB_NO_MEMORY(ctdb
, tcparray
->connections
);
1561 tcparray
->connections
[tcparray
->num
].src
= p
->src
;
1562 tcparray
->connections
[tcparray
->num
].dst
= p
->dst
;
1565 if (tcp_update_needed
) {
1566 vnn
->tcp_update_needed
= true;
1572 /* Do we already have this tickle ?*/
1573 if (ctdb_tcp_find(tcparray
, p
) != NULL
) {
1574 DBG_DEBUG("Already had connection %s\n", conn_str
);
1578 /* A new tickle, we must add it to the array */
1579 tcparray
->connections
= talloc_realloc(tcparray
,
1580 tcparray
->connections
,
1581 struct ctdb_connection
,
1583 CTDB_NO_MEMORY(ctdb
, tcparray
->connections
);
1585 tcparray
->connections
[tcparray
->num
].src
= p
->src
;
1586 tcparray
->connections
[tcparray
->num
].dst
= p
->dst
;
1589 D_INFO("Added connection %s\n", conn_str
);
1591 if (tcp_update_needed
) {
1592 vnn
->tcp_update_needed
= true;
1599 static void ctdb_remove_connection(struct ctdb_vnn
*vnn
,
1600 struct ctdb_connection
*conn
)
1602 struct ctdb_connection
*tcpp
;
1603 char conn_str
[132] = { 0, };
1610 ret
= ctdb_connection_to_buf(conn_str
,
1616 strlcpy(conn_str
, "UNKNOWN", sizeof(conn_str
));
1619 /* If the array is empty there is nothing to remove */
1620 if (vnn
->tcp_array
== NULL
) {
1621 D_INFO("Attempt to remove untracked connection %s (empty)\n",
1627 tcpp
= ctdb_tcp_find(vnn
->tcp_array
, conn
);
1629 D_DEBUG("Attempt to remove untracked connection %s\n", conn_str
);
1635 * We need to remove this entry from the array. Instead of
1636 * allocating a new array and copying data to it, cheat and
1637 * just copy the last entry in the existing array to the entry
1638 * that is to be removed and just shrink the size.
1640 *tcpp
= vnn
->tcp_array
->connections
[vnn
->tcp_array
->num
- 1];
1641 vnn
->tcp_array
->num
--;
1643 /* Last entry deleted, so remove the entire array */
1644 if (vnn
->tcp_array
->num
== 0) {
1645 talloc_free(vnn
->tcp_array
);
1646 vnn
->tcp_array
= NULL
;
1649 vnn
->tcp_update_needed
= true;
1651 D_INFO("Removed connection %s\n", conn_str
);
1656 called by a daemon to inform us of a TCP connection that one of its
1657 clients used are no longer needed in the tickle database
1659 int32_t ctdb_control_tcp_remove(struct ctdb_context
*ctdb
, TDB_DATA indata
)
1661 struct ctdb_vnn
*vnn
;
1662 struct ctdb_connection
*conn
= (struct ctdb_connection
*)indata
.dptr
;
1664 /* If we don't have public IPs, tickles are useless */
1665 if (ctdb
->vnn
== NULL
) {
1669 vnn
= find_public_ip_vnn(ctdb
, &conn
->dst
);
1671 char conn_str
[132] = { 0, };
1674 ret
= ctdb_connection_to_buf(conn_str
,
1680 strlcpy(conn_str
, "UNKNOWN", sizeof(conn_str
));
1683 DBG_ERR("Attempt to remove connection %s "
1684 "but destination is not a public address\n",
1689 ctdb_remove_connection(vnn
, conn
);
1695 static void ctdb_send_set_tcp_tickles_for_all(struct ctdb_context
*ctdb
,
1699 Called when another daemon starts - causes all tickles for all
1700 public addresses we are serving to be sent to the new node on the
1701 next check. This actually causes the tickles to be sent to the
1702 other node immediately. In case there is an error, the periodic
1703 timer will send the updates on timer event. This is simple and
1704 doesn't require careful error handling.
1706 int32_t ctdb_control_startup(struct ctdb_context
*ctdb
, uint32_t pnn
)
1708 DEBUG(DEBUG_INFO
, ("Received startup control from node %lu\n",
1709 (unsigned long) pnn
));
1711 ctdb_send_set_tcp_tickles_for_all(ctdb
, true);
1717 called when a client structure goes away - hook to remove
1718 elements from the tcp_list in all daemons
1720 void ctdb_takeover_client_destructor_hook(struct ctdb_client
*client
)
1722 while (client
->tcp_list
) {
1723 struct ctdb_vnn
*vnn
;
1724 struct ctdb_tcp_list
*tcp
= client
->tcp_list
;
1725 struct ctdb_connection
*conn
= &tcp
->connection
;
1727 vnn
= find_public_ip_vnn(client
->ctdb
,
1730 /* If the IP address is hosted on this node then
1731 * remove the connection. */
1732 if (vnn
!= NULL
&& vnn
->pnn
== client
->ctdb
->pnn
) {
1733 ctdb_remove_connection(vnn
, conn
);
1736 /* Otherwise this function has been called because the
1737 * server IP address has been released to another node
1738 * and the client has exited. This means that we
1739 * should not delete the connection information. The
1740 * takeover node processes connections too. */
1743 * The destructor removes from the list
1750 void ctdb_release_all_ips(struct ctdb_context
*ctdb
)
1752 struct ctdb_vnn
*vnn
, *next
;
1755 if (ctdb_config
.failover_disabled
== 1) {
1759 for (vnn
= ctdb
->vnn
; vnn
!= NULL
; vnn
= next
) {
1763 /* vnn can be freed below in release_ip_post() */
1766 if (!ctdb_sys_have_ip(&vnn
->public_address
)) {
1767 ctdb_vnn_unassign_iface(ctdb
, vnn
);
1771 /* Don't allow multiple releases at once. Some code,
1772 * particularly ctdb_tickle_sentenced_connections() is
1774 if (vnn
->update_in_flight
) {
1776 "Not releasing IP %s/%u on interface %s, "
1777 "an update is already in progress\n",
1778 ctdb_vnn_address_string(vnn
),
1779 vnn
->public_netmask_bits
,
1780 ctdb_vnn_iface_string(vnn
));
1783 vnn
->update_in_flight
= true;
1785 D_INFO("Release of IP %s/%u on interface %s node:-1\n",
1786 ctdb_vnn_address_string(vnn
),
1787 vnn
->public_netmask_bits
,
1788 ctdb_vnn_iface_string(vnn
));
1791 * releaseip timeouts are converted to success, or IP
1792 * might be released but releaseip event failed (due
1793 * to failure of script after 10.interface), so try
1794 * hard to correctly report failures...
1796 ret
= ctdb_event_script_args(
1798 CTDB_EVENT_RELEASE_IP
,
1800 ctdb_vnn_iface_string(vnn
),
1801 ctdb_vnn_address_string(vnn
),
1802 vnn
->public_netmask_bits
);
1803 have_ip
= ctdb_sys_have_ip(&vnn
->public_address
);
1806 DBG_ERR("Error releasing IP %s\n",
1807 ctdb_vnn_address_string(vnn
));
1809 DBG_ERR("IP %s not released (timed out?)\n",
1810 ctdb_vnn_address_string(vnn
));
1812 vnn
->update_in_flight
= false;
1816 DBG_ERR("Error releasing IP %s (but IP is gone!)\n",
1817 ctdb_vnn_address_string(vnn
));
1818 vnn
->update_in_flight
= false;
1822 vnn
= release_ip_post(ctdb
, vnn
, &vnn
->public_address
);
1824 vnn
->update_in_flight
= false;
1829 DEBUG(DEBUG_NOTICE
,(__location__
" Released %d public IPs\n", count
));
1834 get list of public IPs
1836 int32_t ctdb_control_get_public_ips(struct ctdb_context
*ctdb
,
1837 struct ctdb_req_control_old
*c
, TDB_DATA
*outdata
)
1840 struct ctdb_public_ip_list_old
*ips
;
1841 struct ctdb_vnn
*vnn
;
1842 bool only_available
= false;
1844 if (c
->flags
& CTDB_PUBLIC_IP_FLAGS_ONLY_AVAILABLE
) {
1845 only_available
= true;
1848 /* count how many public ip structures we have */
1850 for (vnn
=ctdb
->vnn
;vnn
;vnn
=vnn
->next
) {
1854 len
= offsetof(struct ctdb_public_ip_list_old
, ips
) +
1855 num
*sizeof(struct ctdb_public_ip
);
1856 ips
= talloc_zero_size(outdata
, len
);
1857 CTDB_NO_MEMORY(ctdb
, ips
);
1860 for (vnn
=ctdb
->vnn
;vnn
;vnn
=vnn
->next
) {
1861 if (only_available
&& !ctdb_vnn_available(ctdb
, vnn
)) {
1864 ips
->ips
[i
].pnn
= vnn
->pnn
;
1865 ips
->ips
[i
].addr
= vnn
->public_address
;
1869 len
= offsetof(struct ctdb_public_ip_list_old
, ips
) +
1870 i
*sizeof(struct ctdb_public_ip
);
1872 outdata
->dsize
= len
;
1873 outdata
->dptr
= (uint8_t *)ips
;
1879 int32_t ctdb_control_get_public_ip_info(struct ctdb_context
*ctdb
,
1880 struct ctdb_req_control_old
*c
,
1885 ctdb_sock_addr
*addr
;
1886 struct ctdb_public_ip_info_old
*info
;
1887 struct ctdb_vnn
*vnn
;
1888 struct vnn_interface
*iface
;
1890 addr
= (ctdb_sock_addr
*)indata
.dptr
;
1892 vnn
= find_public_ip_vnn(ctdb
, addr
);
1894 DEBUG(DEBUG_ERR
,(__location__
" Could not get public ip info, "
1895 "'%s'not a public address\n",
1896 ctdb_addr_to_str(addr
)));
1900 /* count how many public ip structures we have */
1902 for (iface
= vnn
->ifaces
; iface
!= NULL
; iface
= iface
->next
) {
1906 len
= offsetof(struct ctdb_public_ip_info_old
, ifaces
) +
1907 num
*sizeof(struct ctdb_iface
);
1908 info
= talloc_zero_size(outdata
, len
);
1909 CTDB_NO_MEMORY(ctdb
, info
);
1911 info
->ip
.addr
= vnn
->public_address
;
1912 info
->ip
.pnn
= vnn
->pnn
;
1913 info
->active_idx
= 0xFFFFFFFF;
1916 for (iface
= vnn
->ifaces
; iface
!= NULL
; iface
= iface
->next
) {
1917 struct ctdb_interface
*cur
;
1920 if (vnn
->iface
== cur
) {
1921 info
->active_idx
= i
;
1923 strncpy(info
->ifaces
[i
].name
, cur
->name
,
1924 sizeof(info
->ifaces
[i
].name
));
1925 info
->ifaces
[i
].name
[sizeof(info
->ifaces
[i
].name
)-1] = '\0';
1926 info
->ifaces
[i
].link_state
= cur
->link_up
;
1927 info
->ifaces
[i
].references
= cur
->references
;
1932 len
= offsetof(struct ctdb_public_ip_info_old
, ifaces
) +
1933 i
*sizeof(struct ctdb_iface
);
1935 outdata
->dsize
= len
;
1936 outdata
->dptr
= (uint8_t *)info
;
1941 int32_t ctdb_control_get_ifaces(struct ctdb_context
*ctdb
,
1942 struct ctdb_req_control_old
*c
,
1946 struct ctdb_iface_list_old
*ifaces
;
1947 struct ctdb_interface
*cur
;
1949 /* count how many public ip structures we have */
1951 for (cur
=ctdb
->ifaces
;cur
;cur
=cur
->next
) {
1955 len
= offsetof(struct ctdb_iface_list_old
, ifaces
) +
1956 num
*sizeof(struct ctdb_iface
);
1957 ifaces
= talloc_zero_size(outdata
, len
);
1958 CTDB_NO_MEMORY(ctdb
, ifaces
);
1961 for (cur
=ctdb
->ifaces
;cur
;cur
=cur
->next
) {
1962 strncpy(ifaces
->ifaces
[i
].name
, cur
->name
,
1963 sizeof(ifaces
->ifaces
[i
].name
));
1964 ifaces
->ifaces
[i
].name
[sizeof(ifaces
->ifaces
[i
].name
)-1] = '\0';
1965 ifaces
->ifaces
[i
].link_state
= cur
->link_up
;
1966 ifaces
->ifaces
[i
].references
= cur
->references
;
1970 len
= offsetof(struct ctdb_iface_list_old
, ifaces
) +
1971 i
*sizeof(struct ctdb_iface
);
1973 outdata
->dsize
= len
;
1974 outdata
->dptr
= (uint8_t *)ifaces
;
1979 int32_t ctdb_control_set_iface_link(struct ctdb_context
*ctdb
,
1980 struct ctdb_req_control_old
*c
,
1983 struct ctdb_iface
*info
;
1984 struct ctdb_interface
*iface
;
1985 bool link_up
= false;
1987 info
= (struct ctdb_iface
*)indata
.dptr
;
1989 if (info
->name
[CTDB_IFACE_SIZE
] != '\0') {
1990 int len
= strnlen(info
->name
, CTDB_IFACE_SIZE
);
1991 DEBUG(DEBUG_ERR
, (__location__
" name[%*.*s] not terminated\n",
1992 len
, len
, info
->name
));
1996 switch (info
->link_state
) {
2004 DEBUG(DEBUG_ERR
, (__location__
" link_state[%u] invalid\n",
2005 (unsigned int)info
->link_state
));
2009 if (info
->references
!= 0) {
2010 DEBUG(DEBUG_ERR
, (__location__
" references[%u] should be 0\n",
2011 (unsigned int)info
->references
));
2015 iface
= ctdb_find_iface(ctdb
, info
->name
);
2016 if (iface
== NULL
) {
2020 if (link_up
== iface
->link_up
) {
2025 ("iface[%s] has changed it's link status %s => %s\n",
2027 iface
->link_up
?"up":"down",
2028 link_up
?"up":"down"));
2030 iface
->link_up
= link_up
;
2036 called by a daemon to inform us of the entire list of TCP tickles for
2037 a particular public address.
2038 this control should only be sent by the node that is currently serving
2039 that public address.
2041 int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context
*ctdb
, TDB_DATA indata
)
2043 struct ctdb_tickle_list_old
*list
= (struct ctdb_tickle_list_old
*)indata
.dptr
;
2044 struct ctdb_tcp_array
*tcparray
;
2045 struct ctdb_vnn
*vnn
;
2047 /* We must at least have tickles.num or else we can't verify the size
2048 of the received data blob
2050 if (indata
.dsize
< offsetof(struct ctdb_tickle_list_old
, connections
)) {
2051 DEBUG(DEBUG_ERR
,("Bad indata in ctdb_tickle_list. Not enough data for the tickle.num field\n"));
2055 /* verify that the size of data matches what we expect */
2056 if (indata
.dsize
< offsetof(struct ctdb_tickle_list_old
, connections
)
2057 + sizeof(struct ctdb_connection
) * list
->num
) {
2058 DEBUG(DEBUG_ERR
,("Bad indata in ctdb_tickle_list\n"));
2062 DEBUG(DEBUG_INFO
, ("Received tickle update for public address %s\n",
2063 ctdb_addr_to_str(&list
->addr
)));
2065 vnn
= find_public_ip_vnn(ctdb
, &list
->addr
);
2067 DEBUG(DEBUG_INFO
,(__location__
" Could not set tcp tickle list, '%s' is not a public address\n",
2068 ctdb_addr_to_str(&list
->addr
)));
2073 if (vnn
->pnn
== ctdb
->pnn
) {
2075 ("Ignoring redundant set tcp tickle list, this node hosts '%s'\n",
2076 ctdb_addr_to_str(&list
->addr
)));
2080 /* remove any old ticklelist we might have */
2081 talloc_free(vnn
->tcp_array
);
2082 vnn
->tcp_array
= NULL
;
2084 tcparray
= talloc(vnn
, struct ctdb_tcp_array
);
2085 CTDB_NO_MEMORY(ctdb
, tcparray
);
2087 tcparray
->num
= list
->num
;
2089 tcparray
->connections
= talloc_array(tcparray
, struct ctdb_connection
, tcparray
->num
);
2090 CTDB_NO_MEMORY(ctdb
, tcparray
->connections
);
2092 memcpy(tcparray
->connections
, &list
->connections
[0],
2093 sizeof(struct ctdb_connection
)*tcparray
->num
);
2095 /* We now have a new fresh tickle list array for this vnn */
2096 vnn
->tcp_array
= tcparray
;
2102 called to return the full list of tickles for the puclic address associated
2103 with the provided vnn
2105 int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context
*ctdb
, TDB_DATA indata
, TDB_DATA
*outdata
)
2107 ctdb_sock_addr
*addr
= (ctdb_sock_addr
*)indata
.dptr
;
2108 struct ctdb_tickle_list_old
*list
;
2109 struct ctdb_tcp_array
*tcparray
;
2110 unsigned int num
, i
;
2111 struct ctdb_vnn
*vnn
;
2114 vnn
= find_public_ip_vnn(ctdb
, addr
);
2116 DEBUG(DEBUG_ERR
,(__location__
" Could not get tcp tickle list, '%s' is not a public address\n",
2117 ctdb_addr_to_str(addr
)));
2122 port
= ctdb_addr_to_port(addr
);
2124 tcparray
= vnn
->tcp_array
;
2126 if (tcparray
!= NULL
) {
2128 /* All connections */
2129 num
= tcparray
->num
;
2131 /* Count connections for port */
2132 for (i
= 0; i
< tcparray
->num
; i
++) {
2133 if (port
== ctdb_addr_to_port(&tcparray
->connections
[i
].dst
)) {
2140 outdata
->dsize
= offsetof(struct ctdb_tickle_list_old
, connections
)
2141 + sizeof(struct ctdb_connection
) * num
;
2143 outdata
->dptr
= talloc_size(outdata
, outdata
->dsize
);
2144 CTDB_NO_MEMORY(ctdb
, outdata
->dptr
);
2145 list
= (struct ctdb_tickle_list_old
*)outdata
->dptr
;
2155 for (i
= 0; i
< tcparray
->num
; i
++) {
2157 port
== ctdb_addr_to_port(&tcparray
->connections
[i
].dst
)) {
2158 list
->connections
[num
] = tcparray
->connections
[i
];
2168 set the list of all tcp tickles for a public address
2170 static int ctdb_send_set_tcp_tickles_for_ip(struct ctdb_context
*ctdb
,
2171 ctdb_sock_addr
*addr
,
2172 struct ctdb_tcp_array
*tcparray
)
2176 struct ctdb_tickle_list_old
*list
;
2179 num
= tcparray
->num
;
2184 data
.dsize
= offsetof(struct ctdb_tickle_list_old
, connections
) +
2185 sizeof(struct ctdb_connection
) * num
;
2186 data
.dptr
= talloc_size(ctdb
, data
.dsize
);
2187 CTDB_NO_MEMORY(ctdb
, data
.dptr
);
2189 list
= (struct ctdb_tickle_list_old
*)data
.dptr
;
2193 memcpy(&list
->connections
[0], tcparray
->connections
, sizeof(struct ctdb_connection
) * num
);
2196 ret
= ctdb_daemon_send_control(ctdb
, CTDB_BROADCAST_ALL
, 0,
2197 CTDB_CONTROL_SET_TCP_TICKLE_LIST
,
2198 0, CTDB_CTRL_FLAG_NOREPLY
, data
, NULL
, NULL
);
2200 DEBUG(DEBUG_ERR
,(__location__
" ctdb_control for set tcp tickles failed\n"));
2204 talloc_free(data
.dptr
);
2209 static void ctdb_send_set_tcp_tickles_for_all(struct ctdb_context
*ctdb
,
2212 struct ctdb_vnn
*vnn
;
2215 for (vnn
= ctdb
->vnn
; vnn
!= NULL
; vnn
= vnn
->next
) {
2216 /* we only send out updates for public addresses that
2219 if (ctdb
->pnn
!= vnn
->pnn
) {
2223 /* We only send out the updates if we need to */
2224 if (!force
&& !vnn
->tcp_update_needed
) {
2228 ret
= ctdb_send_set_tcp_tickles_for_ip(ctdb
,
2229 &vnn
->public_address
,
2232 D_ERR("Failed to send the tickle update for ip %s\n",
2233 ctdb_vnn_address_string(vnn
));
2234 vnn
->tcp_update_needed
= true;
2236 D_INFO("Sent tickle update for ip %s\n",
2237 ctdb_vnn_address_string(vnn
));
2238 vnn
->tcp_update_needed
= false;
2245 perform tickle updates if required
2247 static void ctdb_update_tcp_tickles(struct tevent_context
*ev
,
2248 struct tevent_timer
*te
,
2249 struct timeval t
, void *private_data
)
2251 struct ctdb_context
*ctdb
= talloc_get_type(
2252 private_data
, struct ctdb_context
);
2254 ctdb_send_set_tcp_tickles_for_all(ctdb
, false);
2256 tevent_add_timer(ctdb
->ev
, ctdb
->tickle_update_context
,
2257 timeval_current_ofs(ctdb
->tunable
.tickle_update_interval
, 0),
2258 ctdb_update_tcp_tickles
, ctdb
);
2262 start periodic update of tcp tickles
2264 void ctdb_start_tcp_tickle_update(struct ctdb_context
*ctdb
)
2266 ctdb
->tickle_update_context
= talloc_new(ctdb
);
2268 tevent_add_timer(ctdb
->ev
, ctdb
->tickle_update_context
,
2269 timeval_current_ofs(ctdb
->tunable
.tickle_update_interval
, 0),
2270 ctdb_update_tcp_tickles
, ctdb
);
2276 struct control_gratious_arp
{
2277 struct ctdb_context
*ctdb
;
2278 ctdb_sock_addr addr
;
2284 send a control_gratuitous arp
2286 static void send_gratious_arp(struct tevent_context
*ev
,
2287 struct tevent_timer
*te
,
2288 struct timeval t
, void *private_data
)
2291 struct control_gratious_arp
*arp
= talloc_get_type(private_data
,
2292 struct control_gratious_arp
);
2294 ret
= ctdb_sys_send_arp(&arp
->addr
, arp
->iface
);
2296 DBG_ERR("Failed to send gratuitous ARP on iface %s: %s\n",
2297 arp
->iface
, strerror(ret
));
2302 if (arp
->count
== CTDB_ARP_REPEAT
) {
2307 tevent_add_timer(arp
->ctdb
->ev
, arp
,
2308 timeval_current_ofs(CTDB_ARP_INTERVAL
, 0),
2309 send_gratious_arp
, arp
);
2316 int32_t ctdb_control_send_gratious_arp(struct ctdb_context
*ctdb
, TDB_DATA indata
)
2318 struct ctdb_addr_info_old
*gratious_arp
= (struct ctdb_addr_info_old
*)indata
.dptr
;
2319 struct control_gratious_arp
*arp
;
2321 /* verify the size of indata */
2322 if (indata
.dsize
< offsetof(struct ctdb_addr_info_old
, iface
)) {
2323 DEBUG(DEBUG_ERR
,(__location__
" Too small indata to hold a ctdb_control_gratious_arp structure. Got %u require %u bytes\n",
2324 (unsigned)indata
.dsize
,
2325 (unsigned)offsetof(struct ctdb_addr_info_old
, iface
)));
2329 ( offsetof(struct ctdb_addr_info_old
, iface
)
2330 + gratious_arp
->len
) ){
2332 DEBUG(DEBUG_ERR
,(__location__
" Wrong size of indata. Was %u bytes "
2333 "but should be %u bytes\n",
2334 (unsigned)indata
.dsize
,
2335 (unsigned)(offsetof(struct ctdb_addr_info_old
, iface
)+gratious_arp
->len
)));
2340 arp
= talloc(ctdb
, struct control_gratious_arp
);
2341 CTDB_NO_MEMORY(ctdb
, arp
);
2344 arp
->addr
= gratious_arp
->addr
;
2345 arp
->iface
= talloc_strdup(arp
, gratious_arp
->iface
);
2346 CTDB_NO_MEMORY(ctdb
, arp
->iface
);
2349 tevent_add_timer(arp
->ctdb
->ev
, arp
,
2350 timeval_zero(), send_gratious_arp
, arp
);
2355 int32_t ctdb_control_add_public_address(struct ctdb_context
*ctdb
, TDB_DATA indata
)
2357 struct ctdb_addr_info_old
*pub
= (struct ctdb_addr_info_old
*)indata
.dptr
;
2360 /* verify the size of indata */
2361 if (indata
.dsize
< offsetof(struct ctdb_addr_info_old
, iface
)) {
2362 DEBUG(DEBUG_ERR
,(__location__
" Too small indata to hold a ctdb_addr_info structure\n"));
2366 ( offsetof(struct ctdb_addr_info_old
, iface
)
2369 DEBUG(DEBUG_ERR
,(__location__
" Wrong size of indata. Was %u bytes "
2370 "but should be %u bytes\n",
2371 (unsigned)indata
.dsize
,
2372 (unsigned)(offsetof(struct ctdb_addr_info_old
, iface
)+pub
->len
)));
2376 DEBUG(DEBUG_NOTICE
,("Add IP %s\n", ctdb_addr_to_str(&pub
->addr
)));
2378 ret
= ctdb_add_public_address(ctdb
, &pub
->addr
, pub
->mask
, &pub
->iface
[0]);
2381 DEBUG(DEBUG_ERR
,(__location__
" Failed to add public address\n"));
2388 int32_t ctdb_control_del_public_address(struct ctdb_context
*ctdb
, TDB_DATA indata
)
2390 struct ctdb_addr_info_old
*pub
= (struct ctdb_addr_info_old
*)indata
.dptr
;
2391 struct ctdb_vnn
*vnn
;
2393 /* verify the size of indata */
2394 if (indata
.dsize
< offsetof(struct ctdb_addr_info_old
, iface
)) {
2395 DEBUG(DEBUG_ERR
,(__location__
" Too small indata to hold a ctdb_addr_info structure\n"));
2399 ( offsetof(struct ctdb_addr_info_old
, iface
)
2402 DEBUG(DEBUG_ERR
,(__location__
" Wrong size of indata. Was %u bytes "
2403 "but should be %u bytes\n",
2404 (unsigned)indata
.dsize
,
2405 (unsigned)(offsetof(struct ctdb_addr_info_old
, iface
)+pub
->len
)));
2409 DEBUG(DEBUG_NOTICE
,("Delete IP %s\n", ctdb_addr_to_str(&pub
->addr
)));
2411 vnn
= find_public_ip_vnn(ctdb
, &pub
->addr
);
2413 D_ERR("Delete IP of unknown public IP address %s\n",
2414 ctdb_addr_to_str(&pub
->addr
));
2418 if (vnn
->pnn
== ctdb
->pnn
) {
2420 * This IP is currently being hosted. Defer the
2421 * deletion until the next takeover run. "ctdb
2422 * reloadips" will always cause a takeover run. "ctdb
2423 * delip" will now need an explicit "ctdb
2424 * ipreallocated" afterwards.
2426 vnn
->delete_pending
= true;
2429 * This IP is not hosted on the current node so just
2432 do_delete_ip(ctdb
, vnn
);
2439 struct ipreallocated_callback_state
{
2440 struct ctdb_req_control_old
*c
;
2443 static void ctdb_ipreallocated_callback(struct ctdb_context
*ctdb
,
2444 int status
, void *p
)
2446 struct ipreallocated_callback_state
*state
=
2447 talloc_get_type(p
, struct ipreallocated_callback_state
);
2448 TDB_DATA data
= { .dsize
= 0, };
2452 (" \"ipreallocated\" event script failed (status %d)\n",
2454 if (status
== -ETIMEDOUT
) {
2455 ctdb_ban_self(ctdb
);
2459 D_INFO("Sending IPREALLOCATED message\n");
2460 ctdb_daemon_send_message(ctdb
, ctdb
->pnn
, CTDB_SRVID_IPREALLOCATED
, data
);
2462 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, status
, NULL
);
2466 /* A control to run the ipreallocated event */
2467 int32_t ctdb_control_ipreallocated(struct ctdb_context
*ctdb
,
2468 struct ctdb_req_control_old
*c
,
2472 struct ipreallocated_callback_state
*state
;
2474 state
= talloc(ctdb
, struct ipreallocated_callback_state
);
2475 CTDB_NO_MEMORY(ctdb
, state
);
2477 DEBUG(DEBUG_INFO
,(__location__
" Running \"ipreallocated\" event\n"));
2479 ret
= ctdb_event_script_callback(ctdb
, state
,
2480 ctdb_ipreallocated_callback
, state
,
2481 CTDB_EVENT_IPREALLOCATED
,
2485 DEBUG(DEBUG_ERR
,("Failed to run \"ipreallocated\" event \n"));
2490 /* tell the control that we will be reply asynchronously */
2491 state
->c
= talloc_steal(state
, c
);
2492 *async_reply
= true;
2498 struct start_ipreallocate_callback_state
{
2499 struct ctdb_req_control_old
*c
;
2502 static void ctdb_start_ipreallocate_callback(struct ctdb_context
*ctdb
,
2503 int status
, void *p
)
2505 struct start_ipreallocate_callback_state
*state
= talloc_get_type_abort(
2506 p
, struct start_ipreallocate_callback_state
);
2507 TDB_DATA data
= { .dsize
= 0, };
2510 D_ERR("\"startipreallocate\" event failed (status %d)\n",
2512 if (status
== -ETIMEDOUT
) {
2513 ctdb_ban_self(ctdb
);
2517 D_INFO("Sending START_IPREALLOCATE message\n");
2518 ctdb_daemon_send_message(ctdb
,
2520 CTDB_SRVID_START_IPREALLOCATE
,
2523 ctdb_request_control_reply(ctdb
, state
->c
, NULL
, status
, NULL
);
2527 /* A control to run the startipreallocate event */
2528 int32_t ctdb_control_start_ipreallocate(struct ctdb_context
*ctdb
,
2529 struct ctdb_req_control_old
*c
,
2533 struct start_ipreallocate_callback_state
*state
;
2535 /* Nodes that are not RUNNING can not host IPs */
2536 if (ctdb
->runstate
!= CTDB_RUNSTATE_RUNNING
) {
2537 DBG_INFO("Skipping \"startipreallocate\" event, not RUNNING\n");
2541 state
= talloc(ctdb
, struct start_ipreallocate_callback_state
);
2542 if (state
== NULL
) {
2543 DBG_ERR("Memory allocation error\n");
2547 DBG_INFO("Running \"startipreallocate\" event\n");
2549 ret
= ctdb_event_script_callback(ctdb
,
2551 ctdb_start_ipreallocate_callback
,
2553 CTDB_EVENT_START_IPREALLOCATE
,
2558 D_ERR("Failed to run \"startipreallocate\" event \n");
2563 /* tell the control that we will be reply asynchronously */
2564 state
->c
= talloc_steal(state
, c
);
2565 *async_reply
= true;
2571 struct ctdb_reloadips_handle
{
2572 struct ctdb_context
*ctdb
;
2573 struct ctdb_req_control_old
*c
;
2577 struct tevent_fd
*fde
;
2580 static int ctdb_reloadips_destructor(struct ctdb_reloadips_handle
*h
)
2582 if (h
== h
->ctdb
->reload_ips
) {
2583 h
->ctdb
->reload_ips
= NULL
;
2586 ctdb_request_control_reply(h
->ctdb
, h
->c
, NULL
, h
->status
, NULL
);
2589 ctdb_kill(h
->ctdb
, h
->child
, SIGKILL
);
2593 static void ctdb_reloadips_timeout_event(struct tevent_context
*ev
,
2594 struct tevent_timer
*te
,
2595 struct timeval t
, void *private_data
)
2597 struct ctdb_reloadips_handle
*h
= talloc_get_type(private_data
, struct ctdb_reloadips_handle
);
2602 static void ctdb_reloadips_child_handler(struct tevent_context
*ev
,
2603 struct tevent_fd
*fde
,
2604 uint16_t flags
, void *private_data
)
2606 struct ctdb_reloadips_handle
*h
= talloc_get_type(private_data
, struct ctdb_reloadips_handle
);
2611 ret
= sys_read(h
->fd
[0], &res
, 1);
2612 if (ret
< 1 || res
!= 0) {
2613 DEBUG(DEBUG_ERR
, (__location__
" Reloadips child process returned error\n"));
2621 static int ctdb_reloadips_child(struct ctdb_context
*ctdb
)
2623 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
2624 struct ctdb_public_ip_list_old
*ips
;
2625 struct ctdb_vnn
*vnn
;
2626 struct client_async_data
*async_data
;
2627 struct timeval timeout
;
2629 struct ctdb_client_control_state
*state
;
2634 CTDB_NO_MEMORY(ctdb
, mem_ctx
);
2636 /* Read IPs from local node */
2637 ret
= ctdb_ctrl_get_public_ips(ctdb
, TAKEOVER_TIMEOUT(),
2638 CTDB_CURRENT_NODE
, mem_ctx
, &ips
);
2641 ("Unable to fetch public IPs from local node\n"));
2642 talloc_free(mem_ctx
);
2646 /* Read IPs file - this is safe since this is a child process */
2648 if (ctdb_set_public_addresses(ctdb
) != 0) {
2649 DEBUG(DEBUG_ERR
,("Failed to re-read public addresses file\n"));
2650 talloc_free(mem_ctx
);
2654 async_data
= talloc_zero(mem_ctx
, struct client_async_data
);
2655 CTDB_NO_MEMORY(ctdb
, async_data
);
2657 /* Compare IPs between node and file for IPs to be deleted */
2658 for (i
= 0; i
< ips
->num
; i
++) {
2659 struct ctdb_addr_info_old
*pub
= NULL
;
2661 vnn
= find_public_ip_vnn(ctdb
, &ips
->ips
[i
].addr
);
2663 /* IP is still in file */
2668 * Delete IP ips->ips[i]
2671 D_NOTICE("IP %s no longer configured, deleting it\n",
2672 ctdb_addr_to_str(&ips
->ips
[i
].addr
));
2674 pub
= talloc_zero(mem_ctx
, struct ctdb_addr_info_old
);
2675 CTDB_NO_MEMORY(ctdb
, pub
);
2677 pub
->addr
= ips
->ips
[i
].addr
;
2681 timeout
= TAKEOVER_TIMEOUT();
2683 data
.dsize
= offsetof(struct ctdb_addr_info_old
,
2685 data
.dptr
= (uint8_t *)pub
;
2687 state
= ctdb_control_send(ctdb
, CTDB_CURRENT_NODE
, 0,
2688 CTDB_CONTROL_DEL_PUBLIC_IP
,
2689 0, data
, async_data
,
2691 if (state
== NULL
) {
2692 DBG_ERR("Failed sending CTDB_CONTROL_DEL_PUBLIC_IP\n");
2696 ctdb_client_async_add(async_data
, state
);
2699 /* Compare IPs between node and file for IPs to be added */
2701 for (vnn
= ctdb
->vnn
; vnn
; vnn
= vnn
->next
) {
2702 for (i
= 0; i
< ips
->num
; i
++) {
2703 if (ctdb_same_ip(&vnn
->public_address
,
2704 &ips
->ips
[i
].addr
)) {
2705 /* IP already on node */
2709 if (i
== ips
->num
) {
2710 /* Add IP ips->ips[i] */
2711 struct ctdb_addr_info_old
*pub
;
2712 const char *ifaces
= NULL
;
2714 struct vnn_interface
*iface
= NULL
;
2716 D_NOTICE("New IP %s configured, adding it\n",
2717 ctdb_vnn_address_string(vnn
));
2719 uint32_t pnn
= ctdb_get_pnn(ctdb
);
2721 data
.dsize
= sizeof(pnn
);
2722 data
.dptr
= (uint8_t *)&pnn
;
2724 ret
= ctdb_client_send_message(
2726 CTDB_BROADCAST_CONNECTED
,
2727 CTDB_SRVID_REBALANCE_NODE
,
2730 DEBUG(DEBUG_WARNING
,
2731 ("Failed to send message to force node reallocation - IPs may be unbalanced\n"));
2737 ifaces
= vnn
->ifaces
->iface
->name
;
2738 iface
= vnn
->ifaces
->next
;
2739 while (iface
!= NULL
) {
2740 ifaces
= talloc_asprintf(vnn
, "%s,%s", ifaces
,
2741 iface
->iface
->name
);
2742 iface
= iface
->next
;
2745 len
= strlen(ifaces
) + 1;
2746 pub
= talloc_zero_size(mem_ctx
,
2747 offsetof(struct ctdb_addr_info_old
, iface
) + len
);
2748 CTDB_NO_MEMORY(ctdb
, pub
);
2750 pub
->addr
= vnn
->public_address
;
2751 pub
->mask
= vnn
->public_netmask_bits
;
2753 memcpy(&pub
->iface
[0], ifaces
, pub
->len
);
2755 timeout
= TAKEOVER_TIMEOUT();
2757 data
.dsize
= offsetof(struct ctdb_addr_info_old
,
2759 data
.dptr
= (uint8_t *)pub
;
2761 state
= ctdb_control_send(ctdb
, CTDB_CURRENT_NODE
, 0,
2762 CTDB_CONTROL_ADD_PUBLIC_IP
,
2763 0, data
, async_data
,
2765 if (state
== NULL
) {
2768 " failed sending CTDB_CONTROL_ADD_PUBLIC_IP\n"));
2772 ctdb_client_async_add(async_data
, state
);
2776 if (ctdb_client_async_wait(ctdb
, async_data
) != 0) {
2777 DEBUG(DEBUG_ERR
,(__location__
" Add/delete IPs failed\n"));
2781 talloc_free(mem_ctx
);
2785 talloc_free(mem_ctx
);
2789 /* This control is sent to force the node to re-read the public addresses file
2790 and drop any addresses we should nnot longer host, and add new addresses
2791 that we are now able to host
2793 int32_t ctdb_control_reload_public_ips(struct ctdb_context
*ctdb
, struct ctdb_req_control_old
*c
, bool *async_reply
)
2795 struct ctdb_reloadips_handle
*h
;
2796 pid_t parent
= getpid();
2798 if (ctdb
->reload_ips
!= NULL
) {
2799 talloc_free(ctdb
->reload_ips
);
2800 ctdb
->reload_ips
= NULL
;
2803 h
= talloc(ctdb
, struct ctdb_reloadips_handle
);
2804 CTDB_NO_MEMORY(ctdb
, h
);
2809 if (pipe(h
->fd
) == -1) {
2810 DEBUG(DEBUG_ERR
,("Failed to create pipe for ctdb_freeze_lock\n"));
2815 h
->child
= ctdb_fork(ctdb
);
2816 if (h
->child
== (pid_t
)-1) {
2817 DEBUG(DEBUG_ERR
, ("Failed to fork a child for reloadips\n"));
2825 if (h
->child
== 0) {
2826 signed char res
= 0;
2830 prctl_set_comment("ctdb_reloadips");
2831 if (switch_from_server_to_client(ctdb
) != 0) {
2832 DEBUG(DEBUG_CRIT
,("ERROR: Failed to switch reloadips child into client mode\n"));
2835 res
= ctdb_reloadips_child(ctdb
);
2837 DEBUG(DEBUG_ERR
,("Failed to reload ips on local node\n"));
2841 sys_write(h
->fd
[1], &res
, 1);
2842 ctdb_wait_for_process_to_exit(parent
);
2846 h
->c
= talloc_steal(h
, c
);
2849 set_close_on_exec(h
->fd
[0]);
2851 talloc_set_destructor(h
, ctdb_reloadips_destructor
);
2854 h
->fde
= tevent_add_fd(ctdb
->ev
, h
, h
->fd
[0], TEVENT_FD_READ
,
2855 ctdb_reloadips_child_handler
, (void *)h
);
2856 tevent_fd_set_auto_close(h
->fde
);
2858 tevent_add_timer(ctdb
->ev
, h
, timeval_current_ofs(120, 0),
2859 ctdb_reloadips_timeout_event
, h
);
2861 /* we reply later */
2862 *async_reply
= true;