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;
39 struct sockaddr_in sin;
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->sin, 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 struct sockaddr_in *sin;
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 char *ip = inet_ntoa(state->sin->sin_addr);
127 struct ctdb_tcp_array *tcparray;
129 ctdb_enable_monitoring(ctdb);
132 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
133 ip, state->vnn->iface));
134 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
139 if (!state->vnn->takeover_ctx) {
140 state->vnn->takeover_ctx = talloc_new(ctdb);
141 if (!state->vnn->takeover_ctx) {
146 arp = talloc_zero(state->vnn->takeover_ctx, struct ctdb_takeover_arp);
147 if (!arp) goto failed;
150 arp->sin = *state->sin;
151 arp->vnn = state->vnn;
153 tcparray = state->vnn->tcp_array;
155 /* add all of the known tcp connections for this IP to the
156 list of tcp connections to send tickle acks for */
157 arp->tcparray = talloc_steal(arp, tcparray);
159 state->vnn->tcp_array = NULL;
160 state->vnn->tcp_update_needed = true;
163 event_add_timed(arp->ctdb->ev, state->vnn->takeover_ctx,
164 timeval_zero(), ctdb_control_send_arp, arp);
166 /* the control succeeded */
167 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
172 ctdb_request_control_reply(ctdb, state->c, NULL, -1, NULL);
178 Find the vnn of the node that has a public ip address
179 returns -1 if the address is not known as a public address
181 static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, struct sockaddr_in ip)
183 struct ctdb_vnn *vnn;
185 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
186 if (ctdb_same_ip(&vnn->public_address, &ip)) {
196 take over an ip address
198 int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
199 struct ctdb_req_control *c,
204 struct takeover_callback_state *state;
205 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
206 struct ctdb_vnn *vnn;
208 /* update out vnn list */
209 vnn = find_public_ip_vnn(ctdb, pip->sin);
211 DEBUG(DEBUG_ERR,("takeoverip called for an ip '%s' that is not a public address\n",
212 inet_ntoa(pip->sin.sin_addr)));
217 /* if our kernel already has this IP, do nothing */
218 if (ctdb_sys_have_ip(pip->sin)) {
222 state = talloc(ctdb, struct takeover_callback_state);
223 CTDB_NO_MEMORY(ctdb, state);
225 state->c = talloc_steal(ctdb, c);
226 state->sin = talloc(ctdb, struct sockaddr_in);
227 CTDB_NO_MEMORY(ctdb, state->sin);
228 *state->sin = pip->sin;
232 DEBUG(DEBUG_NOTICE,("Takeover of IP %s/%u on interface %s\n",
233 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
236 ctdb_disable_monitoring(ctdb);
238 ret = ctdb_event_script_callback(ctdb,
239 timeval_current_ofs(ctdb->tunable.script_timeout, 0),
240 state, takeover_ip_callback, state,
243 inet_ntoa(pip->sin.sin_addr),
244 vnn->public_netmask_bits);
247 ctdb_enable_monitoring(ctdb);
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, struct sockaddr_in in)
265 struct ctdb_client_ip *ip;
267 DEBUG(DEBUG_INFO,("release_kill_clients for ip %s\n", inet_ntoa(in.sin_addr)));
269 for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
270 DEBUG(DEBUG_INFO,("checking for client %u with IP %s\n",
271 ip->client_id, inet_ntoa(ip->ip.sin_addr)));
272 if (ctdb_same_ip(&ip->ip, &in)) {
273 struct ctdb_client *client = ctdb_reqid_find(ctdb,
276 DEBUG(DEBUG_INFO,("matched client %u with IP %s and pid %u\n",
277 ip->client_id, inet_ntoa(ip->ip.sin_addr), client->pid));
278 if (client->pid != 0) {
279 DEBUG(DEBUG_INFO,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
280 (unsigned)client->pid, inet_ntoa(in.sin_addr),
282 kill(client->pid, SIGKILL);
289 called when releaseip event finishes
291 static void release_ip_callback(struct ctdb_context *ctdb, int status,
294 struct takeover_callback_state *state =
295 talloc_get_type(private_data, struct takeover_callback_state);
296 char *ip = inet_ntoa(state->sin->sin_addr);
299 ctdb_enable_monitoring(ctdb);
301 /* send a message to all clients of this node telling them
302 that the cluster has been reconfigured and they should
303 release any sockets on this IP */
304 data.dptr = (uint8_t *)ip;
305 data.dsize = strlen(ip)+1;
307 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data);
309 /* kill clients that have registered with this IP */
310 release_kill_clients(ctdb, *state->sin);
312 /* the control succeeded */
313 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
318 release an ip address
320 int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
321 struct ctdb_req_control *c,
326 struct takeover_callback_state *state;
327 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
328 struct ctdb_vnn *vnn;
330 /* update our vnn list */
331 vnn = find_public_ip_vnn(ctdb, pip->sin);
333 DEBUG(DEBUG_ERR,("releaseip called for an ip '%s' that is not a public address\n",
334 inet_ntoa(pip->sin.sin_addr)));
339 /* stop any previous arps */
340 talloc_free(vnn->takeover_ctx);
341 vnn->takeover_ctx = NULL;
343 if (!ctdb_sys_have_ip(pip->sin)) {
344 DEBUG(DEBUG_INFO,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
345 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
350 DEBUG(DEBUG_NOTICE,("Release of IP %s/%u on interface %s\n",
351 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
354 state = talloc(ctdb, struct takeover_callback_state);
355 CTDB_NO_MEMORY(ctdb, state);
357 state->c = talloc_steal(state, c);
358 state->sin = talloc(state, struct sockaddr_in);
359 CTDB_NO_MEMORY(ctdb, state->sin);
360 *state->sin = pip->sin;
364 ctdb_disable_monitoring(ctdb);
366 ret = ctdb_event_script_callback(ctdb,
367 timeval_current_ofs(ctdb->tunable.script_timeout, 0),
368 state, release_ip_callback, state,
369 "releaseip %s %s %u",
371 inet_ntoa(pip->sin.sin_addr),
372 vnn->public_netmask_bits);
374 ctdb_enable_monitoring(ctdb);
376 DEBUG(DEBUG_ERR,(__location__ " Failed to release IP %s on interface %s\n",
377 inet_ntoa(pip->sin.sin_addr), vnn->iface));
382 /* tell the control that we will be reply asynchronously */
389 static int ctdb_add_public_address(struct ctdb_context *ctdb, struct sockaddr_in addr, unsigned mask, const char *iface)
391 struct ctdb_vnn *vnn;
393 /* Verify that we dont have an entry for this ip yet */
394 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
395 if (ctdb_same_sockaddr(&addr, &vnn->public_address)) {
396 DEBUG(DEBUG_CRIT,("Same ip '%s' specified multiple times in the public address list \n",
397 inet_ntoa(addr.sin_addr)));
402 /* create a new vnn structure for this ip address */
403 vnn = talloc_zero(ctdb, struct ctdb_vnn);
404 CTDB_NO_MEMORY_FATAL(ctdb, vnn);
405 vnn->iface = talloc_strdup(vnn, iface);
406 vnn->public_address = addr;
407 vnn->public_netmask_bits = mask;
410 DLIST_ADD(ctdb->vnn, vnn);
417 setup the event script directory
419 int ctdb_set_event_script_dir(struct ctdb_context *ctdb, const char *script_dir)
421 ctdb->event_script_dir = talloc_strdup(ctdb, script_dir);
422 CTDB_NO_MEMORY(ctdb, ctdb->event_script_dir);
427 setup the public address lists from a file
429 int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
435 lines = file_lines_load(alist, &nlines, ctdb);
437 ctdb_set_error(ctdb, "Failed to load public address list '%s'\n", alist);
440 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
444 for (i=0;i<nlines;i++) {
446 struct sockaddr_in addr;
450 tok = strtok(lines[i], " \t");
451 if (!tok || !parse_ip_mask(tok, &addr, &mask)) {
452 DEBUG(DEBUG_CRIT,("Badly formed line %u in public address list\n", i+1));
456 tok = strtok(NULL, " \t");
458 if (NULL == ctdb->default_public_interface) {
459 DEBUG(DEBUG_CRIT,("No default public interface and no interface specified at line %u of public address list\n",
464 iface = ctdb->default_public_interface;
469 if (ctdb_add_public_address(ctdb, addr, mask, iface)) {
470 DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
483 struct ctdb_public_ip_list {
484 struct ctdb_public_ip_list *next;
486 struct sockaddr_in sin;
490 /* Given a physical node, return the number of
491 public addresses that is currently assigned to this node.
493 static int node_ip_coverage(struct ctdb_context *ctdb,
495 struct ctdb_public_ip_list *ips)
499 for (;ips;ips=ips->next) {
500 if (ips->pnn == pnn) {
508 /* Check if this is a public ip known to the node, i.e. can that
509 node takeover this ip ?
511 static int can_node_serve_ip(struct ctdb_context *ctdb, int32_t pnn,
512 struct ctdb_public_ip_list *ip)
514 struct ctdb_all_public_ips *public_ips;
517 public_ips = ctdb->nodes[pnn]->public_ips;
519 if (public_ips == NULL) {
523 for (i=0;i<public_ips->num;i++) {
524 if (ip->sin.sin_addr.s_addr == public_ips->ips[i].sin.sin_addr.s_addr) {
525 /* yes, this node can serve this public ip */
534 /* search the node lists list for a node to takeover this ip.
535 pick the node that currently are serving the least number of ips
536 so that the ips get spread out evenly.
538 static int find_takeover_node(struct ctdb_context *ctdb,
539 struct ctdb_node_map *nodemap, uint32_t mask,
540 struct ctdb_public_ip_list *ip,
541 struct ctdb_public_ip_list *all_ips)
547 for (i=0;i<nodemap->num;i++) {
548 if (nodemap->nodes[i].flags & mask) {
549 /* This node is not healty and can not be used to serve
555 /* verify that this node can serve this ip */
556 if (can_node_serve_ip(ctdb, i, ip)) {
557 /* no it couldnt so skip to the next node */
561 num = node_ip_coverage(ctdb, i, all_ips);
562 /* was this the first node we checked ? */
574 DEBUG(DEBUG_WARNING,(__location__ " Could not find node to take over public address '%s'\n", inet_ntoa(ip->sin.sin_addr)));
582 struct ctdb_public_ip_list *
583 add_ip_to_merged_list(struct ctdb_context *ctdb,
585 struct ctdb_public_ip_list *ip_list,
586 struct ctdb_public_ip *ip)
588 struct ctdb_public_ip_list *tmp_ip;
590 /* do we already have this ip in our merged list ?*/
591 for (tmp_ip=ip_list;tmp_ip;tmp_ip=tmp_ip->next) {
593 /* we already have this public ip in the list */
594 if (tmp_ip->sin.sin_addr.s_addr == ip->sin.sin_addr.s_addr) {
599 /* this is a new public ip, we must add it to the list */
600 tmp_ip = talloc_zero(tmp_ctx, struct ctdb_public_ip_list);
601 CTDB_NO_MEMORY_NULL(ctdb, tmp_ip);
602 tmp_ip->pnn = ip->pnn;
603 tmp_ip->sin = ip->sin;
604 tmp_ip->next = ip_list;
609 struct ctdb_public_ip_list *
610 create_merged_ip_list(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx)
613 struct ctdb_public_ip_list *ip_list = NULL;
614 struct ctdb_all_public_ips *public_ips;
616 for (i=0;i<ctdb->num_nodes;i++) {
617 public_ips = ctdb->nodes[i]->public_ips;
619 /* there were no public ips for this node */
620 if (public_ips == NULL) {
624 for (j=0;j<public_ips->num;j++) {
625 ip_list = add_ip_to_merged_list(ctdb, tmp_ctx,
626 ip_list, &public_ips->ips[j]);
634 make any IP alias changes for public addresses that are necessary
636 int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
638 int i, num_healthy, retries;
639 struct ctdb_public_ip ip;
641 struct ctdb_public_ip_list *all_ips, *tmp_ip;
642 int maxnode, maxnum=0, minnode, minnum=0, num;
644 struct timeval timeout;
645 struct client_async_data *async_data;
646 struct ctdb_client_control_state *state;
647 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
652 /* Count how many completely healthy nodes we have */
654 for (i=0;i<nodemap->num;i++) {
655 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED))) {
660 if (num_healthy > 0) {
661 /* We have healthy nodes, so only consider them for
662 serving public addresses
664 mask = NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED;
666 /* We didnt have any completely healthy nodes so
667 use "disabled" nodes as a fallback
669 mask = NODE_FLAGS_INACTIVE;
672 /* since nodes only know about those public addresses that
673 can be served by that particular node, no single node has
674 a full list of all public addresses that exist in the cluster.
675 Walk over all node structures and create a merged list of
676 all public addresses that exist in the cluster.
678 all_ips = create_merged_ip_list(ctdb, tmp_ctx);
680 /* If we want deterministic ip allocations, i.e. that the ip addresses
681 will always be allocated the same way for a specific set of
682 available/unavailable nodes.
684 if (1 == ctdb->tunable.deterministic_public_ips) {
685 DEBUG(DEBUG_NOTICE,("Deterministic IPs enabled. Resetting all ip allocations\n"));
686 for (i=0,tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next,i++) {
687 tmp_ip->pnn = i%nodemap->num;
692 /* mark all public addresses with a masked node as being served by
695 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
696 if (tmp_ip->pnn == -1) {
699 if (nodemap->nodes[tmp_ip->pnn].flags & mask) {
704 /* verify that the assigned nodes can serve that public ip
705 and set it to -1 if not
707 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
708 if (tmp_ip->pnn == -1) {
711 if (can_node_serve_ip(ctdb, tmp_ip->pnn, tmp_ip) != 0) {
712 /* this node can not serve this ip. */
718 /* now we must redistribute all public addresses with takeover node
719 -1 among the nodes available
723 /* loop over all ip's and find a physical node to cover for
726 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
727 if (tmp_ip->pnn == -1) {
728 if (find_takeover_node(ctdb, nodemap, mask, tmp_ip, all_ips)) {
729 DEBUG(DEBUG_WARNING,("Failed to find node to cover ip %s\n", inet_ntoa(tmp_ip->sin.sin_addr)));
734 /* If we dont want ips to fail back after a node becomes healthy
735 again, we wont even try to reallocat the ip addresses so that
736 they are evenly spread out.
737 This can NOT be used at the same time as DeterministicIPs !
739 if (1 == ctdb->tunable.no_ip_failback) {
740 if (1 == ctdb->tunable.deterministic_public_ips) {
741 DEBUG(DEBUG_ERR, ("ERROR: You can not use 'DeterministicIPs' and 'NoIPFailback' at the same time\n"));
747 /* now, try to make sure the ip adresses are evenly distributed
749 for each ip address, loop over all nodes that can serve this
750 ip and make sure that the difference between the node
751 serving the most and the node serving the least ip's are not greater
754 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
755 if (tmp_ip->pnn == -1) {
759 /* Get the highest and lowest number of ips's served by any
760 valid node which can serve this ip.
764 for (i=0;i<nodemap->num;i++) {
765 if (nodemap->nodes[i].flags & mask) {
769 /* only check nodes that can actually serve this ip */
770 if (can_node_serve_ip(ctdb, i, tmp_ip)) {
771 /* no it couldnt so skip to the next node */
775 num = node_ip_coverage(ctdb, i, all_ips);
796 DEBUG(DEBUG_WARNING,(__location__ " Could not find maxnode. May not be able to serve ip '%s'\n", inet_ntoa(tmp_ip->sin.sin_addr)));
800 /* If we want deterministic IPs then dont try to reallocate
801 them to spread out the load.
803 if (1 == ctdb->tunable.deterministic_public_ips) {
807 /* if the spread between the smallest and largest coverage by
808 a node is >=2 we steal one of the ips from the node with
809 most coverage to even things out a bit.
810 try to do this at most 5 times since we dont want to spend
811 too much time balancing the ip coverage.
813 if ( (maxnum > minnum+1)
815 struct ctdb_public_ip_list *tmp;
817 /* mark one of maxnode's vnn's as unassigned and try
820 for (tmp=all_ips;tmp;tmp=tmp->next) {
821 if (tmp->pnn == maxnode) {
831 /* finished distributing the public addresses, now just send the
832 info out to the nodes
836 /* at this point ->pnn is the node which will own each IP
837 or -1 if there is no node that can cover this ip
840 /* now tell all nodes to delete any alias that they should not
841 have. This will be a NOOP on nodes that don't currently
842 hold the given alias */
843 async_data = talloc_zero(tmp_ctx, struct client_async_data);
844 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
846 for (i=0;i<nodemap->num;i++) {
847 /* don't talk to unconnected nodes, but do talk to banned nodes */
848 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
852 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
853 if (tmp_ip->pnn == nodemap->nodes[i].pnn) {
854 /* This node should be serving this
855 vnn so dont tell it to release the ip
859 ip.pnn = tmp_ip->pnn;
860 ip.sin.sin_family = AF_INET;
861 ip.sin.sin_addr = tmp_ip->sin.sin_addr;
863 timeout = TAKEOVER_TIMEOUT();
864 data.dsize = sizeof(ip);
865 data.dptr = (uint8_t *)&ip;
866 state = ctdb_control_send(ctdb, nodemap->nodes[i].pnn,
867 0, CTDB_CONTROL_RELEASE_IP, 0,
871 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_RELEASE_IP to node %u\n", nodemap->nodes[i].pnn));
872 talloc_free(tmp_ctx);
876 ctdb_client_async_add(async_data, state);
879 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
880 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_RELEASE_IP failed\n"));
881 talloc_free(tmp_ctx);
884 talloc_free(async_data);
887 /* tell all nodes to get their own IPs */
888 async_data = talloc_zero(tmp_ctx, struct client_async_data);
889 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
890 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
891 if (tmp_ip->pnn == -1) {
892 /* this IP won't be taken over */
895 ip.pnn = tmp_ip->pnn;
896 ip.sin.sin_family = AF_INET;
897 ip.sin.sin_addr = tmp_ip->sin.sin_addr;
899 timeout = TAKEOVER_TIMEOUT();
900 data.dsize = sizeof(ip);
901 data.dptr = (uint8_t *)&ip;
902 state = ctdb_control_send(ctdb, tmp_ip->pnn,
903 0, CTDB_CONTROL_TAKEOVER_IP, 0,
907 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_TAKEOVER_IP to node %u\n", tmp_ip->pnn));
908 talloc_free(tmp_ctx);
912 ctdb_client_async_add(async_data, state);
914 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
915 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_TAKEOVER_IP failed\n"));
916 talloc_free(tmp_ctx);
920 talloc_free(tmp_ctx);
926 destroy a ctdb_client_ip structure
928 static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
930 DEBUG(DEBUG_DEBUG,("destroying client tcp for %s:%u (client_id %u)\n",
931 inet_ntoa(ip->ip.sin_addr), ntohs(ip->ip.sin_port), ip->client_id));
932 DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
937 called by a client to inform us of a TCP connection that it is managing
938 that should tickled with an ACK when IP takeover is done
940 int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
943 struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
944 struct ctdb_control_tcp *p = (struct ctdb_control_tcp *)indata.dptr;
945 struct ctdb_tcp_list *tcp;
946 struct ctdb_control_tcp_vnn t;
949 struct ctdb_client_ip *ip;
950 struct ctdb_vnn *vnn;
952 vnn = find_public_ip_vnn(ctdb, p->dest);
954 if (ntohl(p->dest.sin_addr.s_addr) != INADDR_LOOPBACK) {
955 DEBUG(DEBUG_INFO,("Could not add client IP %s. This is not a public address.\n",
956 inet_ntoa(p->dest.sin_addr)));
961 if (vnn->pnn != ctdb->pnn) {
962 DEBUG(DEBUG_ERR,("Attempt to register tcp client for IP %s we don't hold - failing (client_id %u pid %u)\n",
963 inet_ntoa(p->dest.sin_addr),
964 client_id, client->pid));
965 /* failing this call will tell smbd to die */
969 ip = talloc(client, struct ctdb_client_ip);
970 CTDB_NO_MEMORY(ctdb, ip);
974 ip->client_id = client_id;
975 talloc_set_destructor(ip, ctdb_client_ip_destructor);
976 DLIST_ADD(ctdb->client_ip_list, ip);
978 tcp = talloc(client, struct ctdb_tcp_list);
979 CTDB_NO_MEMORY(ctdb, tcp);
981 tcp->connection.saddr = p->src;
982 tcp->connection.daddr = p->dest;
984 DLIST_ADD(client->tcp_list, tcp);
989 data.dptr = (uint8_t *)&t;
990 data.dsize = sizeof(t);
992 DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
993 (unsigned)ntohs(p->dest.sin_port),
994 inet_ntoa(p->src.sin_addr),
995 (unsigned)ntohs(p->src.sin_port), client_id, client->pid));
997 /* tell all nodes about this tcp connection */
998 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
999 CTDB_CONTROL_TCP_ADD,
1000 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1002 DEBUG(DEBUG_ERR,(__location__ " Failed to send CTDB_CONTROL_TCP_ADD\n"));
1010 see if two sockaddr_in are the same
1012 static bool same_sockaddr_in(struct sockaddr_in *in1, struct sockaddr_in *in2)
1014 return in1->sin_family == in2->sin_family &&
1015 in1->sin_port == in2->sin_port &&
1016 in1->sin_addr.s_addr == in2->sin_addr.s_addr;
1020 find a tcp address on a list
1022 static struct ctdb_tcp_connection *ctdb_tcp_find(struct ctdb_tcp_array *array,
1023 struct ctdb_tcp_connection *tcp)
1027 if (array == NULL) {
1031 for (i=0;i<array->num;i++) {
1032 if (same_sockaddr_in(&array->connections[i].saddr, &tcp->saddr) &&
1033 same_sockaddr_in(&array->connections[i].daddr, &tcp->daddr)) {
1034 return &array->connections[i];
1041 called by a daemon to inform us of a TCP connection that one of its
1042 clients managing that should tickled with an ACK when IP takeover is
1045 int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
1047 struct ctdb_control_tcp_vnn *p = (struct ctdb_control_tcp_vnn *)indata.dptr;
1048 struct ctdb_tcp_array *tcparray;
1049 struct ctdb_tcp_connection tcp;
1050 struct ctdb_vnn *vnn;
1052 vnn = find_public_ip_vnn(ctdb, p->dest);
1054 DEBUG(DEBUG_ERR,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
1055 inet_ntoa(p->dest.sin_addr)));
1060 tcparray = vnn->tcp_array;
1062 /* If this is the first tickle */
1063 if (tcparray == NULL) {
1064 tcparray = talloc_size(ctdb->nodes,
1065 offsetof(struct ctdb_tcp_array, connections) +
1066 sizeof(struct ctdb_tcp_connection) * 1);
1067 CTDB_NO_MEMORY(ctdb, tcparray);
1068 vnn->tcp_array = tcparray;
1071 tcparray->connections = talloc_size(tcparray, sizeof(struct ctdb_tcp_connection));
1072 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1074 tcparray->connections[tcparray->num].saddr = p->src;
1075 tcparray->connections[tcparray->num].daddr = p->dest;
1081 /* Do we already have this tickle ?*/
1083 tcp.daddr = p->dest;
1084 if (ctdb_tcp_find(vnn->tcp_array, &tcp) != NULL) {
1085 DEBUG(DEBUG_DEBUG,("Already had tickle info for %s:%u for vnn:%u\n",
1086 inet_ntoa(tcp.daddr.sin_addr),
1087 ntohs(tcp.daddr.sin_port),
1092 /* A new tickle, we must add it to the array */
1093 tcparray->connections = talloc_realloc(tcparray, tcparray->connections,
1094 struct ctdb_tcp_connection,
1096 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1098 vnn->tcp_array = tcparray;
1099 tcparray->connections[tcparray->num].saddr = p->src;
1100 tcparray->connections[tcparray->num].daddr = p->dest;
1103 DEBUG(DEBUG_INFO,("Added tickle info for %s:%u from vnn %u\n",
1104 inet_ntoa(tcp.daddr.sin_addr),
1105 ntohs(tcp.daddr.sin_port),
1113 called by a daemon to inform us of a TCP connection that one of its
1114 clients managing that should tickled with an ACK when IP takeover is
1117 static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tcp_connection *conn)
1119 struct ctdb_tcp_connection *tcpp;
1120 struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, conn->daddr);
1123 DEBUG(DEBUG_ERR,(__location__ " unable to find public address %s\n", inet_ntoa(conn->daddr.sin_addr)));
1127 /* if the array is empty we cant remove it
1128 and we dont need to do anything
1130 if (vnn->tcp_array == NULL) {
1131 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist (array is empty) %s:%u\n",
1132 inet_ntoa(conn->daddr.sin_addr),
1133 ntohs(conn->daddr.sin_port)));
1138 /* See if we know this connection
1139 if we dont know this connection then we dont need to do anything
1141 tcpp = ctdb_tcp_find(vnn->tcp_array, conn);
1143 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist %s:%u\n",
1144 inet_ntoa(conn->daddr.sin_addr),
1145 ntohs(conn->daddr.sin_port)));
1150 /* We need to remove this entry from the array.
1151 Instead of allocating a new array and copying data to it
1152 we cheat and just copy the last entry in the existing array
1153 to the entry that is to be removed and just shring the
1156 *tcpp = vnn->tcp_array->connections[vnn->tcp_array->num - 1];
1157 vnn->tcp_array->num--;
1159 /* If we deleted the last entry we also need to remove the entire array
1161 if (vnn->tcp_array->num == 0) {
1162 talloc_free(vnn->tcp_array);
1163 vnn->tcp_array = NULL;
1166 vnn->tcp_update_needed = true;
1168 DEBUG(DEBUG_INFO,("Removed tickle info for %s:%u\n",
1169 inet_ntoa(conn->saddr.sin_addr),
1170 ntohs(conn->saddr.sin_port)));
1175 called when a daemon restarts - send all tickes for all public addresses
1176 we are serving immediately to the new node.
1178 int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t vnn)
1180 /*XXX here we should send all tickes we are serving to the new node */
1186 called when a client structure goes away - hook to remove
1187 elements from the tcp_list in all daemons
1189 void ctdb_takeover_client_destructor_hook(struct ctdb_client *client)
1191 while (client->tcp_list) {
1192 struct ctdb_tcp_list *tcp = client->tcp_list;
1193 DLIST_REMOVE(client->tcp_list, tcp);
1194 ctdb_remove_tcp_connection(client->ctdb, &tcp->connection);
1200 release all IPs on shutdown
1202 void ctdb_release_all_ips(struct ctdb_context *ctdb)
1204 struct ctdb_vnn *vnn;
1206 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1207 if (!ctdb_sys_have_ip(vnn->public_address)) {
1210 ctdb_event_script(ctdb, "releaseip %s %s %u",
1212 inet_ntoa(vnn->public_address.sin_addr),
1213 vnn->public_netmask_bits);
1214 release_kill_clients(ctdb, vnn->public_address);
1220 get list of public IPs
1222 int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb,
1223 struct ctdb_req_control *c, TDB_DATA *outdata)
1226 struct ctdb_all_public_ips *ips;
1227 struct ctdb_vnn *vnn;
1229 /* count how many public ip structures we have */
1231 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1235 len = offsetof(struct ctdb_all_public_ips, ips) +
1236 num*sizeof(struct ctdb_public_ip);
1237 ips = talloc_zero_size(outdata, len);
1238 CTDB_NO_MEMORY(ctdb, ips);
1240 outdata->dsize = len;
1241 outdata->dptr = (uint8_t *)ips;
1245 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1246 ips->ips[i].pnn = vnn->pnn;
1247 ips->ips[i].sin = vnn->public_address;
1257 structure containing the listening socket and the list of tcp connections
1258 that the ctdb daemon is to kill
1260 struct ctdb_kill_tcp {
1261 struct ctdb_vnn *vnn;
1262 struct ctdb_context *ctdb;
1264 struct fd_event *fde;
1265 trbt_tree_t *connections;
1270 a tcp connection that is to be killed
1272 struct ctdb_killtcp_con {
1273 struct sockaddr_in src;
1274 struct sockaddr_in dst;
1276 struct ctdb_kill_tcp *killtcp;
1279 /* this function is used to create a key to represent this socketpair
1280 in the killtcp tree.
1281 this key is used to insert and lookup matching socketpairs that are
1282 to be tickled and RST
1284 #define KILLTCP_KEYLEN 4
1285 static uint32_t *killtcp_key(struct sockaddr_in *src, struct sockaddr_in *dst)
1287 static uint32_t key[KILLTCP_KEYLEN];
1289 key[0] = dst->sin_addr.s_addr;
1290 key[1] = src->sin_addr.s_addr;
1291 key[2] = dst->sin_port;
1292 key[3] = src->sin_port;
1298 called when we get a read event on the raw socket
1300 static void capture_tcp_handler(struct event_context *ev, struct fd_event *fde,
1301 uint16_t flags, void *private_data)
1303 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
1304 struct ctdb_killtcp_con *con;
1305 struct sockaddr_in src, dst;
1306 uint32_t ack_seq, seq;
1308 if (!(flags & EVENT_FD_READ)) {
1312 if (ctdb_sys_read_tcp_packet(killtcp->capture_fd,
1313 killtcp->private_data,
1315 &ack_seq, &seq) != 0) {
1316 /* probably a non-tcp ACK packet */
1320 /* check if we have this guy in our list of connections
1323 con = trbt_lookuparray32(killtcp->connections,
1324 KILLTCP_KEYLEN, killtcp_key(&src, &dst));
1326 /* no this was some other packet we can just ignore */
1330 /* This one has been tickled !
1331 now reset him and remove him from the list.
1333 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)));
1336 (ctdb_sock_addr *)&con->dst,
1337 (ctdb_sock_addr *)&con->src,
1343 /* when traversing the list of all tcp connections to send tickle acks to
1344 (so that we can capture the ack coming back and kill the connection
1346 this callback is called for each connection we are currently trying to kill
1348 static void tickle_connection_traverse(void *param, void *data)
1350 struct ctdb_killtcp_con *con = talloc_get_type(data, struct ctdb_killtcp_con);
1352 /* have tried too many times, just give up */
1353 if (con->count >= 5) {
1358 /* othervise, try tickling it again */
1361 (ctdb_sock_addr *)&con->dst,
1362 (ctdb_sock_addr *)&con->src,
1368 called every second until all sentenced connections have been reset
1370 static void ctdb_tickle_sentenced_connections(struct event_context *ev, struct timed_event *te,
1371 struct timeval t, void *private_data)
1373 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
1376 /* loop over all connections sending tickle ACKs */
1377 trbt_traversearray32(killtcp->connections, KILLTCP_KEYLEN, tickle_connection_traverse, NULL);
1380 /* If there are no more connections to kill we can remove the
1381 entire killtcp structure
1383 if ( (killtcp->connections == NULL) ||
1384 (killtcp->connections->root == NULL) ) {
1385 talloc_free(killtcp);
1389 /* try tickling them again in a seconds time
1391 event_add_timed(killtcp->ctdb->ev, killtcp, timeval_current_ofs(1, 0),
1392 ctdb_tickle_sentenced_connections, killtcp);
1396 destroy the killtcp structure
1398 static int ctdb_killtcp_destructor(struct ctdb_kill_tcp *killtcp)
1400 killtcp->vnn->killtcp = NULL;
1405 /* nothing fancy here, just unconditionally replace any existing
1406 connection structure with the new one.
1408 dont even free the old one if it did exist, that one is talloc_stolen
1409 by the same node in the tree anyway and will be deleted when the new data
1412 static void *add_killtcp_callback(void *parm, void *data)
1418 add a tcp socket to the list of connections we want to RST
1420 static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
1421 struct sockaddr_in *src, struct sockaddr_in *dst)
1423 struct ctdb_kill_tcp *killtcp;
1424 struct ctdb_killtcp_con *con;
1425 struct ctdb_vnn *vnn;
1427 vnn = find_public_ip_vnn(ctdb, *dst);
1429 vnn = find_public_ip_vnn(ctdb, *src);
1432 /* if it is not a public ip it could be our 'single ip' */
1433 if (ctdb->single_ip_vnn) {
1434 if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, dst)) {
1435 vnn = ctdb->single_ip_vnn;
1440 DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n"));
1444 killtcp = vnn->killtcp;
1446 /* If this is the first connection to kill we must allocate
1449 if (killtcp == NULL) {
1450 killtcp = talloc_zero(ctdb, struct ctdb_kill_tcp);
1451 CTDB_NO_MEMORY(ctdb, killtcp);
1454 killtcp->ctdb = ctdb;
1455 killtcp->capture_fd = -1;
1456 killtcp->connections = trbt_create(killtcp, 0);
1458 vnn->killtcp = killtcp;
1459 talloc_set_destructor(killtcp, ctdb_killtcp_destructor);
1464 /* create a structure that describes this connection we want to
1465 RST and store it in killtcp->connections
1467 con = talloc(killtcp, struct ctdb_killtcp_con);
1468 CTDB_NO_MEMORY(ctdb, con);
1472 con->killtcp = killtcp;
1475 trbt_insertarray32_callback(killtcp->connections,
1476 KILLTCP_KEYLEN, killtcp_key(&con->dst, &con->src),
1477 add_killtcp_callback, con);
1480 If we dont have a socket to listen on yet we must create it
1482 if (killtcp->capture_fd == -1) {
1483 killtcp->capture_fd = ctdb_sys_open_capture_socket(vnn->iface, &killtcp->private_data);
1484 if (killtcp->capture_fd == -1) {
1485 DEBUG(DEBUG_CRIT,(__location__ " Failed to open capturing socket for killtcp\n"));
1491 if (killtcp->fde == NULL) {
1492 killtcp->fde = event_add_fd(ctdb->ev, killtcp, killtcp->capture_fd,
1493 EVENT_FD_READ | EVENT_FD_AUTOCLOSE,
1494 capture_tcp_handler, killtcp);
1496 /* We also need to set up some events to tickle all these connections
1497 until they are all reset
1499 event_add_timed(ctdb->ev, killtcp, timeval_current_ofs(1, 0),
1500 ctdb_tickle_sentenced_connections, killtcp);
1503 /* tickle him once now */
1505 (ctdb_sock_addr *)&con->dst,
1506 (ctdb_sock_addr *)&con->src,
1512 talloc_free(vnn->killtcp);
1513 vnn->killtcp = NULL;
1518 kill a TCP connection.
1520 int32_t ctdb_control_kill_tcp(struct ctdb_context *ctdb, TDB_DATA indata)
1522 struct ctdb_control_killtcp *killtcp = (struct ctdb_control_killtcp *)indata.dptr;
1524 return ctdb_killtcp_add_connection(ctdb, &killtcp->src, &killtcp->dst);
1528 called by a daemon to inform us of the entire list of TCP tickles for
1529 a particular public address.
1530 this control should only be sent by the node that is currently serving
1531 that public address.
1533 int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata)
1535 struct ctdb_control_tcp_tickle_list *list = (struct ctdb_control_tcp_tickle_list *)indata.dptr;
1536 struct ctdb_tcp_array *tcparray;
1537 struct ctdb_vnn *vnn;
1539 /* We must at least have tickles.num or else we cant verify the size
1540 of the received data blob
1542 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
1543 tickles.connections)) {
1544 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list. Not enough data for the tickle.num field\n"));
1548 /* verify that the size of data matches what we expect */
1549 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
1550 tickles.connections)
1551 + sizeof(struct ctdb_tcp_connection)
1552 * list->tickles.num) {
1553 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list\n"));
1557 vnn = find_public_ip_vnn(ctdb, list->ip);
1559 DEBUG(DEBUG_ERR,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n",
1560 inet_ntoa(list->ip.sin_addr)));
1564 /* remove any old ticklelist we might have */
1565 talloc_free(vnn->tcp_array);
1566 vnn->tcp_array = NULL;
1568 tcparray = talloc(ctdb->nodes, struct ctdb_tcp_array);
1569 CTDB_NO_MEMORY(ctdb, tcparray);
1571 tcparray->num = list->tickles.num;
1573 tcparray->connections = talloc_array(tcparray, struct ctdb_tcp_connection, tcparray->num);
1574 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1576 memcpy(tcparray->connections, &list->tickles.connections[0],
1577 sizeof(struct ctdb_tcp_connection)*tcparray->num);
1579 /* We now have a new fresh tickle list array for this vnn */
1580 vnn->tcp_array = talloc_steal(vnn, tcparray);
1586 called to return the full list of tickles for the puclic address associated
1587 with the provided vnn
1589 int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata)
1591 struct sockaddr_in *ip = (struct sockaddr_in *)indata.dptr;
1592 struct ctdb_control_tcp_tickle_list *list;
1593 struct ctdb_tcp_array *tcparray;
1595 struct ctdb_vnn *vnn;
1597 vnn = find_public_ip_vnn(ctdb, *ip);
1599 DEBUG(DEBUG_ERR,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n",
1600 inet_ntoa(ip->sin_addr)));
1604 tcparray = vnn->tcp_array;
1606 num = tcparray->num;
1611 outdata->dsize = offsetof(struct ctdb_control_tcp_tickle_list,
1612 tickles.connections)
1613 + sizeof(struct ctdb_tcp_connection) * num;
1615 outdata->dptr = talloc_size(outdata, outdata->dsize);
1616 CTDB_NO_MEMORY(ctdb, outdata->dptr);
1617 list = (struct ctdb_control_tcp_tickle_list *)outdata->dptr;
1620 list->tickles.num = num;
1622 memcpy(&list->tickles.connections[0], tcparray->connections,
1623 sizeof(struct ctdb_tcp_connection) * num);
1631 set the list of all tcp tickles for a public address
1633 static int ctdb_ctrl_set_tcp_tickles(struct ctdb_context *ctdb,
1634 struct timeval timeout, uint32_t destnode,
1635 struct sockaddr_in *ip,
1636 struct ctdb_tcp_array *tcparray)
1640 struct ctdb_control_tcp_tickle_list *list;
1643 num = tcparray->num;
1648 data.dsize = offsetof(struct ctdb_control_tcp_tickle_list,
1649 tickles.connections) +
1650 sizeof(struct ctdb_tcp_connection) * num;
1651 data.dptr = talloc_size(ctdb, data.dsize);
1652 CTDB_NO_MEMORY(ctdb, data.dptr);
1654 list = (struct ctdb_control_tcp_tickle_list *)data.dptr;
1656 list->tickles.num = num;
1658 memcpy(&list->tickles.connections[0], tcparray->connections, sizeof(struct ctdb_tcp_connection) * num);
1661 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
1662 CTDB_CONTROL_SET_TCP_TICKLE_LIST,
1663 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1665 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set tcp tickles failed\n"));
1669 talloc_free(data.dptr);
1676 perform tickle updates if required
1678 static void ctdb_update_tcp_tickles(struct event_context *ev,
1679 struct timed_event *te,
1680 struct timeval t, void *private_data)
1682 struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
1684 struct ctdb_vnn *vnn;
1686 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1687 /* we only send out updates for public addresses that
1690 if (ctdb->pnn != vnn->pnn) {
1693 /* We only send out the updates if we need to */
1694 if (!vnn->tcp_update_needed) {
1697 ret = ctdb_ctrl_set_tcp_tickles(ctdb,
1699 CTDB_BROADCAST_CONNECTED,
1700 &vnn->public_address,
1703 DEBUG(DEBUG_ERR,("Failed to send the tickle update for public address %s\n",
1704 inet_ntoa(vnn->public_address.sin_addr)));
1708 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
1709 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
1710 ctdb_update_tcp_tickles, ctdb);
1715 start periodic update of tcp tickles
1717 void ctdb_start_tcp_tickle_update(struct ctdb_context *ctdb)
1719 ctdb->tickle_update_context = talloc_new(ctdb);
1721 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
1722 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
1723 ctdb_update_tcp_tickles, ctdb);
1729 struct control_gratious_arp {
1730 struct ctdb_context *ctdb;
1731 struct sockaddr_in sin;
1737 send a control_gratuitous arp
1739 static void send_gratious_arp(struct event_context *ev, struct timed_event *te,
1740 struct timeval t, void *private_data)
1743 struct control_gratious_arp *arp = talloc_get_type(private_data,
1744 struct control_gratious_arp);
1746 ret = ctdb_sys_send_arp(&arp->sin, arp->iface);
1748 DEBUG(DEBUG_ERR,(__location__ " sending of gratious arp failed (%s)\n", strerror(errno)));
1753 if (arp->count == CTDB_ARP_REPEAT) {
1758 event_add_timed(arp->ctdb->ev, arp,
1759 timeval_current_ofs(CTDB_ARP_INTERVAL, 0),
1760 send_gratious_arp, arp);
1767 int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indata)
1769 struct ctdb_control_ip_iface *gratious_arp = (struct ctdb_control_ip_iface *)indata.dptr;
1770 struct control_gratious_arp *arp;
1773 /* verify the size of indata */
1774 if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
1775 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
1779 ( offsetof(struct ctdb_control_ip_iface, iface)
1780 + gratious_arp->len ) ){
1782 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
1783 "but should be %u bytes\n",
1784 (unsigned)indata.dsize,
1785 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+gratious_arp->len)));
1790 arp = talloc(ctdb, struct control_gratious_arp);
1791 CTDB_NO_MEMORY(ctdb, arp);
1794 arp->sin = gratious_arp->sin;
1795 arp->iface = talloc_strdup(arp, gratious_arp->iface);
1796 CTDB_NO_MEMORY(ctdb, arp->iface);
1799 event_add_timed(arp->ctdb->ev, arp,
1800 timeval_zero(), send_gratious_arp, arp);
1805 int32_t ctdb_control_add_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
1807 struct ctdb_control_ip_iface *pub = (struct ctdb_control_ip_iface *)indata.dptr;
1810 /* verify the size of indata */
1811 if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
1812 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
1816 ( offsetof(struct ctdb_control_ip_iface, iface)
1819 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
1820 "but should be %u bytes\n",
1821 (unsigned)indata.dsize,
1822 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+pub->len)));
1826 return ctdb_add_public_address(ctdb, pub->sin, pub->mask, &pub->iface[0]);
1830 called when releaseip event finishes for del_public_address
1832 static void delete_ip_callback(struct ctdb_context *ctdb, int status,
1835 talloc_free(private_data);
1838 int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA indata)
1840 struct ctdb_control_ip_iface *pub = (struct ctdb_control_ip_iface *)indata.dptr;
1841 struct ctdb_vnn *vnn;
1844 /* verify the size of indata */
1845 if (indata.dsize < offsetof(struct ctdb_control_ip_iface, iface)) {
1846 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_ip_iface structure\n"));
1850 ( offsetof(struct ctdb_control_ip_iface, iface)
1853 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
1854 "but should be %u bytes\n",
1855 (unsigned)indata.dsize,
1856 (unsigned)(offsetof(struct ctdb_control_ip_iface, iface)+pub->len)));
1860 /* walk over all public addresses until we find a match */
1861 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1862 if (ctdb_same_ip(&vnn->public_address, &pub->sin)) {
1863 TALLOC_CTX *mem_ctx = talloc_new(ctdb);
1865 DLIST_REMOVE(ctdb->vnn, vnn);
1867 ret = ctdb_event_script_callback(ctdb,
1868 timeval_current_ofs(ctdb->tunable.script_timeout, 0),
1869 mem_ctx, delete_ip_callback, mem_ctx,
1870 "releaseip %s %s %u",
1872 inet_ntoa(vnn->public_address.sin_addr),
1873 vnn->public_netmask_bits);