4 Copyright (C) Ronnie Sahlberg 2007
5 Copyright (C) Andrew Tridgell 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "lib/events/events.h"
22 #include "lib/tdb/include/tdb.h"
23 #include "lib/util/dlinklist.h"
24 #include "system/network.h"
25 #include "system/filesys.h"
26 #include "system/wait.h"
27 #include "../include/ctdb_private.h"
28 #include "../common/rb_tree.h"
31 #define TAKEOVER_TIMEOUT() timeval_current_ofs(ctdb->tunable.takeover_timeout,0)
33 #define CTDB_ARP_INTERVAL 1
34 #define CTDB_ARP_REPEAT 3
37 struct ctdb_iface *prev, *next;
43 static const char *ctdb_vnn_iface_string(const struct ctdb_vnn *vnn)
46 return vnn->iface->name;
52 static int ctdb_add_local_iface(struct ctdb_context *ctdb, const char *iface)
56 /* Verify that we dont have an entry for this ip yet */
57 for (i=ctdb->ifaces;i;i=i->next) {
58 if (strcmp(i->name, iface) == 0) {
63 /* create a new structure for this interface */
64 i = talloc_zero(ctdb, struct ctdb_iface);
65 CTDB_NO_MEMORY_FATAL(ctdb, i);
66 i->name = talloc_strdup(i, iface);
67 CTDB_NO_MEMORY(ctdb, i->name);
70 DLIST_ADD(ctdb->ifaces, i);
75 static struct ctdb_iface *ctdb_find_iface(struct ctdb_context *ctdb,
80 /* Verify that we dont have an entry for this ip yet */
81 for (i=ctdb->ifaces;i;i=i->next) {
82 if (strcmp(i->name, iface) == 0) {
90 static struct ctdb_iface *ctdb_vnn_best_iface(struct ctdb_context *ctdb,
94 struct ctdb_iface *cur = NULL;
95 struct ctdb_iface *best = NULL;
97 for (i=0; vnn->ifaces[i]; i++) {
99 cur = ctdb_find_iface(ctdb, vnn->ifaces[i]);
113 if (cur->references < best->references) {
122 static int32_t ctdb_vnn_assign_iface(struct ctdb_context *ctdb,
123 struct ctdb_vnn *vnn)
125 struct ctdb_iface *best = NULL;
128 DEBUG(DEBUG_INFO, (__location__ " public address '%s' "
129 "still assigned to iface '%s'\n",
130 ctdb_addr_to_str(&vnn->public_address),
131 ctdb_vnn_iface_string(vnn)));
135 best = ctdb_vnn_best_iface(ctdb, vnn);
137 DEBUG(DEBUG_ERR, (__location__ " public address '%s' "
138 "cannot assign to iface any iface\n",
139 ctdb_addr_to_str(&vnn->public_address)));
145 vnn->pnn = ctdb->pnn;
147 DEBUG(DEBUG_INFO, (__location__ " public address '%s' "
148 "now assigned to iface '%s' refs[%d]\n",
149 ctdb_addr_to_str(&vnn->public_address),
150 ctdb_vnn_iface_string(vnn),
155 static void ctdb_vnn_unassign_iface(struct ctdb_context *ctdb,
156 struct ctdb_vnn *vnn)
158 DEBUG(DEBUG_INFO, (__location__ " public address '%s' "
159 "now unassigned (old iface '%s' refs[%d])\n",
160 ctdb_addr_to_str(&vnn->public_address),
161 ctdb_vnn_iface_string(vnn),
162 vnn->iface?vnn->iface->references:0));
164 vnn->iface->references--;
167 if (vnn->pnn == ctdb->pnn) {
172 static bool ctdb_vnn_available(struct ctdb_context *ctdb,
173 struct ctdb_vnn *vnn)
177 if (vnn->iface && vnn->iface->link_up) {
181 for (i=0; vnn->ifaces[i]; i++) {
182 struct ctdb_iface *cur;
184 cur = ctdb_find_iface(ctdb, vnn->ifaces[i]);
197 struct ctdb_takeover_arp {
198 struct ctdb_context *ctdb;
201 struct ctdb_tcp_array *tcparray;
202 struct ctdb_vnn *vnn;
207 lists of tcp endpoints
209 struct ctdb_tcp_list {
210 struct ctdb_tcp_list *prev, *next;
211 struct ctdb_tcp_connection connection;
215 list of clients to kill on IP release
217 struct ctdb_client_ip {
218 struct ctdb_client_ip *prev, *next;
219 struct ctdb_context *ctdb;
226 send a gratuitous arp
228 static void ctdb_control_send_arp(struct event_context *ev, struct timed_event *te,
229 struct timeval t, void *private_data)
231 struct ctdb_takeover_arp *arp = talloc_get_type(private_data,
232 struct ctdb_takeover_arp);
234 struct ctdb_tcp_array *tcparray;
235 const char *iface = ctdb_vnn_iface_string(arp->vnn);
237 ret = ctdb_sys_send_arp(&arp->addr, iface);
239 DEBUG(DEBUG_CRIT,(__location__ " sending of arp failed on iface '%s' (%s)\n",
240 iface, strerror(errno)));
243 tcparray = arp->tcparray;
245 for (i=0;i<tcparray->num;i++) {
246 struct ctdb_tcp_connection *tcon;
248 tcon = &tcparray->connections[i];
249 DEBUG(DEBUG_INFO,("sending tcp tickle ack for %u->%s:%u\n",
250 (unsigned)ntohs(tcon->dst_addr.ip.sin_port),
251 ctdb_addr_to_str(&tcon->src_addr),
252 (unsigned)ntohs(tcon->src_addr.ip.sin_port)));
253 ret = ctdb_sys_send_tcp(
258 DEBUG(DEBUG_CRIT,(__location__ " Failed to send tcp tickle ack for %s\n",
259 ctdb_addr_to_str(&tcon->src_addr)));
266 if (arp->count == CTDB_ARP_REPEAT) {
271 event_add_timed(arp->ctdb->ev, arp->vnn->takeover_ctx,
272 timeval_current_ofs(CTDB_ARP_INTERVAL, 100000),
273 ctdb_control_send_arp, arp);
276 static int32_t ctdb_announce_vnn_iface(struct ctdb_context *ctdb,
277 struct ctdb_vnn *vnn)
279 struct ctdb_takeover_arp *arp;
280 struct ctdb_tcp_array *tcparray;
282 if (!vnn->takeover_ctx) {
283 vnn->takeover_ctx = talloc_new(vnn);
284 if (!vnn->takeover_ctx) {
289 arp = talloc_zero(vnn->takeover_ctx, struct ctdb_takeover_arp);
295 arp->addr = vnn->public_address;
298 tcparray = vnn->tcp_array;
300 /* add all of the known tcp connections for this IP to the
301 list of tcp connections to send tickle acks for */
302 arp->tcparray = talloc_steal(arp, tcparray);
304 vnn->tcp_array = NULL;
305 vnn->tcp_update_needed = true;
308 event_add_timed(arp->ctdb->ev, vnn->takeover_ctx,
309 timeval_zero(), ctdb_control_send_arp, arp);
314 struct takeover_callback_state {
315 struct ctdb_req_control *c;
316 ctdb_sock_addr *addr;
317 struct ctdb_vnn *vnn;
320 struct ctdb_do_takeip_state {
321 struct ctdb_req_control *c;
322 struct ctdb_vnn *vnn;
326 called when takeip event finishes
328 static void ctdb_do_takeip_callback(struct ctdb_context *ctdb, int status,
331 struct ctdb_do_takeip_state *state =
332 talloc_get_type(private_data, struct ctdb_do_takeip_state);
336 if (status == -ETIME) {
339 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
340 ctdb_addr_to_str(&state->vnn->public_address),
341 ctdb_vnn_iface_string(state->vnn)));
342 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
347 ret = ctdb_announce_vnn_iface(ctdb, state->vnn);
349 ctdb_request_control_reply(ctdb, state->c, NULL, -1, NULL);
354 /* the control succeeded */
355 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
361 take over an ip address
363 static int32_t ctdb_do_takeip(struct ctdb_context *ctdb,
364 struct ctdb_req_control *c,
365 struct ctdb_vnn *vnn)
368 struct ctdb_do_takeip_state *state;
370 ret = ctdb_vnn_assign_iface(ctdb, vnn);
372 DEBUG(DEBUG_ERR,("Takeover of IP %s/%u failed to "
373 "assin a usable interface\n",
374 ctdb_addr_to_str(&vnn->public_address),
375 vnn->public_netmask_bits));
379 state = talloc(vnn, struct ctdb_do_takeip_state);
380 CTDB_NO_MEMORY(ctdb, state);
382 state->c = talloc_steal(ctdb, c);
385 DEBUG(DEBUG_NOTICE,("Takeover of IP %s/%u on interface %s\n",
386 ctdb_addr_to_str(&vnn->public_address),
387 vnn->public_netmask_bits,
388 ctdb_vnn_iface_string(vnn)));
390 ret = ctdb_event_script_callback(ctdb,
392 ctdb_do_takeip_callback,
397 ctdb_vnn_iface_string(vnn),
398 ctdb_addr_to_str(&vnn->public_address),
399 vnn->public_netmask_bits);
402 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
403 ctdb_addr_to_str(&vnn->public_address),
404 ctdb_vnn_iface_string(vnn)));
413 Find the vnn of the node that has a public ip address
414 returns -1 if the address is not known as a public address
416 static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
418 struct ctdb_vnn *vnn;
420 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
421 if (ctdb_same_ip(&vnn->public_address, addr)) {
430 take over an ip address
432 int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
433 struct ctdb_req_control *c,
438 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
439 struct ctdb_vnn *vnn;
440 bool have_ip = false;
441 bool do_takeip = false;
443 /* update out vnn list */
444 vnn = find_public_ip_vnn(ctdb, &pip->addr);
446 DEBUG(DEBUG_INFO,("takeoverip called for an ip '%s' that is not a public address\n",
447 ctdb_addr_to_str(&pip->addr)));
452 have_ip = ctdb_sys_have_ip(&pip->addr);
458 ret = ctdb_do_takeip(ctdb, c, vnn);
464 * The interface is up and the kernel known the ip
470 /* tell ctdb_control.c that we will be replying asynchronously */
477 takeover an ip address old v4 style
479 int32_t ctdb_control_takeover_ipv4(struct ctdb_context *ctdb,
480 struct ctdb_req_control *c,
486 data.dsize = sizeof(struct ctdb_public_ip);
487 data.dptr = (uint8_t *)talloc_zero(c, struct ctdb_public_ip);
488 CTDB_NO_MEMORY(ctdb, data.dptr);
490 memcpy(data.dptr, indata.dptr, indata.dsize);
491 return ctdb_control_takeover_ip(ctdb, c, data, async_reply);
495 kill any clients that are registered with a IP that is being released
497 static void release_kill_clients(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
499 struct ctdb_client_ip *ip;
501 DEBUG(DEBUG_INFO,("release_kill_clients for ip %s\n",
502 ctdb_addr_to_str(addr)));
504 for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
505 ctdb_sock_addr tmp_addr;
508 DEBUG(DEBUG_INFO,("checking for client %u with IP %s\n",
510 ctdb_addr_to_str(&ip->addr)));
512 if (ctdb_same_ip(&tmp_addr, addr)) {
513 struct ctdb_client *client = ctdb_reqid_find(ctdb,
516 DEBUG(DEBUG_INFO,("matched client %u with IP %s and pid %u\n",
518 ctdb_addr_to_str(&ip->addr),
521 if (client->pid != 0) {
522 DEBUG(DEBUG_INFO,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
523 (unsigned)client->pid,
524 ctdb_addr_to_str(addr),
526 kill(client->pid, SIGKILL);
533 called when releaseip event finishes
535 static void release_ip_callback(struct ctdb_context *ctdb, int status,
538 struct takeover_callback_state *state =
539 talloc_get_type(private_data, struct takeover_callback_state);
542 if (status == -ETIME) {
546 /* send a message to all clients of this node telling them
547 that the cluster has been reconfigured and they should
548 release any sockets on this IP */
549 data.dptr = (uint8_t *)talloc_strdup(state, ctdb_addr_to_str(state->addr));
550 CTDB_NO_MEMORY_VOID(ctdb, data.dptr);
551 data.dsize = strlen((char *)data.dptr)+1;
553 DEBUG(DEBUG_INFO,(__location__ " sending RELEASE_IP for '%s'\n", data.dptr));
555 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data);
557 /* kill clients that have registered with this IP */
558 release_kill_clients(ctdb, state->addr);
560 ctdb_vnn_unassign_iface(ctdb, state->vnn);
562 /* the control succeeded */
563 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
568 release an ip address
570 int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
571 struct ctdb_req_control *c,
576 struct takeover_callback_state *state;
577 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
578 struct ctdb_vnn *vnn;
580 /* update our vnn list */
581 vnn = find_public_ip_vnn(ctdb, &pip->addr);
583 DEBUG(DEBUG_INFO,("releaseip called for an ip '%s' that is not a public address\n",
584 ctdb_addr_to_str(&pip->addr)));
589 /* stop any previous arps */
590 talloc_free(vnn->takeover_ctx);
591 vnn->takeover_ctx = NULL;
593 if (!ctdb_sys_have_ip(&pip->addr)) {
594 DEBUG(DEBUG_NOTICE,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
595 ctdb_addr_to_str(&pip->addr),
596 vnn->public_netmask_bits,
597 ctdb_vnn_iface_string(vnn)));
598 ctdb_vnn_unassign_iface(ctdb, vnn);
602 DEBUG(DEBUG_NOTICE,("Release of IP %s/%u on interface %s node:%u\n",
603 ctdb_addr_to_str(&pip->addr),
604 vnn->public_netmask_bits,
605 ctdb_vnn_iface_string(vnn),
608 state = talloc(ctdb, struct takeover_callback_state);
609 CTDB_NO_MEMORY(ctdb, state);
611 state->c = talloc_steal(state, c);
612 state->addr = talloc(state, ctdb_sock_addr);
613 CTDB_NO_MEMORY(ctdb, state->addr);
614 *state->addr = pip->addr;
617 ret = ctdb_event_script_callback(ctdb,
618 state, release_ip_callback, state,
620 CTDB_EVENT_RELEASE_IP,
622 ctdb_vnn_iface_string(vnn),
623 ctdb_addr_to_str(&pip->addr),
624 vnn->public_netmask_bits);
626 DEBUG(DEBUG_ERR,(__location__ " Failed to release IP %s on interface %s\n",
627 ctdb_addr_to_str(&pip->addr),
628 ctdb_vnn_iface_string(vnn)));
633 /* tell the control that we will be reply asynchronously */
639 release an ip address old v4 style
641 int32_t ctdb_control_release_ipv4(struct ctdb_context *ctdb,
642 struct ctdb_req_control *c,
648 data.dsize = sizeof(struct ctdb_public_ip);
649 data.dptr = (uint8_t *)talloc_zero(c, struct ctdb_public_ip);
650 CTDB_NO_MEMORY(ctdb, data.dptr);
652 memcpy(data.dptr, indata.dptr, indata.dsize);
653 return ctdb_control_release_ip(ctdb, c, data, async_reply);
657 static int ctdb_add_public_address(struct ctdb_context *ctdb,
658 ctdb_sock_addr *addr,
659 unsigned mask, const char *ifaces)
661 struct ctdb_vnn *vnn;
668 /* Verify that we dont have an entry for this ip yet */
669 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
670 if (ctdb_same_sockaddr(addr, &vnn->public_address)) {
671 DEBUG(DEBUG_CRIT,("Same ip '%s' specified multiple times in the public address list \n",
672 ctdb_addr_to_str(addr)));
677 /* create a new vnn structure for this ip address */
678 vnn = talloc_zero(ctdb, struct ctdb_vnn);
679 CTDB_NO_MEMORY_FATAL(ctdb, vnn);
680 vnn->ifaces = talloc_array(vnn, const char *, num + 2);
681 tmp = talloc_strdup(vnn, ifaces);
682 CTDB_NO_MEMORY_FATAL(ctdb, tmp);
683 for (iface = strtok(tmp, ","); iface; iface = strtok(NULL, ",")) {
684 vnn->ifaces = talloc_realloc(vnn, vnn->ifaces, const char *, num + 2);
685 CTDB_NO_MEMORY_FATAL(ctdb, vnn->ifaces);
686 vnn->ifaces[num] = talloc_strdup(vnn, iface);
687 CTDB_NO_MEMORY_FATAL(ctdb, vnn->ifaces[num]);
691 vnn->ifaces[num] = NULL;
692 vnn->public_address = *addr;
693 vnn->public_netmask_bits = mask;
696 for (i=0; vnn->ifaces[i]; i++) {
697 ret = ctdb_add_local_iface(ctdb, vnn->ifaces[i]);
699 DEBUG(DEBUG_CRIT, (__location__ " failed to add iface[%s] "
700 "for public_address[%s]\n",
701 vnn->ifaces[i], ctdb_addr_to_str(addr)));
707 DLIST_ADD(ctdb->vnn, vnn);
713 setup the event script directory
715 int ctdb_set_event_script_dir(struct ctdb_context *ctdb, const char *script_dir)
717 ctdb->event_script_dir = talloc_strdup(ctdb, script_dir);
718 CTDB_NO_MEMORY(ctdb, ctdb->event_script_dir);
723 setup the public address lists from a file
725 int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
731 lines = file_lines_load(alist, &nlines, ctdb);
733 ctdb_set_error(ctdb, "Failed to load public address list '%s'\n", alist);
736 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
740 for (i=0;i<nlines;i++) {
748 while ((*line == ' ') || (*line == '\t')) {
754 if (strcmp(line, "") == 0) {
757 tok = strtok(line, " \t");
759 tok = strtok(NULL, " \t");
761 if (NULL == ctdb->default_public_interface) {
762 DEBUG(DEBUG_CRIT,("No default public interface and no interface specified at line %u of public address list\n",
767 ifaces = ctdb->default_public_interface;
772 if (!addrstr || !parse_ip_mask(addrstr, ifaces, &addr, &mask)) {
773 DEBUG(DEBUG_CRIT,("Badly formed line %u in public address list\n", i+1));
777 if (ctdb_add_public_address(ctdb, &addr, mask, ifaces)) {
778 DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
788 int ctdb_set_single_public_ip(struct ctdb_context *ctdb,
792 struct ctdb_vnn *svnn;
796 svnn = talloc_zero(ctdb, struct ctdb_vnn);
797 CTDB_NO_MEMORY(ctdb, svnn);
799 svnn->ifaces = talloc_array(svnn, const char *, 2);
800 CTDB_NO_MEMORY(ctdb, svnn->ifaces);
801 svnn->ifaces[0] = talloc_strdup(svnn->ifaces, iface);
802 CTDB_NO_MEMORY(ctdb, svnn->ifaces[0]);
803 svnn->ifaces[1] = NULL;
805 ok = parse_ip(ip, iface, 0, &svnn->public_address);
811 ret = ctdb_add_local_iface(ctdb, svnn->ifaces[0]);
813 DEBUG(DEBUG_CRIT, (__location__ " failed to add iface[%s] "
814 "for single_ip[%s]\n",
816 ctdb_addr_to_str(&svnn->public_address)));
821 ret = ctdb_vnn_assign_iface(ctdb, svnn);
827 ctdb->single_ip_vnn = svnn;
831 struct ctdb_public_ip_list {
832 struct ctdb_public_ip_list *next;
838 /* Given a physical node, return the number of
839 public addresses that is currently assigned to this node.
841 static int node_ip_coverage(struct ctdb_context *ctdb,
843 struct ctdb_public_ip_list *ips)
847 for (;ips;ips=ips->next) {
848 if (ips->pnn == pnn) {
856 /* Check if this is a public ip known to the node, i.e. can that
857 node takeover this ip ?
859 static int can_node_serve_ip(struct ctdb_context *ctdb, int32_t pnn,
860 struct ctdb_public_ip_list *ip)
862 struct ctdb_all_public_ips *public_ips;
865 public_ips = ctdb->nodes[pnn]->available_public_ips;
867 if (public_ips == NULL) {
871 for (i=0;i<public_ips->num;i++) {
872 if (ctdb_same_ip(&ip->addr, &public_ips->ips[i].addr)) {
873 /* yes, this node can serve this public ip */
882 /* search the node lists list for a node to takeover this ip.
883 pick the node that currently are serving the least number of ips
884 so that the ips get spread out evenly.
886 static int find_takeover_node(struct ctdb_context *ctdb,
887 struct ctdb_node_map *nodemap, uint32_t mask,
888 struct ctdb_public_ip_list *ip,
889 struct ctdb_public_ip_list *all_ips)
895 for (i=0;i<nodemap->num;i++) {
896 if (nodemap->nodes[i].flags & mask) {
897 /* This node is not healty and can not be used to serve
903 /* verify that this node can serve this ip */
904 if (can_node_serve_ip(ctdb, i, ip)) {
905 /* no it couldnt so skip to the next node */
909 num = node_ip_coverage(ctdb, i, all_ips);
910 /* was this the first node we checked ? */
922 DEBUG(DEBUG_WARNING,(__location__ " Could not find node to take over public address '%s'\n",
923 ctdb_addr_to_str(&ip->addr)));
933 static uint32_t *ip_key(ctdb_sock_addr *ip)
935 static uint32_t key[IP_KEYLEN];
937 bzero(key, sizeof(key));
939 switch (ip->sa.sa_family) {
941 key[3] = htonl(ip->ip.sin_addr.s_addr);
944 key[0] = htonl(ip->ip6.sin6_addr.s6_addr32[0]);
945 key[1] = htonl(ip->ip6.sin6_addr.s6_addr32[1]);
946 key[2] = htonl(ip->ip6.sin6_addr.s6_addr32[2]);
947 key[3] = htonl(ip->ip6.sin6_addr.s6_addr32[3]);
950 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", ip->sa.sa_family));
957 static void *add_ip_callback(void *parm, void *data)
962 void getips_count_callback(void *param, void *data)
964 struct ctdb_public_ip_list **ip_list = (struct ctdb_public_ip_list **)param;
965 struct ctdb_public_ip_list *new_ip = (struct ctdb_public_ip_list *)data;
967 new_ip->next = *ip_list;
971 struct ctdb_public_ip_list *
972 create_merged_ip_list(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx)
975 struct ctdb_public_ip_list *ip_list;
976 struct ctdb_all_public_ips *public_ips;
977 trbt_tree_t *ip_tree;
979 ip_tree = trbt_create(tmp_ctx, 0);
981 for (i=0;i<ctdb->num_nodes;i++) {
982 public_ips = ctdb->nodes[i]->known_public_ips;
984 if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
988 /* there were no public ips for this node */
989 if (public_ips == NULL) {
993 for (j=0;j<public_ips->num;j++) {
994 struct ctdb_public_ip_list *tmp_ip;
996 tmp_ip = talloc_zero(tmp_ctx, struct ctdb_public_ip_list);
997 CTDB_NO_MEMORY_NULL(ctdb, tmp_ip);
998 tmp_ip->pnn = public_ips->ips[j].pnn;
999 tmp_ip->addr = public_ips->ips[j].addr;
1000 tmp_ip->next = NULL;
1002 trbt_insertarray32_callback(ip_tree,
1003 IP_KEYLEN, ip_key(&public_ips->ips[j].addr),
1010 trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &ip_list);
1016 make any IP alias changes for public addresses that are necessary
1018 int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
1020 int i, num_healthy, retries;
1021 struct ctdb_public_ip ip;
1022 struct ctdb_public_ipv4 ipv4;
1024 struct ctdb_public_ip_list *all_ips, *tmp_ip;
1025 int maxnode, maxnum=0, minnode, minnum=0, num;
1027 struct timeval timeout;
1028 struct client_async_data *async_data;
1029 struct ctdb_client_control_state *state;
1030 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1035 /* Count how many completely healthy nodes we have */
1037 for (i=0;i<nodemap->num;i++) {
1038 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED))) {
1043 if (num_healthy > 0) {
1044 /* We have healthy nodes, so only consider them for
1045 serving public addresses
1047 mask = NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED;
1049 /* We didnt have any completely healthy nodes so
1050 use "disabled" nodes as a fallback
1052 mask = NODE_FLAGS_INACTIVE;
1055 /* since nodes only know about those public addresses that
1056 can be served by that particular node, no single node has
1057 a full list of all public addresses that exist in the cluster.
1058 Walk over all node structures and create a merged list of
1059 all public addresses that exist in the cluster.
1061 all_ips = create_merged_ip_list(ctdb, tmp_ctx);
1063 /* If we want deterministic ip allocations, i.e. that the ip addresses
1064 will always be allocated the same way for a specific set of
1065 available/unavailable nodes.
1067 if (1 == ctdb->tunable.deterministic_public_ips) {
1068 DEBUG(DEBUG_NOTICE,("Deterministic IPs enabled. Resetting all ip allocations\n"));
1069 for (i=0,tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next,i++) {
1070 tmp_ip->pnn = i%nodemap->num;
1075 /* mark all public addresses with a masked node as being served by
1078 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
1079 if (tmp_ip->pnn == -1) {
1082 if (nodemap->nodes[tmp_ip->pnn].flags & mask) {
1087 /* verify that the assigned nodes can serve that public ip
1088 and set it to -1 if not
1090 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
1091 if (tmp_ip->pnn == -1) {
1094 if (can_node_serve_ip(ctdb, tmp_ip->pnn, tmp_ip) != 0) {
1095 /* this node can not serve this ip. */
1101 /* now we must redistribute all public addresses with takeover node
1102 -1 among the nodes available
1106 /* loop over all ip's and find a physical node to cover for
1109 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
1110 if (tmp_ip->pnn == -1) {
1111 if (find_takeover_node(ctdb, nodemap, mask, tmp_ip, all_ips)) {
1112 DEBUG(DEBUG_WARNING,("Failed to find node to cover ip %s\n",
1113 ctdb_addr_to_str(&tmp_ip->addr)));
1118 /* If we dont want ips to fail back after a node becomes healthy
1119 again, we wont even try to reallocat the ip addresses so that
1120 they are evenly spread out.
1121 This can NOT be used at the same time as DeterministicIPs !
1123 if (1 == ctdb->tunable.no_ip_failback) {
1124 if (1 == ctdb->tunable.deterministic_public_ips) {
1125 DEBUG(DEBUG_ERR, ("ERROR: You can not use 'DeterministicIPs' and 'NoIPFailback' at the same time\n"));
1131 /* now, try to make sure the ip adresses are evenly distributed
1133 for each ip address, loop over all nodes that can serve this
1134 ip and make sure that the difference between the node
1135 serving the most and the node serving the least ip's are not greater
1138 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
1139 if (tmp_ip->pnn == -1) {
1143 /* Get the highest and lowest number of ips's served by any
1144 valid node which can serve this ip.
1148 for (i=0;i<nodemap->num;i++) {
1149 if (nodemap->nodes[i].flags & mask) {
1153 /* only check nodes that can actually serve this ip */
1154 if (can_node_serve_ip(ctdb, i, tmp_ip)) {
1155 /* no it couldnt so skip to the next node */
1159 num = node_ip_coverage(ctdb, i, all_ips);
1160 if (maxnode == -1) {
1169 if (minnode == -1) {
1179 if (maxnode == -1) {
1180 DEBUG(DEBUG_WARNING,(__location__ " Could not find maxnode. May not be able to serve ip '%s'\n",
1181 ctdb_addr_to_str(&tmp_ip->addr)));
1186 /* If we want deterministic IPs then dont try to reallocate
1187 them to spread out the load.
1189 if (1 == ctdb->tunable.deterministic_public_ips) {
1193 /* if the spread between the smallest and largest coverage by
1194 a node is >=2 we steal one of the ips from the node with
1195 most coverage to even things out a bit.
1196 try to do this at most 5 times since we dont want to spend
1197 too much time balancing the ip coverage.
1199 if ( (maxnum > minnum+1)
1201 struct ctdb_public_ip_list *tmp;
1203 /* mark one of maxnode's vnn's as unassigned and try
1206 for (tmp=all_ips;tmp;tmp=tmp->next) {
1207 if (tmp->pnn == maxnode) {
1217 /* finished distributing the public addresses, now just send the
1218 info out to the nodes
1222 /* at this point ->pnn is the node which will own each IP
1223 or -1 if there is no node that can cover this ip
1226 /* now tell all nodes to delete any alias that they should not
1227 have. This will be a NOOP on nodes that don't currently
1228 hold the given alias */
1229 async_data = talloc_zero(tmp_ctx, struct client_async_data);
1230 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
1232 for (i=0;i<nodemap->num;i++) {
1233 /* don't talk to unconnected nodes, but do talk to banned nodes */
1234 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
1238 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
1239 if (tmp_ip->pnn == nodemap->nodes[i].pnn) {
1240 /* This node should be serving this
1241 vnn so dont tell it to release the ip
1245 if (tmp_ip->addr.sa.sa_family == AF_INET) {
1246 ipv4.pnn = tmp_ip->pnn;
1247 ipv4.sin = tmp_ip->addr.ip;
1249 timeout = TAKEOVER_TIMEOUT();
1250 data.dsize = sizeof(ipv4);
1251 data.dptr = (uint8_t *)&ipv4;
1252 state = ctdb_control_send(ctdb, nodemap->nodes[i].pnn,
1253 0, CTDB_CONTROL_RELEASE_IPv4, 0,
1257 ip.pnn = tmp_ip->pnn;
1258 ip.addr = tmp_ip->addr;
1260 timeout = TAKEOVER_TIMEOUT();
1261 data.dsize = sizeof(ip);
1262 data.dptr = (uint8_t *)&ip;
1263 state = ctdb_control_send(ctdb, nodemap->nodes[i].pnn,
1264 0, CTDB_CONTROL_RELEASE_IP, 0,
1269 if (state == NULL) {
1270 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_RELEASE_IP to node %u\n", nodemap->nodes[i].pnn));
1271 talloc_free(tmp_ctx);
1275 ctdb_client_async_add(async_data, state);
1278 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
1279 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_RELEASE_IP failed\n"));
1280 talloc_free(tmp_ctx);
1283 talloc_free(async_data);
1286 /* tell all nodes to get their own IPs */
1287 async_data = talloc_zero(tmp_ctx, struct client_async_data);
1288 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
1289 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
1290 if (tmp_ip->pnn == -1) {
1291 /* this IP won't be taken over */
1295 if (tmp_ip->addr.sa.sa_family == AF_INET) {
1296 ipv4.pnn = tmp_ip->pnn;
1297 ipv4.sin = tmp_ip->addr.ip;
1299 timeout = TAKEOVER_TIMEOUT();
1300 data.dsize = sizeof(ipv4);
1301 data.dptr = (uint8_t *)&ipv4;
1302 state = ctdb_control_send(ctdb, tmp_ip->pnn,
1303 0, CTDB_CONTROL_TAKEOVER_IPv4, 0,
1307 ip.pnn = tmp_ip->pnn;
1308 ip.addr = tmp_ip->addr;
1310 timeout = TAKEOVER_TIMEOUT();
1311 data.dsize = sizeof(ip);
1312 data.dptr = (uint8_t *)&ip;
1313 state = ctdb_control_send(ctdb, tmp_ip->pnn,
1314 0, CTDB_CONTROL_TAKEOVER_IP, 0,
1318 if (state == NULL) {
1319 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_TAKEOVER_IP to node %u\n", tmp_ip->pnn));
1320 talloc_free(tmp_ctx);
1324 ctdb_client_async_add(async_data, state);
1326 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
1327 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_TAKEOVER_IP failed\n"));
1328 talloc_free(tmp_ctx);
1332 talloc_free(tmp_ctx);
1338 destroy a ctdb_client_ip structure
1340 static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
1342 DEBUG(DEBUG_DEBUG,("destroying client tcp for %s:%u (client_id %u)\n",
1343 ctdb_addr_to_str(&ip->addr),
1344 ntohs(ip->addr.ip.sin_port),
1347 DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
1352 called by a client to inform us of a TCP connection that it is managing
1353 that should tickled with an ACK when IP takeover is done
1354 we handle both the old ipv4 style of packets as well as the new ipv4/6
1357 int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
1360 struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
1361 struct ctdb_control_tcp *old_addr = NULL;
1362 struct ctdb_control_tcp_addr new_addr;
1363 struct ctdb_control_tcp_addr *tcp_sock = NULL;
1364 struct ctdb_tcp_list *tcp;
1365 struct ctdb_control_tcp_vnn t;
1368 struct ctdb_client_ip *ip;
1369 struct ctdb_vnn *vnn;
1370 ctdb_sock_addr addr;
1372 switch (indata.dsize) {
1373 case sizeof(struct ctdb_control_tcp):
1374 old_addr = (struct ctdb_control_tcp *)indata.dptr;
1375 ZERO_STRUCT(new_addr);
1376 tcp_sock = &new_addr;
1377 tcp_sock->src.ip = old_addr->src;
1378 tcp_sock->dest.ip = old_addr->dest;
1380 case sizeof(struct ctdb_control_tcp_addr):
1381 tcp_sock = (struct ctdb_control_tcp_addr *)indata.dptr;
1384 DEBUG(DEBUG_ERR,(__location__ " Invalid data structure passed "
1385 "to ctdb_control_tcp_client. size was %d but "
1386 "only allowed sizes are %lu and %lu\n",
1388 (long unsigned)sizeof(struct ctdb_control_tcp),
1389 (long unsigned)sizeof(struct ctdb_control_tcp_addr)));
1393 addr = tcp_sock->src;
1394 ctdb_canonicalize_ip(&addr, &tcp_sock->src);
1395 addr = tcp_sock->dest;
1396 ctdb_canonicalize_ip(&addr, &tcp_sock->dest);
1399 memcpy(&addr, &tcp_sock->dest, sizeof(addr));
1400 vnn = find_public_ip_vnn(ctdb, &addr);
1402 switch (addr.sa.sa_family) {
1404 if (ntohl(addr.ip.sin_addr.s_addr) != INADDR_LOOPBACK) {
1405 DEBUG(DEBUG_ERR,("Could not add client IP %s. This is not a public address.\n",
1406 ctdb_addr_to_str(&addr)));
1410 DEBUG(DEBUG_ERR,("Could not add client IP %s. This is not a public ipv6 address.\n",
1411 ctdb_addr_to_str(&addr)));
1414 DEBUG(DEBUG_ERR,(__location__ " Unknown family type %d\n", addr.sa.sa_family));
1420 if (vnn->pnn != ctdb->pnn) {
1421 DEBUG(DEBUG_ERR,("Attempt to register tcp client for IP %s we don't hold - failing (client_id %u pid %u)\n",
1422 ctdb_addr_to_str(&addr),
1423 client_id, client->pid));
1424 /* failing this call will tell smbd to die */
1428 ip = talloc(client, struct ctdb_client_ip);
1429 CTDB_NO_MEMORY(ctdb, ip);
1433 ip->client_id = client_id;
1434 talloc_set_destructor(ip, ctdb_client_ip_destructor);
1435 DLIST_ADD(ctdb->client_ip_list, ip);
1437 tcp = talloc(client, struct ctdb_tcp_list);
1438 CTDB_NO_MEMORY(ctdb, tcp);
1440 tcp->connection.src_addr = tcp_sock->src;
1441 tcp->connection.dst_addr = tcp_sock->dest;
1443 DLIST_ADD(client->tcp_list, tcp);
1445 t.src = tcp_sock->src;
1446 t.dest = tcp_sock->dest;
1448 data.dptr = (uint8_t *)&t;
1449 data.dsize = sizeof(t);
1451 switch (addr.sa.sa_family) {
1453 DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
1454 (unsigned)ntohs(tcp_sock->dest.ip.sin_port),
1455 ctdb_addr_to_str(&tcp_sock->src),
1456 (unsigned)ntohs(tcp_sock->src.ip.sin_port), client_id, client->pid));
1459 DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
1460 (unsigned)ntohs(tcp_sock->dest.ip6.sin6_port),
1461 ctdb_addr_to_str(&tcp_sock->src),
1462 (unsigned)ntohs(tcp_sock->src.ip6.sin6_port), client_id, client->pid));
1465 DEBUG(DEBUG_ERR,(__location__ " Unknown family %d\n", addr.sa.sa_family));
1469 /* tell all nodes about this tcp connection */
1470 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
1471 CTDB_CONTROL_TCP_ADD,
1472 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1474 DEBUG(DEBUG_ERR,(__location__ " Failed to send CTDB_CONTROL_TCP_ADD\n"));
1482 find a tcp address on a list
1484 static struct ctdb_tcp_connection *ctdb_tcp_find(struct ctdb_tcp_array *array,
1485 struct ctdb_tcp_connection *tcp)
1489 if (array == NULL) {
1493 for (i=0;i<array->num;i++) {
1494 if (ctdb_same_sockaddr(&array->connections[i].src_addr, &tcp->src_addr) &&
1495 ctdb_same_sockaddr(&array->connections[i].dst_addr, &tcp->dst_addr)) {
1496 return &array->connections[i];
1503 called by a daemon to inform us of a TCP connection that one of its
1504 clients managing that should tickled with an ACK when IP takeover is
1507 int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
1509 struct ctdb_control_tcp_vnn *p = (struct ctdb_control_tcp_vnn *)indata.dptr;
1510 struct ctdb_tcp_array *tcparray;
1511 struct ctdb_tcp_connection tcp;
1512 struct ctdb_vnn *vnn;
1514 vnn = find_public_ip_vnn(ctdb, &p->dest);
1516 DEBUG(DEBUG_INFO,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
1517 ctdb_addr_to_str(&p->dest)));
1523 tcparray = vnn->tcp_array;
1525 /* If this is the first tickle */
1526 if (tcparray == NULL) {
1527 tcparray = talloc_size(ctdb->nodes,
1528 offsetof(struct ctdb_tcp_array, connections) +
1529 sizeof(struct ctdb_tcp_connection) * 1);
1530 CTDB_NO_MEMORY(ctdb, tcparray);
1531 vnn->tcp_array = tcparray;
1534 tcparray->connections = talloc_size(tcparray, sizeof(struct ctdb_tcp_connection));
1535 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1537 tcparray->connections[tcparray->num].src_addr = p->src;
1538 tcparray->connections[tcparray->num].dst_addr = p->dest;
1544 /* Do we already have this tickle ?*/
1545 tcp.src_addr = p->src;
1546 tcp.dst_addr = p->dest;
1547 if (ctdb_tcp_find(vnn->tcp_array, &tcp) != NULL) {
1548 DEBUG(DEBUG_DEBUG,("Already had tickle info for %s:%u for vnn:%u\n",
1549 ctdb_addr_to_str(&tcp.dst_addr),
1550 ntohs(tcp.dst_addr.ip.sin_port),
1555 /* A new tickle, we must add it to the array */
1556 tcparray->connections = talloc_realloc(tcparray, tcparray->connections,
1557 struct ctdb_tcp_connection,
1559 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1561 vnn->tcp_array = tcparray;
1562 tcparray->connections[tcparray->num].src_addr = p->src;
1563 tcparray->connections[tcparray->num].dst_addr = p->dest;
1566 DEBUG(DEBUG_INFO,("Added tickle info for %s:%u from vnn %u\n",
1567 ctdb_addr_to_str(&tcp.dst_addr),
1568 ntohs(tcp.dst_addr.ip.sin_port),
1576 called by a daemon to inform us of a TCP connection that one of its
1577 clients managing that should tickled with an ACK when IP takeover is
1580 static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tcp_connection *conn)
1582 struct ctdb_tcp_connection *tcpp;
1583 struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, &conn->dst_addr);
1586 DEBUG(DEBUG_ERR,(__location__ " unable to find public address %s\n",
1587 ctdb_addr_to_str(&conn->dst_addr)));
1591 /* if the array is empty we cant remove it
1592 and we dont need to do anything
1594 if (vnn->tcp_array == NULL) {
1595 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist (array is empty) %s:%u\n",
1596 ctdb_addr_to_str(&conn->dst_addr),
1597 ntohs(conn->dst_addr.ip.sin_port)));
1602 /* See if we know this connection
1603 if we dont know this connection then we dont need to do anything
1605 tcpp = ctdb_tcp_find(vnn->tcp_array, conn);
1607 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist %s:%u\n",
1608 ctdb_addr_to_str(&conn->dst_addr),
1609 ntohs(conn->dst_addr.ip.sin_port)));
1614 /* We need to remove this entry from the array.
1615 Instead of allocating a new array and copying data to it
1616 we cheat and just copy the last entry in the existing array
1617 to the entry that is to be removed and just shring the
1620 *tcpp = vnn->tcp_array->connections[vnn->tcp_array->num - 1];
1621 vnn->tcp_array->num--;
1623 /* If we deleted the last entry we also need to remove the entire array
1625 if (vnn->tcp_array->num == 0) {
1626 talloc_free(vnn->tcp_array);
1627 vnn->tcp_array = NULL;
1630 vnn->tcp_update_needed = true;
1632 DEBUG(DEBUG_INFO,("Removed tickle info for %s:%u\n",
1633 ctdb_addr_to_str(&conn->src_addr),
1634 ntohs(conn->src_addr.ip.sin_port)));
1639 called when a daemon restarts - send all tickes for all public addresses
1640 we are serving immediately to the new node.
1642 int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t vnn)
1644 /*XXX here we should send all tickes we are serving to the new node */
1650 called when a client structure goes away - hook to remove
1651 elements from the tcp_list in all daemons
1653 void ctdb_takeover_client_destructor_hook(struct ctdb_client *client)
1655 while (client->tcp_list) {
1656 struct ctdb_tcp_list *tcp = client->tcp_list;
1657 DLIST_REMOVE(client->tcp_list, tcp);
1658 ctdb_remove_tcp_connection(client->ctdb, &tcp->connection);
1664 release all IPs on shutdown
1666 void ctdb_release_all_ips(struct ctdb_context *ctdb)
1668 struct ctdb_vnn *vnn;
1670 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1671 if (!ctdb_sys_have_ip(&vnn->public_address)) {
1672 ctdb_vnn_unassign_iface(ctdb, vnn);
1678 ctdb_event_script_args(ctdb, CTDB_EVENT_RELEASE_IP, "%s %s %u",
1679 ctdb_vnn_iface_string(vnn),
1680 ctdb_addr_to_str(&vnn->public_address),
1681 vnn->public_netmask_bits);
1682 release_kill_clients(ctdb, &vnn->public_address);
1683 ctdb_vnn_unassign_iface(ctdb, vnn);
1689 get list of public IPs
1691 int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb,
1692 struct ctdb_req_control *c, TDB_DATA *outdata)
1695 struct ctdb_all_public_ips *ips;
1696 struct ctdb_vnn *vnn;
1697 bool only_available = false;
1699 if (c->flags & CTDB_PUBLIC_IP_FLAGS_ONLY_AVAILABLE) {
1700 only_available = true;
1703 /* count how many public ip structures we have */
1705 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1709 len = offsetof(struct ctdb_all_public_ips, ips) +
1710 num*sizeof(struct ctdb_public_ip);
1711 ips = talloc_zero_size(outdata, len);
1712 CTDB_NO_MEMORY(ctdb, ips);
1715 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1716 if (only_available && !ctdb_vnn_available(ctdb, vnn)) {
1719 ips->ips[i].pnn = vnn->pnn;
1720 ips->ips[i].addr = vnn->public_address;
1724 len = offsetof(struct ctdb_all_public_ips, ips) +
1725 i*sizeof(struct ctdb_public_ip);
1727 outdata->dsize = len;
1728 outdata->dptr = (uint8_t *)ips;
1735 get list of public IPs, old ipv4 style. only returns ipv4 addresses
1737 int32_t ctdb_control_get_public_ipsv4(struct ctdb_context *ctdb,
1738 struct ctdb_req_control *c, TDB_DATA *outdata)
1741 struct ctdb_all_public_ipsv4 *ips;
1742 struct ctdb_vnn *vnn;
1744 /* count how many public ip structures we have */
1746 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1747 if (vnn->public_address.sa.sa_family != AF_INET) {
1753 len = offsetof(struct ctdb_all_public_ipsv4, ips) +
1754 num*sizeof(struct ctdb_public_ipv4);
1755 ips = talloc_zero_size(outdata, len);
1756 CTDB_NO_MEMORY(ctdb, ips);
1758 outdata->dsize = len;
1759 outdata->dptr = (uint8_t *)ips;
1763 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1764 if (vnn->public_address.sa.sa_family != AF_INET) {
1767 ips->ips[i].pnn = vnn->pnn;
1768 ips->ips[i].sin = vnn->public_address.ip;
1775 int32_t ctdb_control_get_public_ip_info(struct ctdb_context *ctdb,
1776 struct ctdb_req_control *c,
1781 ctdb_sock_addr *addr;
1782 struct ctdb_control_public_ip_info *info;
1783 struct ctdb_vnn *vnn;
1785 addr = (ctdb_sock_addr *)indata.dptr;
1787 vnn = find_public_ip_vnn(ctdb, addr);
1789 /* if it is not a public ip it could be our 'single ip' */
1790 if (ctdb->single_ip_vnn) {
1791 if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, addr)) {
1792 vnn = ctdb->single_ip_vnn;
1797 DEBUG(DEBUG_ERR,(__location__ " Could not get public ip info, "
1798 "'%s'not a public address\n",
1799 ctdb_addr_to_str(addr)));
1803 /* count how many public ip structures we have */
1805 for (;vnn->ifaces[num];) {
1809 len = offsetof(struct ctdb_control_public_ip_info, ifaces) +
1810 num*sizeof(struct ctdb_control_iface_info);
1811 info = talloc_zero_size(outdata, len);
1812 CTDB_NO_MEMORY(ctdb, info);
1814 info->ip.addr = vnn->public_address;
1815 info->ip.pnn = vnn->pnn;
1816 info->active_idx = 0xFFFFFFFF;
1818 for (i=0; vnn->ifaces[i]; i++) {
1819 struct ctdb_iface *cur;
1821 cur = ctdb_find_iface(ctdb, vnn->ifaces[i]);
1823 DEBUG(DEBUG_CRIT, (__location__ " internal error iface[%s] unknown\n",
1827 if (vnn->iface == cur) {
1828 info->active_idx = i;
1830 strcpy(info->ifaces[i].name, cur->name);
1831 info->ifaces[i].link_state = cur->link_up;
1832 info->ifaces[i].references = cur->references;
1835 len = offsetof(struct ctdb_control_public_ip_info, ifaces) +
1836 i*sizeof(struct ctdb_control_iface_info);
1838 outdata->dsize = len;
1839 outdata->dptr = (uint8_t *)info;
1844 int32_t ctdb_control_get_ifaces(struct ctdb_context *ctdb,
1845 struct ctdb_req_control *c,
1849 struct ctdb_control_get_ifaces *ifaces;
1850 struct ctdb_iface *cur;
1852 /* count how many public ip structures we have */
1854 for (cur=ctdb->ifaces;cur;cur=cur->next) {
1858 len = offsetof(struct ctdb_control_get_ifaces, ifaces) +
1859 num*sizeof(struct ctdb_control_iface_info);
1860 ifaces = talloc_zero_size(outdata, len);
1861 CTDB_NO_MEMORY(ctdb, ifaces);
1864 for (cur=ctdb->ifaces;cur;cur=cur->next) {
1865 strcpy(ifaces->ifaces[i].name, cur->name);
1866 ifaces->ifaces[i].link_state = cur->link_up;
1867 ifaces->ifaces[i].references = cur->references;
1871 len = offsetof(struct ctdb_control_get_ifaces, ifaces) +
1872 i*sizeof(struct ctdb_control_iface_info);
1874 outdata->dsize = len;
1875 outdata->dptr = (uint8_t *)ifaces;
1880 int32_t ctdb_control_set_iface_link(struct ctdb_context *ctdb,
1881 struct ctdb_req_control *c,
1884 struct ctdb_control_iface_info *info;
1885 struct ctdb_iface *iface;
1886 bool link_up = false;
1888 info = (struct ctdb_control_iface_info *)indata.dptr;
1890 if (info->name[CTDB_IFACE_SIZE] != '\0') {
1891 int len = strnlen(info->name, CTDB_IFACE_SIZE);
1892 DEBUG(DEBUG_ERR, (__location__ " name[%*.*s] not terminated\n",
1893 len, len, info->name));
1897 switch (info->link_state) {
1905 DEBUG(DEBUG_ERR, (__location__ " link_state[%u] invalid\n",
1906 (unsigned int)info->link_state));
1910 if (info->references != 0) {
1911 DEBUG(DEBUG_ERR, (__location__ " references[%u] should be 0\n",
1912 (unsigned int)info->references));
1916 iface = ctdb_find_iface(ctdb, info->name);
1917 if (iface == NULL) {
1918 DEBUG(DEBUG_ERR, (__location__ "iface[%s] is unknown\n",
1923 if (link_up == iface->link_up) {
1927 DEBUG(iface->link_up?DEBUG_ERR:DEBUG_NOTICE,
1928 ("iface[%s] has changed it's link status %s => %s\n",
1930 iface->link_up?"up":"down",
1931 link_up?"up":"down"));
1933 iface->link_up = link_up;
1939 structure containing the listening socket and the list of tcp connections
1940 that the ctdb daemon is to kill
1942 struct ctdb_kill_tcp {
1943 struct ctdb_vnn *vnn;
1944 struct ctdb_context *ctdb;
1946 struct fd_event *fde;
1947 trbt_tree_t *connections;
1952 a tcp connection that is to be killed
1954 struct ctdb_killtcp_con {
1955 ctdb_sock_addr src_addr;
1956 ctdb_sock_addr dst_addr;
1958 struct ctdb_kill_tcp *killtcp;
1961 /* this function is used to create a key to represent this socketpair
1962 in the killtcp tree.
1963 this key is used to insert and lookup matching socketpairs that are
1964 to be tickled and RST
1966 #define KILLTCP_KEYLEN 10
1967 static uint32_t *killtcp_key(ctdb_sock_addr *src, ctdb_sock_addr *dst)
1969 static uint32_t key[KILLTCP_KEYLEN];
1971 bzero(key, sizeof(key));
1973 if (src->sa.sa_family != dst->sa.sa_family) {
1974 DEBUG(DEBUG_ERR, (__location__ " ERROR, different families passed :%u vs %u\n", src->sa.sa_family, dst->sa.sa_family));
1978 switch (src->sa.sa_family) {
1980 key[0] = dst->ip.sin_addr.s_addr;
1981 key[1] = src->ip.sin_addr.s_addr;
1982 key[2] = dst->ip.sin_port;
1983 key[3] = src->ip.sin_port;
1986 key[0] = dst->ip6.sin6_addr.s6_addr32[3];
1987 key[1] = src->ip6.sin6_addr.s6_addr32[3];
1988 key[2] = dst->ip6.sin6_addr.s6_addr32[2];
1989 key[3] = src->ip6.sin6_addr.s6_addr32[2];
1990 key[4] = dst->ip6.sin6_addr.s6_addr32[1];
1991 key[5] = src->ip6.sin6_addr.s6_addr32[1];
1992 key[6] = dst->ip6.sin6_addr.s6_addr32[0];
1993 key[7] = src->ip6.sin6_addr.s6_addr32[0];
1994 key[8] = dst->ip6.sin6_port;
1995 key[9] = src->ip6.sin6_port;
1998 DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", src->sa.sa_family));
2006 called when we get a read event on the raw socket
2008 static void capture_tcp_handler(struct event_context *ev, struct fd_event *fde,
2009 uint16_t flags, void *private_data)
2011 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
2012 struct ctdb_killtcp_con *con;
2013 ctdb_sock_addr src, dst;
2014 uint32_t ack_seq, seq;
2016 if (!(flags & EVENT_FD_READ)) {
2020 if (ctdb_sys_read_tcp_packet(killtcp->capture_fd,
2021 killtcp->private_data,
2023 &ack_seq, &seq) != 0) {
2024 /* probably a non-tcp ACK packet */
2028 /* check if we have this guy in our list of connections
2031 con = trbt_lookuparray32(killtcp->connections,
2032 KILLTCP_KEYLEN, killtcp_key(&src, &dst));
2034 /* no this was some other packet we can just ignore */
2038 /* This one has been tickled !
2039 now reset him and remove him from the list.
2041 DEBUG(DEBUG_INFO, ("sending a tcp reset to kill connection :%d -> %s:%d\n",
2042 ntohs(con->dst_addr.ip.sin_port),
2043 ctdb_addr_to_str(&con->src_addr),
2044 ntohs(con->src_addr.ip.sin_port)));
2046 ctdb_sys_send_tcp(&con->dst_addr, &con->src_addr, ack_seq, seq, 1);
2051 /* when traversing the list of all tcp connections to send tickle acks to
2052 (so that we can capture the ack coming back and kill the connection
2054 this callback is called for each connection we are currently trying to kill
2056 static void tickle_connection_traverse(void *param, void *data)
2058 struct ctdb_killtcp_con *con = talloc_get_type(data, struct ctdb_killtcp_con);
2060 /* have tried too many times, just give up */
2061 if (con->count >= 5) {
2066 /* othervise, try tickling it again */
2069 (ctdb_sock_addr *)&con->dst_addr,
2070 (ctdb_sock_addr *)&con->src_addr,
2076 called every second until all sentenced connections have been reset
2078 static void ctdb_tickle_sentenced_connections(struct event_context *ev, struct timed_event *te,
2079 struct timeval t, void *private_data)
2081 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
2084 /* loop over all connections sending tickle ACKs */
2085 trbt_traversearray32(killtcp->connections, KILLTCP_KEYLEN, tickle_connection_traverse, NULL);
2088 /* If there are no more connections to kill we can remove the
2089 entire killtcp structure
2091 if ( (killtcp->connections == NULL) ||
2092 (killtcp->connections->root == NULL) ) {
2093 talloc_free(killtcp);
2097 /* try tickling them again in a seconds time
2099 event_add_timed(killtcp->ctdb->ev, killtcp, timeval_current_ofs(1, 0),
2100 ctdb_tickle_sentenced_connections, killtcp);
2104 destroy the killtcp structure
2106 static int ctdb_killtcp_destructor(struct ctdb_kill_tcp *killtcp)
2108 killtcp->vnn->killtcp = NULL;
2113 /* nothing fancy here, just unconditionally replace any existing
2114 connection structure with the new one.
2116 dont even free the old one if it did exist, that one is talloc_stolen
2117 by the same node in the tree anyway and will be deleted when the new data
2120 static void *add_killtcp_callback(void *parm, void *data)
2126 add a tcp socket to the list of connections we want to RST
2128 static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
2132 ctdb_sock_addr src, dst;
2133 struct ctdb_kill_tcp *killtcp;
2134 struct ctdb_killtcp_con *con;
2135 struct ctdb_vnn *vnn;
2137 ctdb_canonicalize_ip(s, &src);
2138 ctdb_canonicalize_ip(d, &dst);
2140 vnn = find_public_ip_vnn(ctdb, &dst);
2142 vnn = find_public_ip_vnn(ctdb, &src);
2145 /* if it is not a public ip it could be our 'single ip' */
2146 if (ctdb->single_ip_vnn) {
2147 if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, &dst)) {
2148 vnn = ctdb->single_ip_vnn;
2153 DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n"));
2157 killtcp = vnn->killtcp;
2159 /* If this is the first connection to kill we must allocate
2162 if (killtcp == NULL) {
2163 killtcp = talloc_zero(ctdb, struct ctdb_kill_tcp);
2164 CTDB_NO_MEMORY(ctdb, killtcp);
2167 killtcp->ctdb = ctdb;
2168 killtcp->capture_fd = -1;
2169 killtcp->connections = trbt_create(killtcp, 0);
2171 vnn->killtcp = killtcp;
2172 talloc_set_destructor(killtcp, ctdb_killtcp_destructor);
2177 /* create a structure that describes this connection we want to
2178 RST and store it in killtcp->connections
2180 con = talloc(killtcp, struct ctdb_killtcp_con);
2181 CTDB_NO_MEMORY(ctdb, con);
2182 con->src_addr = src;
2183 con->dst_addr = dst;
2185 con->killtcp = killtcp;
2188 trbt_insertarray32_callback(killtcp->connections,
2189 KILLTCP_KEYLEN, killtcp_key(&con->dst_addr, &con->src_addr),
2190 add_killtcp_callback, con);
2193 If we dont have a socket to listen on yet we must create it
2195 if (killtcp->capture_fd == -1) {
2196 const char *iface = ctdb_vnn_iface_string(vnn);
2197 killtcp->capture_fd = ctdb_sys_open_capture_socket(iface, &killtcp->private_data);
2198 if (killtcp->capture_fd == -1) {
2199 DEBUG(DEBUG_CRIT,(__location__ " Failed to open capturing "
2200 "socket on iface '%s' for killtcp (%s)\n",
2201 iface, strerror(errno)));
2207 if (killtcp->fde == NULL) {
2208 killtcp->fde = event_add_fd(ctdb->ev, killtcp, killtcp->capture_fd,
2209 EVENT_FD_READ | EVENT_FD_AUTOCLOSE,
2210 capture_tcp_handler, killtcp);
2212 /* We also need to set up some events to tickle all these connections
2213 until they are all reset
2215 event_add_timed(ctdb->ev, killtcp, timeval_current_ofs(1, 0),
2216 ctdb_tickle_sentenced_connections, killtcp);
2219 /* tickle him once now */
2228 talloc_free(vnn->killtcp);
2229 vnn->killtcp = NULL;
2234 kill a TCP connection.
2236 int32_t ctdb_control_kill_tcp(struct ctdb_context *ctdb, TDB_DATA indata)
2238 struct ctdb_control_killtcp *killtcp = (struct ctdb_control_killtcp *)indata.dptr;
2240 return ctdb_killtcp_add_connection(ctdb, &killtcp->src_addr, &killtcp->dst_addr);
2244 called by a daemon to inform us of the entire list of TCP tickles for
2245 a particular public address.
2246 this control should only be sent by the node that is currently serving
2247 that public address.
2249 int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata)
2251 struct ctdb_control_tcp_tickle_list *list = (struct ctdb_control_tcp_tickle_list *)indata.dptr;
2252 struct ctdb_tcp_array *tcparray;
2253 struct ctdb_vnn *vnn;
2255 /* We must at least have tickles.num or else we cant verify the size
2256 of the received data blob
2258 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
2259 tickles.connections)) {
2260 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list. Not enough data for the tickle.num field\n"));
2264 /* verify that the size of data matches what we expect */
2265 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
2266 tickles.connections)
2267 + sizeof(struct ctdb_tcp_connection)
2268 * list->tickles.num) {
2269 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list\n"));
2273 vnn = find_public_ip_vnn(ctdb, &list->addr);
2275 DEBUG(DEBUG_INFO,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n",
2276 ctdb_addr_to_str(&list->addr)));
2281 /* remove any old ticklelist we might have */
2282 talloc_free(vnn->tcp_array);
2283 vnn->tcp_array = NULL;
2285 tcparray = talloc(ctdb->nodes, struct ctdb_tcp_array);
2286 CTDB_NO_MEMORY(ctdb, tcparray);
2288 tcparray->num = list->tickles.num;
2290 tcparray->connections = talloc_array(tcparray, struct ctdb_tcp_connection, tcparray->num);
2291 CTDB_NO_MEMORY(ctdb, tcparray->connections);
2293 memcpy(tcparray->connections, &list->tickles.connections[0],
2294 sizeof(struct ctdb_tcp_connection)*tcparray->num);
2296 /* We now have a new fresh tickle list array for this vnn */
2297 vnn->tcp_array = talloc_steal(vnn, tcparray);
2303 called to return the full list of tickles for the puclic address associated
2304 with the provided vnn
2306 int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata)
2308 ctdb_sock_addr *addr = (ctdb_sock_addr *)indata.dptr;
2309 struct ctdb_control_tcp_tickle_list *list;
2310 struct ctdb_tcp_array *tcparray;
2312 struct ctdb_vnn *vnn;
2314 vnn = find_public_ip_vnn(ctdb, addr);
2316 DEBUG(DEBUG_ERR,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n",
2317 ctdb_addr_to_str(addr)));
2322 tcparray = vnn->tcp_array;
2324 num = tcparray->num;
2329 outdata->dsize = offsetof(struct ctdb_control_tcp_tickle_list,
2330 tickles.connections)
2331 + sizeof(struct ctdb_tcp_connection) * num;
2333 outdata->dptr = talloc_size(outdata, outdata->dsize);
2334 CTDB_NO_MEMORY(ctdb, outdata->dptr);
2335 list = (struct ctdb_control_tcp_tickle_list *)outdata->dptr;
2338 list->tickles.num = num;
2340 memcpy(&list->tickles.connections[0], tcparray->connections,
2341 sizeof(struct ctdb_tcp_connection) * num);
2349 set the list of all tcp tickles for a public address
2351 static int ctdb_ctrl_set_tcp_tickles(struct ctdb_context *ctdb,
2352 struct timeval timeout, uint32_t destnode,
2353 ctdb_sock_addr *addr,
2354 struct ctdb_tcp_array *tcparray)
2358 struct ctdb_control_tcp_tickle_list *list;
2361 num = tcparray->num;
2366 data.dsize = offsetof(struct ctdb_control_tcp_tickle_list,
2367 tickles.connections) +
2368 sizeof(struct ctdb_tcp_connection) * num;
2369 data.dptr = talloc_size(ctdb, data.dsize);
2370 CTDB_NO_MEMORY(ctdb, data.dptr);
2372 list = (struct ctdb_control_tcp_tickle_list *)data.dptr;
2374 list->tickles.num = num;
2376 memcpy(&list->tickles.connections[0], tcparray->connections, sizeof(struct ctdb_tcp_connection) * num);
2379 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
2380 CTDB_CONTROL_SET_TCP_TICKLE_LIST,
2381 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
2383 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set tcp tickles failed\n"));
2387 talloc_free(data.dptr);
2394 perform tickle updates if required
2396 static void ctdb_update_tcp_tickles(struct event_context *ev,
2397 struct timed_event *te,
2398 struct timeval t, void *private_data)
2400 struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
2402 struct ctdb_vnn *vnn;
2404 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
2405 /* we only send out updates for public addresses that
2408 if (ctdb->pnn != vnn->pnn) {
2411 /* We only send out the updates if we need to */
2412 if (!vnn->tcp_update_needed) {
2415 ret = ctdb_ctrl_set_tcp_tickles(ctdb,
2417 CTDB_BROADCAST_CONNECTED,
2418 &vnn->public_address,
2421 DEBUG(DEBUG_ERR,("Failed to send the tickle update for public address %s\n",
2422 ctdb_addr_to_str(&vnn->public_address)));
2426 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
2427 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
2428 ctdb_update_tcp_tickles, ctdb);
2433 start periodic update of tcp tickles
2435 void ctdb_start_tcp_tickle_update(struct ctdb_context *ctdb)
2437 ctdb->tickle_update_context = talloc_new(ctdb);
2439 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
2440 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
2441 ctdb_update_tcp_tickles, ctdb);
2447 struct control_gratious_arp {
2448 struct ctdb_context *ctdb;
2449 ctdb_sock_addr addr;
2455 send a control_gratuitous arp
2457 static void send_gratious_arp(struct event_context *ev, struct timed_event *te,
2458 struct timeval t, void *private_data)
2461 struct control_gratious_arp *arp = talloc_get_type(private_data,
2462 struct control_gratious_arp);
2464 ret = ctdb_sys_send_arp(&arp->addr, arp->iface);
2466 DEBUG(DEBUG_ERR,(__location__ " sending of gratious arp on iface '%s' failed (%s)\n",
2467 arp->iface, strerror(errno)));
2472 if (arp->count == CTDB_ARP_REPEAT) {
2477 event_add_timed(arp->ctdb->ev, arp,
2478 timeval_current_ofs(CTDB_ARP_INTERVAL, 0),
2479 send_gratious_arp, arp);
2486 int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indata)
2488 struct ctdb_control_gratious_arp *gratious_arp = (struct ctdb_control_gratious_arp *)indata.dptr;
2489 struct control_gratious_arp *arp;
2491 /* verify the size of indata */
2492 if (indata.dsize < offsetof(struct ctdb_control_gratious_arp, iface)) {
2493 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_gratious_arp structure. Got %u require %u bytes\n",
2494 (unsigned)indata.dsize,
2495 (unsigned)offsetof(struct ctdb_control_gratious_arp, iface)));
2499 ( offsetof(struct ctdb_control_gratious_arp, iface)
2500 + gratious_arp->len ) ){
2502 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
2503 "but should be %u bytes\n",
2504 (unsigned)indata.dsize,
2505 (unsigned)(offsetof(struct ctdb_control_gratious_arp, iface)+gratious_arp->len)));
2510 arp = talloc(ctdb, struct control_gratious_arp);
2511 CTDB_NO_MEMORY(ctdb, arp);
2514 arp->addr = gratious_arp->addr;
2515 arp->iface = talloc_strdup(arp, gratious_arp->iface);
2516 CTDB_NO_MEMORY(ctdb, arp->iface);
2519 event_add_timed(arp->ctdb->ev, arp,
2520 timeval_zero(), send_gratious_arp, arp);
2525 int32_t ctdb_control_add_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
2527 struct ctdb_control_ip_iface *pub = (struct ctdb_control_ip_iface *)indata.dptr;
2530 /* verify the size of indata */
2531 if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
2532 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
2536 ( offsetof(struct ctdb_control_ip_iface, iface)
2539 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
2540 "but should be %u bytes\n",
2541 (unsigned)indata.dsize,
2542 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+pub->len)));
2546 ret = ctdb_add_public_address(ctdb, &pub->addr, pub->mask, &pub->iface[0]);
2549 DEBUG(DEBUG_ERR,(__location__ " Failed to add public address\n"));
2557 called when releaseip event finishes for del_public_address
2559 static void delete_ip_callback(struct ctdb_context *ctdb, int status,
2562 talloc_free(private_data);
2565 int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
2567 struct ctdb_control_ip_iface *pub = (struct ctdb_control_ip_iface *)indata.dptr;
2568 struct ctdb_vnn *vnn;
2571 /* verify the size of indata */
2572 if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
2573 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
2577 ( offsetof(struct ctdb_control_ip_iface, iface)
2580 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
2581 "but should be %u bytes\n",
2582 (unsigned)indata.dsize,
2583 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+pub->len)));
2587 /* walk over all public addresses until we find a match */
2588 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
2589 if (ctdb_same_ip(&vnn->public_address, &pub->addr)) {
2590 TALLOC_CTX *mem_ctx;
2592 DLIST_REMOVE(ctdb->vnn, vnn);
2593 if (vnn->iface == NULL) {
2598 mem_ctx = talloc_new(ctdb);
2599 ret = ctdb_event_script_callback(ctdb,
2600 mem_ctx, delete_ip_callback, mem_ctx,
2602 CTDB_EVENT_RELEASE_IP,
2604 ctdb_vnn_iface_string(vnn),
2605 ctdb_addr_to_str(&vnn->public_address),
2606 vnn->public_netmask_bits);
2607 ctdb_vnn_unassign_iface(ctdb, vnn);