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
36 struct ctdb_takeover_arp {
37 struct ctdb_context *ctdb;
40 struct ctdb_tcp_array *tcparray;
46 lists of tcp endpoints
48 struct ctdb_tcp_list {
49 struct ctdb_tcp_list *prev, *next;
50 struct ctdb_tcp_connection connection;
54 list of clients to kill on IP release
56 struct ctdb_client_ip {
57 struct ctdb_client_ip *prev, *next;
58 struct ctdb_context *ctdb;
59 struct sockaddr_in ip;
67 static void ctdb_control_send_arp(struct event_context *ev, struct timed_event *te,
68 struct timeval t, void *private_data)
70 struct ctdb_takeover_arp *arp = talloc_get_type(private_data,
71 struct ctdb_takeover_arp);
73 struct ctdb_tcp_array *tcparray;
76 ret = ctdb_sys_send_arp(&arp->addr, arp->vnn->iface);
78 DEBUG(DEBUG_CRIT,(__location__ " sending of arp failed (%s)\n", strerror(errno)));
81 tcparray = arp->tcparray;
83 for (i=0;i<tcparray->num;i++) {
84 DEBUG(DEBUG_INFO,("sending tcp tickle ack for %u->%s:%u\n",
85 (unsigned)ntohs(tcparray->connections[i].daddr.sin_port),
86 inet_ntoa(tcparray->connections[i].saddr.sin_addr),
87 (unsigned)ntohs(tcparray->connections[i].saddr.sin_port)));
88 ret = ctdb_sys_send_tcp(
89 (ctdb_sock_addr *)&tcparray->connections[i].saddr,
90 (ctdb_sock_addr *)&tcparray->connections[i].daddr,
93 DEBUG(DEBUG_CRIT,(__location__ " Failed to send tcp tickle ack for %s\n",
94 inet_ntoa(tcparray->connections[i].saddr.sin_addr)));
101 if (arp->count == CTDB_ARP_REPEAT) {
106 event_add_timed(arp->ctdb->ev, arp->vnn->takeover_ctx,
107 timeval_current_ofs(CTDB_ARP_INTERVAL, 0),
108 ctdb_control_send_arp, arp);
111 struct takeover_callback_state {
112 struct ctdb_req_control *c;
113 ctdb_sock_addr *addr;
114 struct ctdb_vnn *vnn;
118 called when takeip event finishes
120 static void takeover_ip_callback(struct ctdb_context *ctdb, int status,
123 struct takeover_callback_state *state =
124 talloc_get_type(private_data, struct takeover_callback_state);
125 struct ctdb_takeover_arp *arp;
126 struct ctdb_tcp_array *tcparray;
131 if (inet_ntop(state->addr->sa.sa_family, &state->addr->sa.sa_data[0], ip, sizeof(ip)) == NULL) {
132 DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
135 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
136 ip, state->vnn->iface));
137 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
142 if (!state->vnn->takeover_ctx) {
143 state->vnn->takeover_ctx = talloc_new(ctdb);
144 if (!state->vnn->takeover_ctx) {
149 arp = talloc_zero(state->vnn->takeover_ctx, struct ctdb_takeover_arp);
150 if (!arp) goto failed;
153 arp->addr = *state->addr;
154 arp->vnn = state->vnn;
156 tcparray = state->vnn->tcp_array;
158 /* add all of the known tcp connections for this IP to the
159 list of tcp connections to send tickle acks for */
160 arp->tcparray = talloc_steal(arp, tcparray);
162 state->vnn->tcp_array = NULL;
163 state->vnn->tcp_update_needed = true;
166 event_add_timed(arp->ctdb->ev, state->vnn->takeover_ctx,
167 timeval_zero(), ctdb_control_send_arp, arp);
169 /* the control succeeded */
170 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
175 ctdb_request_control_reply(ctdb, state->c, NULL, -1, NULL);
181 Find the vnn of the node that has a public ip address
182 returns -1 if the address is not known as a public address
184 static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, struct sockaddr_in ip)
186 struct ctdb_vnn *vnn;
188 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
189 if (ctdb_same_ipv4(&vnn->public_address, &ip)) {
199 take over an ip address
201 int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
202 struct ctdb_req_control *c,
207 struct takeover_callback_state *state;
208 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
209 struct ctdb_vnn *vnn;
211 /* update out vnn list */
212 vnn = find_public_ip_vnn(ctdb, pip->sin);
214 DEBUG(DEBUG_ERR,("takeoverip called for an ip '%s' that is not a public address\n",
215 inet_ntoa(pip->sin.sin_addr)));
220 /* if our kernel already has this IP, do nothing */
221 if (ctdb_sys_have_ip(pip->sin)) {
225 state = talloc(ctdb, struct takeover_callback_state);
226 CTDB_NO_MEMORY(ctdb, state);
228 state->c = talloc_steal(ctdb, c);
229 state->addr = talloc(ctdb, ctdb_sock_addr);
230 CTDB_NO_MEMORY(ctdb, state->addr);
232 state->addr->ip = pip->sin; //qqq pip must be converted
235 DEBUG(DEBUG_NOTICE,("Takeover of IP %s/%u on interface %s\n",
236 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
239 ret = ctdb_event_script_callback(ctdb,
240 timeval_current_ofs(ctdb->tunable.script_timeout, 0),
241 state, takeover_ip_callback, state,
244 inet_ntoa(pip->sin.sin_addr),
245 vnn->public_netmask_bits);
248 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
249 inet_ntoa(pip->sin.sin_addr), vnn->iface));
254 /* tell ctdb_control.c that we will be replying asynchronously */
261 kill any clients that are registered with a IP that is being released
263 static void release_kill_clients(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
265 struct ctdb_client_ip *ip;
268 DEBUG(DEBUG_INFO,("release_kill_clients for ip %s\n", inet_ntop(addr->sa.sa_family, &addr->sa.sa_data[0], cip, sizeof(cip))));
270 for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
271 ctdb_sock_addr tmp_addr;
273 tmp_addr.ip = ip->ip; //qqq until ip->ip is no longer a sockaddr_in
274 DEBUG(DEBUG_INFO,("checking for client %u with IP %s\n",
275 ip->client_id, inet_ntoa(ip->ip.sin_addr)));
276 if (ctdb_same_ip(&tmp_addr, addr)) {
277 struct ctdb_client *client = ctdb_reqid_find(ctdb,
280 DEBUG(DEBUG_INFO,("matched client %u with IP %s and pid %u\n",
281 ip->client_id, inet_ntoa(ip->ip.sin_addr), client->pid));
282 if (client->pid != 0) {
283 DEBUG(DEBUG_INFO,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
284 (unsigned)client->pid,
285 inet_ntop(addr->sa.sa_family, &addr->sa.sa_data[0], cip, sizeof(cip)),
287 kill(client->pid, SIGKILL);
294 called when releaseip event finishes
296 static void release_ip_callback(struct ctdb_context *ctdb, int status,
299 struct takeover_callback_state *state =
300 talloc_get_type(private_data, struct takeover_callback_state);
304 /* send a message to all clients of this node telling them
305 that the cluster has been reconfigured and they should
306 release any sockets on this IP */
307 if (inet_ntop(state->addr->sa.sa_family, &state->addr->sa.sa_data[0], ip, sizeof(ip)) == NULL) {
308 DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
311 data.dptr = (uint8_t *)ip;
312 data.dsize = strlen(ip)+1;
314 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data);
316 /* kill clients that have registered with this IP */
317 release_kill_clients(ctdb, state->addr);
319 /* the control succeeded */
320 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
325 release an ip address
327 int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
328 struct ctdb_req_control *c,
333 struct takeover_callback_state *state;
334 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
335 struct ctdb_vnn *vnn;
337 /* update our vnn list */
338 vnn = find_public_ip_vnn(ctdb, pip->sin);
340 DEBUG(DEBUG_INFO,("releaseip called for an ip '%s' that is not a public address\n",
341 inet_ntoa(pip->sin.sin_addr)));
346 /* stop any previous arps */
347 talloc_free(vnn->takeover_ctx);
348 vnn->takeover_ctx = NULL;
350 if (!ctdb_sys_have_ip(pip->sin)) {
351 DEBUG(DEBUG_INFO,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
352 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
357 DEBUG(DEBUG_NOTICE,("Release of IP %s/%u on interface %s\n",
358 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
361 state = talloc(ctdb, struct takeover_callback_state);
362 CTDB_NO_MEMORY(ctdb, state);
364 state->c = talloc_steal(state, c);
365 state->addr = talloc(state, ctdb_sock_addr);
366 CTDB_NO_MEMORY(ctdb, state->addr);
367 state->addr->ip = pip->sin; //qqq pip must be converted
371 ret = ctdb_event_script_callback(ctdb,
372 timeval_current_ofs(ctdb->tunable.script_timeout, 0),
373 state, release_ip_callback, state,
374 "releaseip %s %s %u",
376 inet_ntoa(pip->sin.sin_addr),
377 vnn->public_netmask_bits);
379 DEBUG(DEBUG_ERR,(__location__ " Failed to release IP %s on interface %s\n",
380 inet_ntoa(pip->sin.sin_addr), vnn->iface));
385 /* tell the control that we will be reply asynchronously */
392 static int ctdb_add_public_address(struct ctdb_context *ctdb, struct sockaddr_in addr, unsigned mask, const char *iface)
394 struct ctdb_vnn *vnn;
396 /* Verify that we dont have an entry for this ip yet */
397 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
398 if (ctdb_same_sockaddr(&addr, &vnn->public_address)) {
399 DEBUG(DEBUG_CRIT,("Same ip '%s' specified multiple times in the public address list \n",
400 inet_ntoa(addr.sin_addr)));
405 /* create a new vnn structure for this ip address */
406 vnn = talloc_zero(ctdb, struct ctdb_vnn);
407 CTDB_NO_MEMORY_FATAL(ctdb, vnn);
408 vnn->iface = talloc_strdup(vnn, iface);
409 vnn->public_address = addr;
410 vnn->public_netmask_bits = mask;
413 DLIST_ADD(ctdb->vnn, vnn);
420 setup the event script directory
422 int ctdb_set_event_script_dir(struct ctdb_context *ctdb, const char *script_dir)
424 ctdb->event_script_dir = talloc_strdup(ctdb, script_dir);
425 CTDB_NO_MEMORY(ctdb, ctdb->event_script_dir);
430 setup the public address lists from a file
432 int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
438 lines = file_lines_load(alist, &nlines, ctdb);
440 ctdb_set_error(ctdb, "Failed to load public address list '%s'\n", alist);
443 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
447 for (i=0;i<nlines;i++) {
449 struct sockaddr_in addr;
453 tok = strtok(lines[i], " \t");
454 if (!tok || !parse_ip_mask(tok, &addr, &mask)) {
455 DEBUG(DEBUG_CRIT,("Badly formed line %u in public address list\n", i+1));
459 tok = strtok(NULL, " \t");
461 if (NULL == ctdb->default_public_interface) {
462 DEBUG(DEBUG_CRIT,("No default public interface and no interface specified at line %u of public address list\n",
467 iface = ctdb->default_public_interface;
472 if (ctdb_add_public_address(ctdb, addr, mask, iface)) {
473 DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
486 struct ctdb_public_ip_list {
487 struct ctdb_public_ip_list *next;
489 struct sockaddr_in sin;
493 /* Given a physical node, return the number of
494 public addresses that is currently assigned to this node.
496 static int node_ip_coverage(struct ctdb_context *ctdb,
498 struct ctdb_public_ip_list *ips)
502 for (;ips;ips=ips->next) {
503 if (ips->pnn == pnn) {
511 /* Check if this is a public ip known to the node, i.e. can that
512 node takeover this ip ?
514 static int can_node_serve_ip(struct ctdb_context *ctdb, int32_t pnn,
515 struct ctdb_public_ip_list *ip)
517 struct ctdb_all_public_ips *public_ips;
520 public_ips = ctdb->nodes[pnn]->public_ips;
522 if (public_ips == NULL) {
526 for (i=0;i<public_ips->num;i++) {
527 if (ip->sin.sin_addr.s_addr == public_ips->ips[i].sin.sin_addr.s_addr) {
528 /* yes, this node can serve this public ip */
537 /* search the node lists list for a node to takeover this ip.
538 pick the node that currently are serving the least number of ips
539 so that the ips get spread out evenly.
541 static int find_takeover_node(struct ctdb_context *ctdb,
542 struct ctdb_node_map *nodemap, uint32_t mask,
543 struct ctdb_public_ip_list *ip,
544 struct ctdb_public_ip_list *all_ips)
550 for (i=0;i<nodemap->num;i++) {
551 if (nodemap->nodes[i].flags & mask) {
552 /* This node is not healty and can not be used to serve
558 /* verify that this node can serve this ip */
559 if (can_node_serve_ip(ctdb, i, ip)) {
560 /* no it couldnt so skip to the next node */
564 num = node_ip_coverage(ctdb, i, all_ips);
565 /* was this the first node we checked ? */
577 DEBUG(DEBUG_WARNING,(__location__ " Could not find node to take over public address '%s'\n", inet_ntoa(ip->sin.sin_addr)));
585 struct ctdb_public_ip_list *
586 add_ip_to_merged_list(struct ctdb_context *ctdb,
588 struct ctdb_public_ip_list *ip_list,
589 struct ctdb_public_ip *ip)
591 struct ctdb_public_ip_list *tmp_ip;
593 /* do we already have this ip in our merged list ?*/
594 for (tmp_ip=ip_list;tmp_ip;tmp_ip=tmp_ip->next) {
596 /* we already have this public ip in the list */
597 if (tmp_ip->sin.sin_addr.s_addr == ip->sin.sin_addr.s_addr) {
602 /* this is a new public ip, we must add it to the list */
603 tmp_ip = talloc_zero(tmp_ctx, struct ctdb_public_ip_list);
604 CTDB_NO_MEMORY_NULL(ctdb, tmp_ip);
605 tmp_ip->pnn = ip->pnn;
606 tmp_ip->sin = ip->sin;
607 tmp_ip->next = ip_list;
612 struct ctdb_public_ip_list *
613 create_merged_ip_list(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx)
616 struct ctdb_public_ip_list *ip_list = NULL;
617 struct ctdb_all_public_ips *public_ips;
619 for (i=0;i<ctdb->num_nodes;i++) {
620 public_ips = ctdb->nodes[i]->public_ips;
622 /* there were no public ips for this node */
623 if (public_ips == NULL) {
627 for (j=0;j<public_ips->num;j++) {
628 ip_list = add_ip_to_merged_list(ctdb, tmp_ctx,
629 ip_list, &public_ips->ips[j]);
637 make any IP alias changes for public addresses that are necessary
639 int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
641 int i, num_healthy, retries;
642 struct ctdb_public_ip ip;
644 struct ctdb_public_ip_list *all_ips, *tmp_ip;
645 int maxnode, maxnum=0, minnode, minnum=0, num;
647 struct timeval timeout;
648 struct client_async_data *async_data;
649 struct ctdb_client_control_state *state;
650 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
655 /* Count how many completely healthy nodes we have */
657 for (i=0;i<nodemap->num;i++) {
658 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED))) {
663 if (num_healthy > 0) {
664 /* We have healthy nodes, so only consider them for
665 serving public addresses
667 mask = NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED;
669 /* We didnt have any completely healthy nodes so
670 use "disabled" nodes as a fallback
672 mask = NODE_FLAGS_INACTIVE;
675 /* since nodes only know about those public addresses that
676 can be served by that particular node, no single node has
677 a full list of all public addresses that exist in the cluster.
678 Walk over all node structures and create a merged list of
679 all public addresses that exist in the cluster.
681 all_ips = create_merged_ip_list(ctdb, tmp_ctx);
683 /* If we want deterministic ip allocations, i.e. that the ip addresses
684 will always be allocated the same way for a specific set of
685 available/unavailable nodes.
687 if (1 == ctdb->tunable.deterministic_public_ips) {
688 DEBUG(DEBUG_NOTICE,("Deterministic IPs enabled. Resetting all ip allocations\n"));
689 for (i=0,tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next,i++) {
690 tmp_ip->pnn = i%nodemap->num;
695 /* mark all public addresses with a masked node as being served by
698 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
699 if (tmp_ip->pnn == -1) {
702 if (nodemap->nodes[tmp_ip->pnn].flags & mask) {
707 /* verify that the assigned nodes can serve that public ip
708 and set it to -1 if not
710 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
711 if (tmp_ip->pnn == -1) {
714 if (can_node_serve_ip(ctdb, tmp_ip->pnn, tmp_ip) != 0) {
715 /* this node can not serve this ip. */
721 /* now we must redistribute all public addresses with takeover node
722 -1 among the nodes available
726 /* loop over all ip's and find a physical node to cover for
729 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
730 if (tmp_ip->pnn == -1) {
731 if (find_takeover_node(ctdb, nodemap, mask, tmp_ip, all_ips)) {
732 DEBUG(DEBUG_WARNING,("Failed to find node to cover ip %s\n", inet_ntoa(tmp_ip->sin.sin_addr)));
737 /* If we dont want ips to fail back after a node becomes healthy
738 again, we wont even try to reallocat the ip addresses so that
739 they are evenly spread out.
740 This can NOT be used at the same time as DeterministicIPs !
742 if (1 == ctdb->tunable.no_ip_failback) {
743 if (1 == ctdb->tunable.deterministic_public_ips) {
744 DEBUG(DEBUG_ERR, ("ERROR: You can not use 'DeterministicIPs' and 'NoIPFailback' at the same time\n"));
750 /* now, try to make sure the ip adresses are evenly distributed
752 for each ip address, loop over all nodes that can serve this
753 ip and make sure that the difference between the node
754 serving the most and the node serving the least ip's are not greater
757 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
758 if (tmp_ip->pnn == -1) {
762 /* Get the highest and lowest number of ips's served by any
763 valid node which can serve this ip.
767 for (i=0;i<nodemap->num;i++) {
768 if (nodemap->nodes[i].flags & mask) {
772 /* only check nodes that can actually serve this ip */
773 if (can_node_serve_ip(ctdb, i, tmp_ip)) {
774 /* no it couldnt so skip to the next node */
778 num = node_ip_coverage(ctdb, i, all_ips);
799 DEBUG(DEBUG_WARNING,(__location__ " Could not find maxnode. May not be able to serve ip '%s'\n", inet_ntoa(tmp_ip->sin.sin_addr)));
803 /* If we want deterministic IPs then dont try to reallocate
804 them to spread out the load.
806 if (1 == ctdb->tunable.deterministic_public_ips) {
810 /* if the spread between the smallest and largest coverage by
811 a node is >=2 we steal one of the ips from the node with
812 most coverage to even things out a bit.
813 try to do this at most 5 times since we dont want to spend
814 too much time balancing the ip coverage.
816 if ( (maxnum > minnum+1)
818 struct ctdb_public_ip_list *tmp;
820 /* mark one of maxnode's vnn's as unassigned and try
823 for (tmp=all_ips;tmp;tmp=tmp->next) {
824 if (tmp->pnn == maxnode) {
834 /* finished distributing the public addresses, now just send the
835 info out to the nodes
839 /* at this point ->pnn is the node which will own each IP
840 or -1 if there is no node that can cover this ip
843 /* now tell all nodes to delete any alias that they should not
844 have. This will be a NOOP on nodes that don't currently
845 hold the given alias */
846 async_data = talloc_zero(tmp_ctx, struct client_async_data);
847 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
849 for (i=0;i<nodemap->num;i++) {
850 /* don't talk to unconnected nodes, but do talk to banned nodes */
851 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
855 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
856 if (tmp_ip->pnn == nodemap->nodes[i].pnn) {
857 /* This node should be serving this
858 vnn so dont tell it to release the ip
862 ip.pnn = tmp_ip->pnn;
863 ip.sin.sin_family = AF_INET;
864 ip.sin.sin_addr = tmp_ip->sin.sin_addr;
866 timeout = TAKEOVER_TIMEOUT();
867 data.dsize = sizeof(ip);
868 data.dptr = (uint8_t *)&ip;
869 state = ctdb_control_send(ctdb, nodemap->nodes[i].pnn,
870 0, CTDB_CONTROL_RELEASE_IP, 0,
874 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_RELEASE_IP to node %u\n", nodemap->nodes[i].pnn));
875 talloc_free(tmp_ctx);
879 ctdb_client_async_add(async_data, state);
882 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
883 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_RELEASE_IP failed\n"));
884 talloc_free(tmp_ctx);
887 talloc_free(async_data);
890 /* tell all nodes to get their own IPs */
891 async_data = talloc_zero(tmp_ctx, struct client_async_data);
892 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
893 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
894 if (tmp_ip->pnn == -1) {
895 /* this IP won't be taken over */
898 ip.pnn = tmp_ip->pnn;
899 ip.sin.sin_family = AF_INET;
900 ip.sin.sin_addr = tmp_ip->sin.sin_addr;
902 timeout = TAKEOVER_TIMEOUT();
903 data.dsize = sizeof(ip);
904 data.dptr = (uint8_t *)&ip;
905 state = ctdb_control_send(ctdb, tmp_ip->pnn,
906 0, CTDB_CONTROL_TAKEOVER_IP, 0,
910 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_TAKEOVER_IP to node %u\n", tmp_ip->pnn));
911 talloc_free(tmp_ctx);
915 ctdb_client_async_add(async_data, state);
917 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
918 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_TAKEOVER_IP failed\n"));
919 talloc_free(tmp_ctx);
923 talloc_free(tmp_ctx);
929 destroy a ctdb_client_ip structure
931 static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
933 DEBUG(DEBUG_DEBUG,("destroying client tcp for %s:%u (client_id %u)\n",
934 inet_ntoa(ip->ip.sin_addr), ntohs(ip->ip.sin_port), ip->client_id));
935 DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
940 called by a client to inform us of a TCP connection that it is managing
941 that should tickled with an ACK when IP takeover is done
943 int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
946 struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
947 struct ctdb_control_tcp *p = (struct ctdb_control_tcp *)indata.dptr;
948 struct ctdb_tcp_list *tcp;
949 struct ctdb_control_tcp_vnn t;
952 struct ctdb_client_ip *ip;
953 struct ctdb_vnn *vnn;
955 vnn = find_public_ip_vnn(ctdb, p->dest);
957 if (ntohl(p->dest.sin_addr.s_addr) != INADDR_LOOPBACK) {
958 DEBUG(DEBUG_INFO,("Could not add client IP %s. This is not a public address.\n",
959 inet_ntoa(p->dest.sin_addr)));
964 if (vnn->pnn != ctdb->pnn) {
965 DEBUG(DEBUG_ERR,("Attempt to register tcp client for IP %s we don't hold - failing (client_id %u pid %u)\n",
966 inet_ntoa(p->dest.sin_addr),
967 client_id, client->pid));
968 /* failing this call will tell smbd to die */
972 ip = talloc(client, struct ctdb_client_ip);
973 CTDB_NO_MEMORY(ctdb, ip);
977 ip->client_id = client_id;
978 talloc_set_destructor(ip, ctdb_client_ip_destructor);
979 DLIST_ADD(ctdb->client_ip_list, ip);
981 tcp = talloc(client, struct ctdb_tcp_list);
982 CTDB_NO_MEMORY(ctdb, tcp);
984 tcp->connection.saddr = p->src;
985 tcp->connection.daddr = p->dest;
987 DLIST_ADD(client->tcp_list, tcp);
992 data.dptr = (uint8_t *)&t;
993 data.dsize = sizeof(t);
995 DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
996 (unsigned)ntohs(p->dest.sin_port),
997 inet_ntoa(p->src.sin_addr),
998 (unsigned)ntohs(p->src.sin_port), client_id, client->pid));
1000 /* tell all nodes about this tcp connection */
1001 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
1002 CTDB_CONTROL_TCP_ADD,
1003 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1005 DEBUG(DEBUG_ERR,(__location__ " Failed to send CTDB_CONTROL_TCP_ADD\n"));
1013 see if two sockaddr_in are the same
1015 static bool same_sockaddr_in(struct sockaddr_in *in1, struct sockaddr_in *in2)
1017 return in1->sin_family == in2->sin_family &&
1018 in1->sin_port == in2->sin_port &&
1019 in1->sin_addr.s_addr == in2->sin_addr.s_addr;
1023 find a tcp address on a list
1025 static struct ctdb_tcp_connection *ctdb_tcp_find(struct ctdb_tcp_array *array,
1026 struct ctdb_tcp_connection *tcp)
1030 if (array == NULL) {
1034 for (i=0;i<array->num;i++) {
1035 if (same_sockaddr_in(&array->connections[i].saddr, &tcp->saddr) &&
1036 same_sockaddr_in(&array->connections[i].daddr, &tcp->daddr)) {
1037 return &array->connections[i];
1044 called by a daemon to inform us of a TCP connection that one of its
1045 clients managing that should tickled with an ACK when IP takeover is
1048 int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
1050 struct ctdb_control_tcp_vnn *p = (struct ctdb_control_tcp_vnn *)indata.dptr;
1051 struct ctdb_tcp_array *tcparray;
1052 struct ctdb_tcp_connection tcp;
1053 struct ctdb_vnn *vnn;
1055 vnn = find_public_ip_vnn(ctdb, p->dest);
1057 DEBUG(DEBUG_ERR,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
1058 inet_ntoa(p->dest.sin_addr)));
1063 tcparray = vnn->tcp_array;
1065 /* If this is the first tickle */
1066 if (tcparray == NULL) {
1067 tcparray = talloc_size(ctdb->nodes,
1068 offsetof(struct ctdb_tcp_array, connections) +
1069 sizeof(struct ctdb_tcp_connection) * 1);
1070 CTDB_NO_MEMORY(ctdb, tcparray);
1071 vnn->tcp_array = tcparray;
1074 tcparray->connections = talloc_size(tcparray, sizeof(struct ctdb_tcp_connection));
1075 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1077 tcparray->connections[tcparray->num].saddr = p->src;
1078 tcparray->connections[tcparray->num].daddr = p->dest;
1084 /* Do we already have this tickle ?*/
1086 tcp.daddr = p->dest;
1087 if (ctdb_tcp_find(vnn->tcp_array, &tcp) != NULL) {
1088 DEBUG(DEBUG_DEBUG,("Already had tickle info for %s:%u for vnn:%u\n",
1089 inet_ntoa(tcp.daddr.sin_addr),
1090 ntohs(tcp.daddr.sin_port),
1095 /* A new tickle, we must add it to the array */
1096 tcparray->connections = talloc_realloc(tcparray, tcparray->connections,
1097 struct ctdb_tcp_connection,
1099 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1101 vnn->tcp_array = tcparray;
1102 tcparray->connections[tcparray->num].saddr = p->src;
1103 tcparray->connections[tcparray->num].daddr = p->dest;
1106 DEBUG(DEBUG_INFO,("Added tickle info for %s:%u from vnn %u\n",
1107 inet_ntoa(tcp.daddr.sin_addr),
1108 ntohs(tcp.daddr.sin_port),
1116 called by a daemon to inform us of a TCP connection that one of its
1117 clients managing that should tickled with an ACK when IP takeover is
1120 static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tcp_connection *conn)
1122 struct ctdb_tcp_connection *tcpp;
1123 struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, conn->daddr);
1126 DEBUG(DEBUG_ERR,(__location__ " unable to find public address %s\n", inet_ntoa(conn->daddr.sin_addr)));
1130 /* if the array is empty we cant remove it
1131 and we dont need to do anything
1133 if (vnn->tcp_array == NULL) {
1134 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist (array is empty) %s:%u\n",
1135 inet_ntoa(conn->daddr.sin_addr),
1136 ntohs(conn->daddr.sin_port)));
1141 /* See if we know this connection
1142 if we dont know this connection then we dont need to do anything
1144 tcpp = ctdb_tcp_find(vnn->tcp_array, conn);
1146 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist %s:%u\n",
1147 inet_ntoa(conn->daddr.sin_addr),
1148 ntohs(conn->daddr.sin_port)));
1153 /* We need to remove this entry from the array.
1154 Instead of allocating a new array and copying data to it
1155 we cheat and just copy the last entry in the existing array
1156 to the entry that is to be removed and just shring the
1159 *tcpp = vnn->tcp_array->connections[vnn->tcp_array->num - 1];
1160 vnn->tcp_array->num--;
1162 /* If we deleted the last entry we also need to remove the entire array
1164 if (vnn->tcp_array->num == 0) {
1165 talloc_free(vnn->tcp_array);
1166 vnn->tcp_array = NULL;
1169 vnn->tcp_update_needed = true;
1171 DEBUG(DEBUG_INFO,("Removed tickle info for %s:%u\n",
1172 inet_ntoa(conn->saddr.sin_addr),
1173 ntohs(conn->saddr.sin_port)));
1178 called when a daemon restarts - send all tickes for all public addresses
1179 we are serving immediately to the new node.
1181 int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t vnn)
1183 /*XXX here we should send all tickes we are serving to the new node */
1189 called when a client structure goes away - hook to remove
1190 elements from the tcp_list in all daemons
1192 void ctdb_takeover_client_destructor_hook(struct ctdb_client *client)
1194 while (client->tcp_list) {
1195 struct ctdb_tcp_list *tcp = client->tcp_list;
1196 DLIST_REMOVE(client->tcp_list, tcp);
1197 ctdb_remove_tcp_connection(client->ctdb, &tcp->connection);
1203 release all IPs on shutdown
1205 void ctdb_release_all_ips(struct ctdb_context *ctdb)
1207 struct ctdb_vnn *vnn;
1209 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1210 if (!ctdb_sys_have_ip(vnn->public_address)) {
1213 ctdb_event_script(ctdb, "releaseip %s %s %u",
1215 inet_ntoa(vnn->public_address.sin_addr),
1216 vnn->public_netmask_bits);
1217 // convert when vnn->public_address is no longer a sockaddr_in
1218 release_kill_clients(ctdb, (ctdb_sock_addr *)&vnn->public_address);
1224 get list of public IPs
1226 int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb,
1227 struct ctdb_req_control *c, TDB_DATA *outdata)
1230 struct ctdb_all_public_ips *ips;
1231 struct ctdb_vnn *vnn;
1233 /* count how many public ip structures we have */
1235 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1239 len = offsetof(struct ctdb_all_public_ips, ips) +
1240 num*sizeof(struct ctdb_public_ip);
1241 ips = talloc_zero_size(outdata, len);
1242 CTDB_NO_MEMORY(ctdb, ips);
1244 outdata->dsize = len;
1245 outdata->dptr = (uint8_t *)ips;
1249 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1250 ips->ips[i].pnn = vnn->pnn;
1251 ips->ips[i].sin = vnn->public_address;
1261 structure containing the listening socket and the list of tcp connections
1262 that the ctdb daemon is to kill
1264 struct ctdb_kill_tcp {
1265 struct ctdb_vnn *vnn;
1266 struct ctdb_context *ctdb;
1268 struct fd_event *fde;
1269 trbt_tree_t *connections;
1274 a tcp connection that is to be killed
1276 struct ctdb_killtcp_con {
1277 struct sockaddr_in src;
1278 struct sockaddr_in dst;
1280 struct ctdb_kill_tcp *killtcp;
1283 /* this function is used to create a key to represent this socketpair
1284 in the killtcp tree.
1285 this key is used to insert and lookup matching socketpairs that are
1286 to be tickled and RST
1288 #define KILLTCP_KEYLEN 4
1289 static uint32_t *killtcp_key(struct sockaddr_in *src, struct sockaddr_in *dst)
1291 static uint32_t key[KILLTCP_KEYLEN];
1293 key[0] = dst->sin_addr.s_addr;
1294 key[1] = src->sin_addr.s_addr;
1295 key[2] = dst->sin_port;
1296 key[3] = src->sin_port;
1302 called when we get a read event on the raw socket
1304 static void capture_tcp_handler(struct event_context *ev, struct fd_event *fde,
1305 uint16_t flags, void *private_data)
1307 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
1308 struct ctdb_killtcp_con *con;
1309 struct sockaddr_in src, dst;
1310 uint32_t ack_seq, seq;
1312 if (!(flags & EVENT_FD_READ)) {
1316 if (ctdb_sys_read_tcp_packet(killtcp->capture_fd,
1317 killtcp->private_data,
1319 &ack_seq, &seq) != 0) {
1320 /* probably a non-tcp ACK packet */
1324 /* check if we have this guy in our list of connections
1327 con = trbt_lookuparray32(killtcp->connections,
1328 KILLTCP_KEYLEN, killtcp_key(&src, &dst));
1330 /* no this was some other packet we can just ignore */
1334 /* This one has been tickled !
1335 now reset him and remove him from the list.
1337 DEBUG(DEBUG_INFO, ("sending a tcp reset to kill connection :%d -> %s:%d\n", ntohs(con->dst.sin_port), inet_ntoa(con->src.sin_addr), ntohs(con->src.sin_port)));
1340 (ctdb_sock_addr *)&con->dst,
1341 (ctdb_sock_addr *)&con->src,
1347 /* when traversing the list of all tcp connections to send tickle acks to
1348 (so that we can capture the ack coming back and kill the connection
1350 this callback is called for each connection we are currently trying to kill
1352 static void tickle_connection_traverse(void *param, void *data)
1354 struct ctdb_killtcp_con *con = talloc_get_type(data, struct ctdb_killtcp_con);
1356 /* have tried too many times, just give up */
1357 if (con->count >= 5) {
1362 /* othervise, try tickling it again */
1365 (ctdb_sock_addr *)&con->dst,
1366 (ctdb_sock_addr *)&con->src,
1372 called every second until all sentenced connections have been reset
1374 static void ctdb_tickle_sentenced_connections(struct event_context *ev, struct timed_event *te,
1375 struct timeval t, void *private_data)
1377 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
1380 /* loop over all connections sending tickle ACKs */
1381 trbt_traversearray32(killtcp->connections, KILLTCP_KEYLEN, tickle_connection_traverse, NULL);
1384 /* If there are no more connections to kill we can remove the
1385 entire killtcp structure
1387 if ( (killtcp->connections == NULL) ||
1388 (killtcp->connections->root == NULL) ) {
1389 talloc_free(killtcp);
1393 /* try tickling them again in a seconds time
1395 event_add_timed(killtcp->ctdb->ev, killtcp, timeval_current_ofs(1, 0),
1396 ctdb_tickle_sentenced_connections, killtcp);
1400 destroy the killtcp structure
1402 static int ctdb_killtcp_destructor(struct ctdb_kill_tcp *killtcp)
1404 killtcp->vnn->killtcp = NULL;
1409 /* nothing fancy here, just unconditionally replace any existing
1410 connection structure with the new one.
1412 dont even free the old one if it did exist, that one is talloc_stolen
1413 by the same node in the tree anyway and will be deleted when the new data
1416 static void *add_killtcp_callback(void *parm, void *data)
1422 add a tcp socket to the list of connections we want to RST
1424 static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
1425 struct sockaddr_in *src, struct sockaddr_in *dst)
1427 struct ctdb_kill_tcp *killtcp;
1428 struct ctdb_killtcp_con *con;
1429 struct ctdb_vnn *vnn;
1431 vnn = find_public_ip_vnn(ctdb, *dst);
1433 vnn = find_public_ip_vnn(ctdb, *src);
1436 /* if it is not a public ip it could be our 'single ip' */
1437 if (ctdb->single_ip_vnn) {
1438 if (ctdb_same_ipv4(&ctdb->single_ip_vnn->public_address, dst)) {
1439 vnn = ctdb->single_ip_vnn;
1444 DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n"));
1448 killtcp = vnn->killtcp;
1450 /* If this is the first connection to kill we must allocate
1453 if (killtcp == NULL) {
1454 killtcp = talloc_zero(ctdb, struct ctdb_kill_tcp);
1455 CTDB_NO_MEMORY(ctdb, killtcp);
1458 killtcp->ctdb = ctdb;
1459 killtcp->capture_fd = -1;
1460 killtcp->connections = trbt_create(killtcp, 0);
1462 vnn->killtcp = killtcp;
1463 talloc_set_destructor(killtcp, ctdb_killtcp_destructor);
1468 /* create a structure that describes this connection we want to
1469 RST and store it in killtcp->connections
1471 con = talloc(killtcp, struct ctdb_killtcp_con);
1472 CTDB_NO_MEMORY(ctdb, con);
1476 con->killtcp = killtcp;
1479 trbt_insertarray32_callback(killtcp->connections,
1480 KILLTCP_KEYLEN, killtcp_key(&con->dst, &con->src),
1481 add_killtcp_callback, con);
1484 If we dont have a socket to listen on yet we must create it
1486 if (killtcp->capture_fd == -1) {
1487 killtcp->capture_fd = ctdb_sys_open_capture_socket(vnn->iface, &killtcp->private_data);
1488 if (killtcp->capture_fd == -1) {
1489 DEBUG(DEBUG_CRIT,(__location__ " Failed to open capturing socket for killtcp\n"));
1495 if (killtcp->fde == NULL) {
1496 killtcp->fde = event_add_fd(ctdb->ev, killtcp, killtcp->capture_fd,
1497 EVENT_FD_READ | EVENT_FD_AUTOCLOSE,
1498 capture_tcp_handler, killtcp);
1500 /* We also need to set up some events to tickle all these connections
1501 until they are all reset
1503 event_add_timed(ctdb->ev, killtcp, timeval_current_ofs(1, 0),
1504 ctdb_tickle_sentenced_connections, killtcp);
1507 /* tickle him once now */
1509 (ctdb_sock_addr *)&con->dst,
1510 (ctdb_sock_addr *)&con->src,
1516 talloc_free(vnn->killtcp);
1517 vnn->killtcp = NULL;
1522 kill a TCP connection.
1524 int32_t ctdb_control_kill_tcp(struct ctdb_context *ctdb, TDB_DATA indata)
1526 struct ctdb_control_killtcp *killtcp = (struct ctdb_control_killtcp *)indata.dptr;
1528 return ctdb_killtcp_add_connection(ctdb, &killtcp->src, &killtcp->dst);
1532 called by a daemon to inform us of the entire list of TCP tickles for
1533 a particular public address.
1534 this control should only be sent by the node that is currently serving
1535 that public address.
1537 int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata)
1539 struct ctdb_control_tcp_tickle_list *list = (struct ctdb_control_tcp_tickle_list *)indata.dptr;
1540 struct ctdb_tcp_array *tcparray;
1541 struct ctdb_vnn *vnn;
1543 /* We must at least have tickles.num or else we cant verify the size
1544 of the received data blob
1546 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
1547 tickles.connections)) {
1548 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list. Not enough data for the tickle.num field\n"));
1552 /* verify that the size of data matches what we expect */
1553 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
1554 tickles.connections)
1555 + sizeof(struct ctdb_tcp_connection)
1556 * list->tickles.num) {
1557 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list\n"));
1561 vnn = find_public_ip_vnn(ctdb, list->ip);
1563 DEBUG(DEBUG_INFO,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n",
1564 inet_ntoa(list->ip.sin_addr)));
1568 /* remove any old ticklelist we might have */
1569 talloc_free(vnn->tcp_array);
1570 vnn->tcp_array = NULL;
1572 tcparray = talloc(ctdb->nodes, struct ctdb_tcp_array);
1573 CTDB_NO_MEMORY(ctdb, tcparray);
1575 tcparray->num = list->tickles.num;
1577 tcparray->connections = talloc_array(tcparray, struct ctdb_tcp_connection, tcparray->num);
1578 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1580 memcpy(tcparray->connections, &list->tickles.connections[0],
1581 sizeof(struct ctdb_tcp_connection)*tcparray->num);
1583 /* We now have a new fresh tickle list array for this vnn */
1584 vnn->tcp_array = talloc_steal(vnn, tcparray);
1590 called to return the full list of tickles for the puclic address associated
1591 with the provided vnn
1593 int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata)
1595 struct sockaddr_in *ip = (struct sockaddr_in *)indata.dptr;
1596 struct ctdb_control_tcp_tickle_list *list;
1597 struct ctdb_tcp_array *tcparray;
1599 struct ctdb_vnn *vnn;
1601 vnn = find_public_ip_vnn(ctdb, *ip);
1603 DEBUG(DEBUG_ERR,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n",
1604 inet_ntoa(ip->sin_addr)));
1608 tcparray = vnn->tcp_array;
1610 num = tcparray->num;
1615 outdata->dsize = offsetof(struct ctdb_control_tcp_tickle_list,
1616 tickles.connections)
1617 + sizeof(struct ctdb_tcp_connection) * num;
1619 outdata->dptr = talloc_size(outdata, outdata->dsize);
1620 CTDB_NO_MEMORY(ctdb, outdata->dptr);
1621 list = (struct ctdb_control_tcp_tickle_list *)outdata->dptr;
1624 list->tickles.num = num;
1626 memcpy(&list->tickles.connections[0], tcparray->connections,
1627 sizeof(struct ctdb_tcp_connection) * num);
1635 set the list of all tcp tickles for a public address
1637 static int ctdb_ctrl_set_tcp_tickles(struct ctdb_context *ctdb,
1638 struct timeval timeout, uint32_t destnode,
1639 struct sockaddr_in *ip,
1640 struct ctdb_tcp_array *tcparray)
1644 struct ctdb_control_tcp_tickle_list *list;
1647 num = tcparray->num;
1652 data.dsize = offsetof(struct ctdb_control_tcp_tickle_list,
1653 tickles.connections) +
1654 sizeof(struct ctdb_tcp_connection) * num;
1655 data.dptr = talloc_size(ctdb, data.dsize);
1656 CTDB_NO_MEMORY(ctdb, data.dptr);
1658 list = (struct ctdb_control_tcp_tickle_list *)data.dptr;
1660 list->tickles.num = num;
1662 memcpy(&list->tickles.connections[0], tcparray->connections, sizeof(struct ctdb_tcp_connection) * num);
1665 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
1666 CTDB_CONTROL_SET_TCP_TICKLE_LIST,
1667 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1669 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set tcp tickles failed\n"));
1673 talloc_free(data.dptr);
1680 perform tickle updates if required
1682 static void ctdb_update_tcp_tickles(struct event_context *ev,
1683 struct timed_event *te,
1684 struct timeval t, void *private_data)
1686 struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
1688 struct ctdb_vnn *vnn;
1690 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1691 /* we only send out updates for public addresses that
1694 if (ctdb->pnn != vnn->pnn) {
1697 /* We only send out the updates if we need to */
1698 if (!vnn->tcp_update_needed) {
1701 ret = ctdb_ctrl_set_tcp_tickles(ctdb,
1703 CTDB_BROADCAST_CONNECTED,
1704 &vnn->public_address,
1707 DEBUG(DEBUG_ERR,("Failed to send the tickle update for public address %s\n",
1708 inet_ntoa(vnn->public_address.sin_addr)));
1712 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
1713 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
1714 ctdb_update_tcp_tickles, ctdb);
1719 start periodic update of tcp tickles
1721 void ctdb_start_tcp_tickle_update(struct ctdb_context *ctdb)
1723 ctdb->tickle_update_context = talloc_new(ctdb);
1725 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
1726 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
1727 ctdb_update_tcp_tickles, ctdb);
1733 struct control_gratious_arp {
1734 struct ctdb_context *ctdb;
1735 ctdb_sock_addr addr;
1741 send a control_gratuitous arp
1743 static void send_gratious_arp(struct event_context *ev, struct timed_event *te,
1744 struct timeval t, void *private_data)
1747 struct control_gratious_arp *arp = talloc_get_type(private_data,
1748 struct control_gratious_arp);
1750 ret = ctdb_sys_send_arp(&arp->addr, arp->iface);
1752 DEBUG(DEBUG_ERR,(__location__ " sending of gratious arp failed (%s)\n", strerror(errno)));
1757 if (arp->count == CTDB_ARP_REPEAT) {
1762 event_add_timed(arp->ctdb->ev, arp,
1763 timeval_current_ofs(CTDB_ARP_INTERVAL, 0),
1764 send_gratious_arp, arp);
1771 int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indata)
1773 struct ctdb_control_gratious_arp *gratious_arp = (struct ctdb_control_gratious_arp *)indata.dptr;
1774 struct control_gratious_arp *arp;
1776 /* verify the size of indata */
1777 if (indata.dsize < offsetof(struct ctdb_control_gratious_arp, iface)) {
1778 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_gratious_arp structure. Got %u require %u bytes\n", indata.dsize, offsetof(struct ctdb_control_gratious_arp, iface)));
1782 ( offsetof(struct ctdb_control_gratious_arp, iface)
1783 + gratious_arp->len ) ){
1785 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
1786 "but should be %u bytes\n",
1787 (unsigned)indata.dsize,
1788 (unsigned)(offsetof(struct ctdb_control_gratious_arp, iface)+gratious_arp->len)));
1793 arp = talloc(ctdb, struct control_gratious_arp);
1794 CTDB_NO_MEMORY(ctdb, arp);
1797 arp->addr = gratious_arp->addr;
1798 arp->iface = talloc_strdup(arp, gratious_arp->iface);
1799 CTDB_NO_MEMORY(ctdb, arp->iface);
1802 event_add_timed(arp->ctdb->ev, arp,
1803 timeval_zero(), send_gratious_arp, arp);
1808 int32_t ctdb_control_add_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
1810 struct ctdb_control_ip_iface *pub = (struct ctdb_control_ip_iface *)indata.dptr;
1813 /* verify the size of indata */
1814 if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
1815 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
1819 ( offsetof(struct ctdb_control_ip_iface, iface)
1822 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
1823 "but should be %u bytes\n",
1824 (unsigned)indata.dsize,
1825 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+pub->len)));
1829 return ctdb_add_public_address(ctdb, pub->sin, pub->mask, &pub->iface[0]);
1833 called when releaseip event finishes for del_public_address
1835 static void delete_ip_callback(struct ctdb_context *ctdb, int status,
1838 talloc_free(private_data);
1841 int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
1843 struct ctdb_control_ip_iface *pub = (struct ctdb_control_ip_iface *)indata.dptr;
1844 struct ctdb_vnn *vnn;
1847 /* verify the size of indata */
1848 if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
1849 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
1853 ( offsetof(struct ctdb_control_ip_iface, iface)
1856 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
1857 "but should be %u bytes\n",
1858 (unsigned)indata.dsize,
1859 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+pub->len)));
1863 /* walk over all public addresses until we find a match */
1864 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1865 if (ctdb_same_ipv4(&vnn->public_address, &pub->sin)) {
1866 TALLOC_CTX *mem_ctx = talloc_new(ctdb);
1868 DLIST_REMOVE(ctdb->vnn, vnn);
1870 ret = ctdb_event_script_callback(ctdb,
1871 timeval_current_ofs(ctdb->tunable.script_timeout, 0),
1872 mem_ctx, delete_ip_callback, mem_ctx,
1873 "releaseip %s %s %u",
1875 inet_ntoa(vnn->public_address.sin_addr),
1876 vnn->public_netmask_bits);