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 s = ctdb_sys_open_sending_socket();
83 DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket for sending tickles\n"));
87 tcparray = arp->tcparray;
89 for (i=0;i<tcparray->num;i++) {
90 DEBUG(DEBUG_INFO,("sending tcp tickle ack for %u->%s:%u\n",
91 (unsigned)ntohs(tcparray->connections[i].daddr.sin_port),
92 inet_ntoa(tcparray->connections[i].saddr.sin_addr),
93 (unsigned)ntohs(tcparray->connections[i].saddr.sin_port)));
94 ret = ctdb_sys_send_tcp(s, &tcparray->connections[i].saddr,
95 &tcparray->connections[i].daddr, 0, 0, 0);
97 DEBUG(DEBUG_CRIT,(__location__ " Failed to send tcp tickle ack for %s\n",
98 inet_ntoa(tcparray->connections[i].saddr.sin_addr)));
106 if (arp->count == CTDB_ARP_REPEAT) {
111 event_add_timed(arp->ctdb->ev, arp->vnn->takeover_ctx,
112 timeval_current_ofs(CTDB_ARP_INTERVAL, 0),
113 ctdb_control_send_arp, arp);
116 struct takeover_callback_state {
117 struct ctdb_req_control *c;
118 struct sockaddr_in *sin;
119 struct ctdb_vnn *vnn;
123 called when takeip event finishes
125 static void takeover_ip_callback(struct ctdb_context *ctdb, int status,
128 struct takeover_callback_state *state =
129 talloc_get_type(private_data, struct takeover_callback_state);
130 struct ctdb_takeover_arp *arp;
131 char *ip = inet_ntoa(state->sin->sin_addr);
132 struct ctdb_tcp_array *tcparray;
134 ctdb_enable_monitoring(ctdb);
137 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
138 ip, state->vnn->iface));
139 ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
144 if (!state->vnn->takeover_ctx) {
145 state->vnn->takeover_ctx = talloc_new(ctdb);
146 if (!state->vnn->takeover_ctx) {
151 arp = talloc_zero(state->vnn->takeover_ctx, struct ctdb_takeover_arp);
152 if (!arp) goto failed;
155 arp->sin = *state->sin;
156 arp->vnn = state->vnn;
158 tcparray = state->vnn->tcp_array;
160 /* add all of the known tcp connections for this IP to the
161 list of tcp connections to send tickle acks for */
162 arp->tcparray = talloc_steal(arp, tcparray);
164 state->vnn->tcp_array = NULL;
165 state->vnn->tcp_update_needed = true;
168 event_add_timed(arp->ctdb->ev, state->vnn->takeover_ctx,
169 timeval_zero(), ctdb_control_send_arp, arp);
171 /* the control succeeded */
172 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
177 ctdb_request_control_reply(ctdb, state->c, NULL, -1, NULL);
183 Find the vnn of the node that has a public ip address
184 returns -1 if the address is not known as a public address
186 static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, struct sockaddr_in ip)
188 struct ctdb_vnn *vnn;
190 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
191 if (ctdb_same_ip(&vnn->public_address, &ip)) {
201 take over an ip address
203 int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
204 struct ctdb_req_control *c,
209 struct takeover_callback_state *state;
210 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
211 struct ctdb_vnn *vnn;
213 /* update out vnn list */
214 vnn = find_public_ip_vnn(ctdb, pip->sin);
216 DEBUG(DEBUG_ERR,("takeoverip called for an ip '%s' that is not a public address\n",
217 inet_ntoa(pip->sin.sin_addr)));
222 /* if our kernel already has this IP, do nothing */
223 if (ctdb_sys_have_ip(pip->sin)) {
227 state = talloc(ctdb, struct takeover_callback_state);
228 CTDB_NO_MEMORY(ctdb, state);
230 state->c = talloc_steal(ctdb, c);
231 state->sin = talloc(ctdb, struct sockaddr_in);
232 CTDB_NO_MEMORY(ctdb, state->sin);
233 *state->sin = pip->sin;
237 DEBUG(DEBUG_NOTICE,("Takeover of IP %s/%u on interface %s\n",
238 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
241 ctdb_disable_monitoring(ctdb);
243 ret = ctdb_event_script_callback(ctdb,
244 timeval_current_ofs(ctdb->tunable.script_timeout, 0),
245 state, takeover_ip_callback, state,
248 inet_ntoa(pip->sin.sin_addr),
249 vnn->public_netmask_bits);
252 ctdb_enable_monitoring(ctdb);
253 DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
254 inet_ntoa(pip->sin.sin_addr), vnn->iface));
259 /* tell ctdb_control.c that we will be replying asynchronously */
266 kill any clients that are registered with a IP that is being released
268 static void release_kill_clients(struct ctdb_context *ctdb, struct sockaddr_in in)
270 struct ctdb_client_ip *ip;
272 DEBUG(DEBUG_INFO,("release_kill_clients for ip %s\n", inet_ntoa(in.sin_addr)));
274 for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
275 DEBUG(DEBUG_INFO,("checking for client %u with IP %s\n",
276 ip->client_id, inet_ntoa(ip->ip.sin_addr)));
277 if (ctdb_same_ip(&ip->ip, &in)) {
278 struct ctdb_client *client = ctdb_reqid_find(ctdb,
281 DEBUG(DEBUG_INFO,("matched client %u with IP %s and pid %u\n",
282 ip->client_id, inet_ntoa(ip->ip.sin_addr), client->pid));
283 if (client->pid != 0) {
284 DEBUG(DEBUG_INFO,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
285 (unsigned)client->pid, inet_ntoa(in.sin_addr),
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);
301 char *ip = inet_ntoa(state->sin->sin_addr);
304 ctdb_enable_monitoring(ctdb);
306 /* send a message to all clients of this node telling them
307 that the cluster has been reconfigured and they should
308 release any sockets on this IP */
309 data.dptr = (uint8_t *)ip;
310 data.dsize = strlen(ip)+1;
312 ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data);
314 /* kill clients that have registered with this IP */
315 release_kill_clients(ctdb, *state->sin);
317 /* the control succeeded */
318 ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
323 release an ip address
325 int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
326 struct ctdb_req_control *c,
331 struct takeover_callback_state *state;
332 struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
333 struct ctdb_vnn *vnn;
335 /* update our vnn list */
336 vnn = find_public_ip_vnn(ctdb, pip->sin);
338 DEBUG(DEBUG_ERR,("releaseip called for an ip '%s' that is not a public address\n",
339 inet_ntoa(pip->sin.sin_addr)));
344 /* stop any previous arps */
345 talloc_free(vnn->takeover_ctx);
346 vnn->takeover_ctx = NULL;
348 if (!ctdb_sys_have_ip(pip->sin)) {
349 DEBUG(DEBUG_INFO,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
350 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
355 DEBUG(DEBUG_NOTICE,("Release of IP %s/%u on interface %s\n",
356 inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
359 state = talloc(ctdb, struct takeover_callback_state);
360 CTDB_NO_MEMORY(ctdb, state);
362 state->c = talloc_steal(state, c);
363 state->sin = talloc(state, struct sockaddr_in);
364 CTDB_NO_MEMORY(ctdb, state->sin);
365 *state->sin = pip->sin;
369 ctdb_disable_monitoring(ctdb);
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 ctdb_enable_monitoring(ctdb);
381 DEBUG(DEBUG_ERR,(__location__ " Failed to release IP %s on interface %s\n",
382 inet_ntoa(pip->sin.sin_addr), vnn->iface));
387 /* tell the control that we will be reply asynchronously */
394 static int add_public_address(struct ctdb_context *ctdb, struct sockaddr_in addr, unsigned mask, const char *iface)
396 struct ctdb_vnn *vnn;
398 /* Verify that we dont have an entry for this ip yet */
399 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
400 if (ctdb_same_sockaddr(&addr, &vnn->public_address)) {
401 DEBUG(DEBUG_CRIT,("Same ip '%s' specified multiple times in the public address list \n",
402 inet_ntoa(addr.sin_addr)));
407 /* create a new vnn structure for this ip address */
408 vnn = talloc_zero(ctdb, struct ctdb_vnn);
409 CTDB_NO_MEMORY_FATAL(ctdb, vnn);
410 vnn->iface = talloc_strdup(vnn, iface);
411 vnn->public_address = addr;
412 vnn->public_netmask_bits = mask;
415 DLIST_ADD(ctdb->vnn, vnn);
422 setup the event script directory
424 int ctdb_set_event_script_dir(struct ctdb_context *ctdb, const char *script_dir)
426 ctdb->event_script_dir = talloc_strdup(ctdb, script_dir);
427 CTDB_NO_MEMORY(ctdb, ctdb->event_script_dir);
432 setup the public address lists from a file
434 int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
440 lines = file_lines_load(alist, &nlines, ctdb);
442 ctdb_set_error(ctdb, "Failed to load public address list '%s'\n", alist);
445 while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
449 for (i=0;i<nlines;i++) {
451 struct sockaddr_in addr;
455 tok = strtok(lines[i], " \t");
456 if (!tok || !parse_ip_mask(tok, &addr, &mask)) {
457 DEBUG(DEBUG_CRIT,("Badly formed line %u in public address list\n", i+1));
461 tok = strtok(NULL, " \t");
463 if (NULL == ctdb->default_public_interface) {
464 DEBUG(DEBUG_CRIT,("No default public interface and no interface specified at line %u of public address list\n",
469 iface = ctdb->default_public_interface;
474 if (add_public_address(ctdb, addr, mask, iface)) {
475 DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
488 struct ctdb_public_ip_list {
489 struct ctdb_public_ip_list *next;
491 struct sockaddr_in sin;
495 /* Given a physical node, return the number of
496 public addresses that is currently assigned to this node.
498 static int node_ip_coverage(struct ctdb_context *ctdb,
500 struct ctdb_public_ip_list *ips)
504 for (;ips;ips=ips->next) {
505 if (ips->pnn == pnn) {
513 /* Check if this is a public ip known to the node, i.e. can that
514 node takeover this ip ?
516 static int can_node_serve_ip(struct ctdb_context *ctdb, int32_t pnn,
517 struct ctdb_public_ip_list *ip)
519 struct ctdb_all_public_ips *public_ips;
522 public_ips = ctdb->nodes[pnn]->public_ips;
524 if (public_ips == NULL) {
528 for (i=0;i<public_ips->num;i++) {
529 if (ip->sin.sin_addr.s_addr == public_ips->ips[i].sin.sin_addr.s_addr) {
530 /* yes, this node can serve this public ip */
539 /* search the node lists list for a node to takeover this ip.
540 pick the node that currently are serving the least number of ips
541 so that the ips get spread out evenly.
543 static int find_takeover_node(struct ctdb_context *ctdb,
544 struct ctdb_node_map *nodemap, uint32_t mask,
545 struct ctdb_public_ip_list *ip,
546 struct ctdb_public_ip_list *all_ips)
552 for (i=0;i<nodemap->num;i++) {
553 if (nodemap->nodes[i].flags & mask) {
554 /* This node is not healty and can not be used to serve
560 /* verify that this node can serve this ip */
561 if (can_node_serve_ip(ctdb, i, ip)) {
562 /* no it couldnt so skip to the next node */
566 num = node_ip_coverage(ctdb, i, all_ips);
567 /* was this the first node we checked ? */
579 DEBUG(DEBUG_WARNING,(__location__ " Could not find node to take over public address '%s'\n", inet_ntoa(ip->sin.sin_addr)));
587 struct ctdb_public_ip_list *
588 add_ip_to_merged_list(struct ctdb_context *ctdb,
590 struct ctdb_public_ip_list *ip_list,
591 struct ctdb_public_ip *ip)
593 struct ctdb_public_ip_list *tmp_ip;
595 /* do we already have this ip in our merged list ?*/
596 for (tmp_ip=ip_list;tmp_ip;tmp_ip=tmp_ip->next) {
598 /* we already have this public ip in the list */
599 if (tmp_ip->sin.sin_addr.s_addr == ip->sin.sin_addr.s_addr) {
604 /* this is a new public ip, we must add it to the list */
605 tmp_ip = talloc_zero(tmp_ctx, struct ctdb_public_ip_list);
606 CTDB_NO_MEMORY_NULL(ctdb, tmp_ip);
607 tmp_ip->pnn = ip->pnn;
608 tmp_ip->sin = ip->sin;
609 tmp_ip->next = ip_list;
614 struct ctdb_public_ip_list *
615 create_merged_ip_list(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx)
618 struct ctdb_public_ip_list *ip_list = NULL;
619 struct ctdb_all_public_ips *public_ips;
621 for (i=0;i<ctdb->num_nodes;i++) {
622 public_ips = ctdb->nodes[i]->public_ips;
624 /* there were no public ips for this node */
625 if (public_ips == NULL) {
629 for (j=0;j<public_ips->num;j++) {
630 ip_list = add_ip_to_merged_list(ctdb, tmp_ctx,
631 ip_list, &public_ips->ips[j]);
639 make any IP alias changes for public addresses that are necessary
641 int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
643 int i, num_healthy, retries;
644 struct ctdb_public_ip ip;
646 struct ctdb_public_ip_list *all_ips, *tmp_ip;
647 int maxnode, maxnum=0, minnode, minnum=0, num;
649 struct timeval timeout;
650 struct client_async_data *async_data;
651 struct ctdb_client_control_state *state;
652 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
657 /* Count how many completely healthy nodes we have */
659 for (i=0;i<nodemap->num;i++) {
660 if (!(nodemap->nodes[i].flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED))) {
665 if (num_healthy > 0) {
666 /* We have healthy nodes, so only consider them for
667 serving public addresses
669 mask = NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED;
671 /* We didnt have any completely healthy nodes so
672 use "disabled" nodes as a fallback
674 mask = NODE_FLAGS_INACTIVE;
677 /* since nodes only know about those public addresses that
678 can be served by that particular node, no single node has
679 a full list of all public addresses that exist in the cluster.
680 Walk over all node structures and create a merged list of
681 all public addresses that exist in the cluster.
683 all_ips = create_merged_ip_list(ctdb, tmp_ctx);
685 /* If we want deterministic ip allocations, i.e. that the ip addresses
686 will always be allocated the same way for a specific set of
687 available/unavailable nodes.
689 if (1 == ctdb->tunable.deterministic_public_ips) {
690 DEBUG(DEBUG_NOTICE,("Deterministic IPs enabled. Resetting all ip allocations\n"));
691 for (i=0,tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next,i++) {
692 tmp_ip->pnn = i%nodemap->num;
697 /* mark all public addresses with a masked node as being served by
700 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
701 if (tmp_ip->pnn == -1) {
704 if (nodemap->nodes[tmp_ip->pnn].flags & mask) {
709 /* verify that the assigned nodes can serve that public ip
710 and set it to -1 if not
712 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
713 if (tmp_ip->pnn == -1) {
716 if (can_node_serve_ip(ctdb, tmp_ip->pnn, tmp_ip) != 0) {
717 /* this node can not serve this ip. */
723 /* now we must redistribute all public addresses with takeover node
724 -1 among the nodes available
728 /* loop over all ip's and find a physical node to cover for
731 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
732 if (tmp_ip->pnn == -1) {
733 if (find_takeover_node(ctdb, nodemap, mask, tmp_ip, all_ips)) {
734 DEBUG(DEBUG_WARNING,("Failed to find node to cover ip %s\n", inet_ntoa(tmp_ip->sin.sin_addr)));
739 /* If we dont want ips to fail back after a node becomes healthy
740 again, we wont even try to reallocat the ip addresses so that
741 they are evenly spread out.
742 This can NOT be used at the same time as DeterministicIPs !
744 if (1 == ctdb->tunable.no_ip_failback) {
745 if (1 == ctdb->tunable.deterministic_public_ips) {
746 DEBUG(DEBUG_ERR, ("ERROR: You can not use 'DeterministicIPs' and 'NoIPFailback' at the same time\n"));
752 /* now, try to make sure the ip adresses are evenly distributed
754 for each ip address, loop over all nodes that can serve this
755 ip and make sure that the difference between the node
756 serving the most and the node serving the least ip's are not greater
759 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
760 if (tmp_ip->pnn == -1) {
764 /* Get the highest and lowest number of ips's served by any
765 valid node which can serve this ip.
769 for (i=0;i<nodemap->num;i++) {
770 if (nodemap->nodes[i].flags & mask) {
774 /* only check nodes that can actually serve this ip */
775 if (can_node_serve_ip(ctdb, i, tmp_ip)) {
776 /* no it couldnt so skip to the next node */
780 num = node_ip_coverage(ctdb, i, all_ips);
801 DEBUG(DEBUG_WARNING,(__location__ " Could not find maxnode. May not be able to serve ip '%s'\n", inet_ntoa(tmp_ip->sin.sin_addr)));
805 /* If we want deterministic IPs then dont try to reallocate
806 them to spread out the load.
808 if (1 == ctdb->tunable.deterministic_public_ips) {
812 /* if the spread between the smallest and largest coverage by
813 a node is >=2 we steal one of the ips from the node with
814 most coverage to even things out a bit.
815 try to do this at most 5 times since we dont want to spend
816 too much time balancing the ip coverage.
818 if ( (maxnum > minnum+1)
820 struct ctdb_public_ip_list *tmp;
822 /* mark one of maxnode's vnn's as unassigned and try
825 for (tmp=all_ips;tmp;tmp=tmp->next) {
826 if (tmp->pnn == maxnode) {
836 /* finished distributing the public addresses, now just send the
837 info out to the nodes
841 /* at this point ->pnn is the node which will own each IP
842 or -1 if there is no node that can cover this ip
845 /* now tell all nodes to delete any alias that they should not
846 have. This will be a NOOP on nodes that don't currently
847 hold the given alias */
848 async_data = talloc_zero(tmp_ctx, struct client_async_data);
849 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
851 for (i=0;i<nodemap->num;i++) {
852 /* don't talk to unconnected nodes, but do talk to banned nodes */
853 if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
857 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
858 if (tmp_ip->pnn == nodemap->nodes[i].pnn) {
859 /* This node should be serving this
860 vnn so dont tell it to release the ip
864 ip.pnn = tmp_ip->pnn;
865 ip.sin.sin_family = AF_INET;
866 ip.sin.sin_addr = tmp_ip->sin.sin_addr;
868 timeout = TAKEOVER_TIMEOUT();
869 data.dsize = sizeof(ip);
870 data.dptr = (uint8_t *)&ip;
871 state = ctdb_control_send(ctdb, nodemap->nodes[i].pnn,
872 0, CTDB_CONTROL_RELEASE_IP, 0,
876 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_RELEASE_IP to node %u\n", nodemap->nodes[i].pnn));
877 talloc_free(tmp_ctx);
881 ctdb_client_async_add(async_data, state);
884 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
885 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_RELEASE_IP failed\n"));
886 talloc_free(tmp_ctx);
889 talloc_free(async_data);
892 /* tell all nodes to get their own IPs */
893 async_data = talloc_zero(tmp_ctx, struct client_async_data);
894 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
895 for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
896 if (tmp_ip->pnn == -1) {
897 /* this IP won't be taken over */
900 ip.pnn = tmp_ip->pnn;
901 ip.sin.sin_family = AF_INET;
902 ip.sin.sin_addr = tmp_ip->sin.sin_addr;
904 timeout = TAKEOVER_TIMEOUT();
905 data.dsize = sizeof(ip);
906 data.dptr = (uint8_t *)&ip;
907 state = ctdb_control_send(ctdb, tmp_ip->pnn,
908 0, CTDB_CONTROL_TAKEOVER_IP, 0,
912 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control CTDB_CONTROL_TAKEOVER_IP to node %u\n", tmp_ip->pnn));
913 talloc_free(tmp_ctx);
917 ctdb_client_async_add(async_data, state);
919 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
920 DEBUG(DEBUG_ERR,(__location__ " Async control CTDB_CONTROL_TAKEOVER_IP failed\n"));
921 talloc_free(tmp_ctx);
925 talloc_free(tmp_ctx);
931 destroy a ctdb_client_ip structure
933 static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
935 DEBUG(DEBUG_DEBUG,("destroying client tcp for %s:%u (client_id %u)\n",
936 inet_ntoa(ip->ip.sin_addr), ntohs(ip->ip.sin_port), ip->client_id));
937 DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
942 called by a client to inform us of a TCP connection that it is managing
943 that should tickled with an ACK when IP takeover is done
945 int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
948 struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
949 struct ctdb_control_tcp *p = (struct ctdb_control_tcp *)indata.dptr;
950 struct ctdb_tcp_list *tcp;
951 struct ctdb_control_tcp_vnn t;
954 struct ctdb_client_ip *ip;
955 struct ctdb_vnn *vnn;
957 vnn = find_public_ip_vnn(ctdb, p->dest);
959 if (ntohl(p->dest.sin_addr.s_addr) != INADDR_LOOPBACK) {
960 DEBUG(DEBUG_INFO,("Could not add client IP %s. This is not a public address.\n",
961 inet_ntoa(p->dest.sin_addr)));
966 if (vnn->pnn != ctdb->pnn) {
967 DEBUG(DEBUG_ERR,("Attempt to register tcp client for IP %s we don't hold - failing (client_id %u pid %u)\n",
968 inet_ntoa(p->dest.sin_addr),
969 client_id, client->pid));
970 /* failing this call will tell smbd to die */
974 ip = talloc(client, struct ctdb_client_ip);
975 CTDB_NO_MEMORY(ctdb, ip);
979 ip->client_id = client_id;
980 talloc_set_destructor(ip, ctdb_client_ip_destructor);
981 DLIST_ADD(ctdb->client_ip_list, ip);
983 tcp = talloc(client, struct ctdb_tcp_list);
984 CTDB_NO_MEMORY(ctdb, tcp);
986 tcp->connection.saddr = p->src;
987 tcp->connection.daddr = p->dest;
989 DLIST_ADD(client->tcp_list, tcp);
994 data.dptr = (uint8_t *)&t;
995 data.dsize = sizeof(t);
997 DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
998 (unsigned)ntohs(p->dest.sin_port),
999 inet_ntoa(p->src.sin_addr),
1000 (unsigned)ntohs(p->src.sin_port), client_id, client->pid));
1002 /* tell all nodes about this tcp connection */
1003 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
1004 CTDB_CONTROL_TCP_ADD,
1005 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1007 DEBUG(DEBUG_ERR,(__location__ " Failed to send CTDB_CONTROL_TCP_ADD\n"));
1015 see if two sockaddr_in are the same
1017 static bool same_sockaddr_in(struct sockaddr_in *in1, struct sockaddr_in *in2)
1019 return in1->sin_family == in2->sin_family &&
1020 in1->sin_port == in2->sin_port &&
1021 in1->sin_addr.s_addr == in2->sin_addr.s_addr;
1025 find a tcp address on a list
1027 static struct ctdb_tcp_connection *ctdb_tcp_find(struct ctdb_tcp_array *array,
1028 struct ctdb_tcp_connection *tcp)
1032 if (array == NULL) {
1036 for (i=0;i<array->num;i++) {
1037 if (same_sockaddr_in(&array->connections[i].saddr, &tcp->saddr) &&
1038 same_sockaddr_in(&array->connections[i].daddr, &tcp->daddr)) {
1039 return &array->connections[i];
1046 called by a daemon to inform us of a TCP connection that one of its
1047 clients managing that should tickled with an ACK when IP takeover is
1050 int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
1052 struct ctdb_control_tcp_vnn *p = (struct ctdb_control_tcp_vnn *)indata.dptr;
1053 struct ctdb_tcp_array *tcparray;
1054 struct ctdb_tcp_connection tcp;
1055 struct ctdb_vnn *vnn;
1057 vnn = find_public_ip_vnn(ctdb, p->dest);
1059 DEBUG(DEBUG_ERR,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
1060 inet_ntoa(p->dest.sin_addr)));
1065 tcparray = vnn->tcp_array;
1067 /* If this is the first tickle */
1068 if (tcparray == NULL) {
1069 tcparray = talloc_size(ctdb->nodes,
1070 offsetof(struct ctdb_tcp_array, connections) +
1071 sizeof(struct ctdb_tcp_connection) * 1);
1072 CTDB_NO_MEMORY(ctdb, tcparray);
1073 vnn->tcp_array = tcparray;
1076 tcparray->connections = talloc_size(tcparray, sizeof(struct ctdb_tcp_connection));
1077 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1079 tcparray->connections[tcparray->num].saddr = p->src;
1080 tcparray->connections[tcparray->num].daddr = p->dest;
1086 /* Do we already have this tickle ?*/
1088 tcp.daddr = p->dest;
1089 if (ctdb_tcp_find(vnn->tcp_array, &tcp) != NULL) {
1090 DEBUG(DEBUG_DEBUG,("Already had tickle info for %s:%u for vnn:%u\n",
1091 inet_ntoa(tcp.daddr.sin_addr),
1092 ntohs(tcp.daddr.sin_port),
1097 /* A new tickle, we must add it to the array */
1098 tcparray->connections = talloc_realloc(tcparray, tcparray->connections,
1099 struct ctdb_tcp_connection,
1101 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1103 vnn->tcp_array = tcparray;
1104 tcparray->connections[tcparray->num].saddr = p->src;
1105 tcparray->connections[tcparray->num].daddr = p->dest;
1108 DEBUG(DEBUG_INFO,("Added tickle info for %s:%u from vnn %u\n",
1109 inet_ntoa(tcp.daddr.sin_addr),
1110 ntohs(tcp.daddr.sin_port),
1118 called by a daemon to inform us of a TCP connection that one of its
1119 clients managing that should tickled with an ACK when IP takeover is
1122 static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tcp_connection *conn)
1124 struct ctdb_tcp_connection *tcpp;
1125 struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, conn->daddr);
1128 DEBUG(DEBUG_ERR,(__location__ " unable to find public address %s\n", inet_ntoa(conn->daddr.sin_addr)));
1132 /* if the array is empty we cant remove it
1133 and we dont need to do anything
1135 if (vnn->tcp_array == NULL) {
1136 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist (array is empty) %s:%u\n",
1137 inet_ntoa(conn->daddr.sin_addr),
1138 ntohs(conn->daddr.sin_port)));
1143 /* See if we know this connection
1144 if we dont know this connection then we dont need to do anything
1146 tcpp = ctdb_tcp_find(vnn->tcp_array, conn);
1148 DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist %s:%u\n",
1149 inet_ntoa(conn->daddr.sin_addr),
1150 ntohs(conn->daddr.sin_port)));
1155 /* We need to remove this entry from the array.
1156 Instead of allocating a new array and copying data to it
1157 we cheat and just copy the last entry in the existing array
1158 to the entry that is to be removed and just shring the
1161 *tcpp = vnn->tcp_array->connections[vnn->tcp_array->num - 1];
1162 vnn->tcp_array->num--;
1164 /* If we deleted the last entry we also need to remove the entire array
1166 if (vnn->tcp_array->num == 0) {
1167 talloc_free(vnn->tcp_array);
1168 vnn->tcp_array = NULL;
1171 vnn->tcp_update_needed = true;
1173 DEBUG(DEBUG_INFO,("Removed tickle info for %s:%u\n",
1174 inet_ntoa(conn->saddr.sin_addr),
1175 ntohs(conn->saddr.sin_port)));
1180 called when a daemon restarts - send all tickes for all public addresses
1181 we are serving immediately to the new node.
1183 int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t vnn)
1185 /*XXX here we should send all tickes we are serving to the new node */
1191 called when a client structure goes away - hook to remove
1192 elements from the tcp_list in all daemons
1194 void ctdb_takeover_client_destructor_hook(struct ctdb_client *client)
1196 while (client->tcp_list) {
1197 struct ctdb_tcp_list *tcp = client->tcp_list;
1198 DLIST_REMOVE(client->tcp_list, tcp);
1199 ctdb_remove_tcp_connection(client->ctdb, &tcp->connection);
1205 release all IPs on shutdown
1207 void ctdb_release_all_ips(struct ctdb_context *ctdb)
1209 struct ctdb_vnn *vnn;
1211 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1212 if (!ctdb_sys_have_ip(vnn->public_address)) {
1215 ctdb_event_script(ctdb, "releaseip %s %s %u",
1217 inet_ntoa(vnn->public_address.sin_addr),
1218 vnn->public_netmask_bits);
1219 release_kill_clients(ctdb, vnn->public_address);
1225 get list of public IPs
1227 int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb,
1228 struct ctdb_req_control *c, TDB_DATA *outdata)
1231 struct ctdb_all_public_ips *ips;
1232 struct ctdb_vnn *vnn;
1234 /* count how many public ip structures we have */
1236 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1240 len = offsetof(struct ctdb_all_public_ips, ips) +
1241 num*sizeof(struct ctdb_public_ip);
1242 ips = talloc_zero_size(outdata, len);
1243 CTDB_NO_MEMORY(ctdb, ips);
1245 outdata->dsize = len;
1246 outdata->dptr = (uint8_t *)ips;
1250 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1251 ips->ips[i].pnn = vnn->pnn;
1252 ips->ips[i].sin = vnn->public_address;
1262 structure containing the listening socket and the list of tcp connections
1263 that the ctdb daemon is to kill
1265 struct ctdb_kill_tcp {
1266 struct ctdb_vnn *vnn;
1267 struct ctdb_context *ctdb;
1270 struct fd_event *fde;
1271 trbt_tree_t *connections;
1276 a tcp connection that is to be killed
1278 struct ctdb_killtcp_con {
1279 struct sockaddr_in src;
1280 struct sockaddr_in dst;
1282 struct ctdb_kill_tcp *killtcp;
1285 /* this function is used to create a key to represent this socketpair
1286 in the killtcp tree.
1287 this key is used to insert and lookup matching socketpairs that are
1288 to be tickled and RST
1290 #define KILLTCP_KEYLEN 4
1291 static uint32_t *killtcp_key(struct sockaddr_in *src, struct sockaddr_in *dst)
1293 static uint32_t key[KILLTCP_KEYLEN];
1295 key[0] = dst->sin_addr.s_addr;
1296 key[1] = src->sin_addr.s_addr;
1297 key[2] = dst->sin_port;
1298 key[3] = src->sin_port;
1304 called when we get a read event on the raw socket
1306 static void capture_tcp_handler(struct event_context *ev, struct fd_event *fde,
1307 uint16_t flags, void *private_data)
1309 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
1310 struct ctdb_killtcp_con *con;
1311 struct sockaddr_in src, dst;
1312 uint32_t ack_seq, seq;
1314 if (!(flags & EVENT_FD_READ)) {
1318 if (ctdb_sys_read_tcp_packet(killtcp->capture_fd,
1319 killtcp->private_data,
1321 &ack_seq, &seq) != 0) {
1322 /* probably a non-tcp ACK packet */
1326 /* check if we have this guy in our list of connections
1329 con = trbt_lookuparray32(killtcp->connections,
1330 KILLTCP_KEYLEN, killtcp_key(&src, &dst));
1332 /* no this was some other packet we can just ignore */
1336 /* This one has been tickled !
1337 now reset him and remove him from the list.
1339 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)));
1341 ctdb_sys_send_tcp(killtcp->sending_fd, &con->dst,
1342 &con->src, ack_seq, seq, 1);
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);
1355 struct ctdb_kill_tcp *killtcp = talloc_get_type(param, struct ctdb_kill_tcp);
1357 /* have tried too many times, just give up */
1358 if (con->count >= 5) {
1363 /* othervise, try tickling it again */
1365 ctdb_sys_send_tcp(killtcp->sending_fd, &con->dst, &con->src, 0, 0, 0);
1370 called every second until all sentenced connections have been reset
1372 static void ctdb_tickle_sentenced_connections(struct event_context *ev, struct timed_event *te,
1373 struct timeval t, void *private_data)
1375 struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
1378 /* loop over all connections sending tickle ACKs */
1379 trbt_traversearray32(killtcp->connections, KILLTCP_KEYLEN, tickle_connection_traverse, killtcp);
1382 /* If there are no more connections to kill we can remove the
1383 entire killtcp structure
1385 if ( (killtcp->connections == NULL) ||
1386 (killtcp->connections->root == NULL) ) {
1387 talloc_free(killtcp);
1391 /* try tickling them again in a seconds time
1393 event_add_timed(killtcp->ctdb->ev, killtcp, timeval_current_ofs(1, 0),
1394 ctdb_tickle_sentenced_connections, killtcp);
1398 destroy the killtcp structure
1400 static int ctdb_killtcp_destructor(struct ctdb_kill_tcp *killtcp)
1402 if (killtcp->sending_fd != -1) {
1403 close(killtcp->sending_fd);
1404 killtcp->sending_fd = -1;
1406 killtcp->vnn->killtcp = NULL;
1411 /* nothing fancy here, just unconditionally replace any existing
1412 connection structure with the new one.
1414 dont even free the old one if it did exist, that one is talloc_stolen
1415 by the same node in the tree anyway and will be deleted when the new data
1418 static void *add_killtcp_callback(void *parm, void *data)
1424 add a tcp socket to the list of connections we want to RST
1426 static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
1427 struct sockaddr_in *src, struct sockaddr_in *dst)
1429 struct ctdb_kill_tcp *killtcp;
1430 struct ctdb_killtcp_con *con;
1431 struct ctdb_vnn *vnn;
1433 vnn = find_public_ip_vnn(ctdb, *dst);
1435 vnn = find_public_ip_vnn(ctdb, *src);
1438 /* if it is not a public ip it could be our 'single ip' */
1439 if (ctdb->single_ip_vnn) {
1440 if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, dst)) {
1441 vnn = ctdb->single_ip_vnn;
1446 DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n"));
1450 killtcp = vnn->killtcp;
1452 /* If this is the first connection to kill we must allocate
1455 if (killtcp == NULL) {
1456 killtcp = talloc_zero(ctdb, struct ctdb_kill_tcp);
1457 CTDB_NO_MEMORY(ctdb, killtcp);
1460 killtcp->ctdb = ctdb;
1461 killtcp->capture_fd = -1;
1462 killtcp->sending_fd = -1;
1463 killtcp->connections = trbt_create(killtcp, 0);
1465 vnn->killtcp = killtcp;
1466 talloc_set_destructor(killtcp, ctdb_killtcp_destructor);
1471 /* create a structure that describes this connection we want to
1472 RST and store it in killtcp->connections
1474 con = talloc(killtcp, struct ctdb_killtcp_con);
1475 CTDB_NO_MEMORY(ctdb, con);
1479 con->killtcp = killtcp;
1482 trbt_insertarray32_callback(killtcp->connections,
1483 KILLTCP_KEYLEN, killtcp_key(&con->dst, &con->src),
1484 add_killtcp_callback, con);
1487 If we dont have a socket to send from yet we must create it
1489 if (killtcp->sending_fd == -1) {
1490 killtcp->sending_fd = ctdb_sys_open_sending_socket();
1491 if (killtcp->sending_fd == -1) {
1492 DEBUG(DEBUG_CRIT,(__location__ " Failed to open sending socket for killtcp\n"));
1498 If we dont have a socket to listen on yet we must create it
1500 if (killtcp->capture_fd == -1) {
1501 killtcp->capture_fd = ctdb_sys_open_capture_socket(vnn->iface, &killtcp->private_data);
1502 if (killtcp->capture_fd == -1) {
1503 DEBUG(DEBUG_CRIT,(__location__ " Failed to open capturing socket for killtcp\n"));
1509 if (killtcp->fde == NULL) {
1510 killtcp->fde = event_add_fd(ctdb->ev, killtcp, killtcp->capture_fd,
1511 EVENT_FD_READ | EVENT_FD_AUTOCLOSE,
1512 capture_tcp_handler, killtcp);
1514 /* We also need to set up some events to tickle all these connections
1515 until they are all reset
1517 event_add_timed(ctdb->ev, killtcp, timeval_current_ofs(1, 0),
1518 ctdb_tickle_sentenced_connections, killtcp);
1521 /* tickle him once now */
1522 ctdb_sys_send_tcp(killtcp->sending_fd, &con->dst, &con->src, 0, 0, 0);
1527 talloc_free(vnn->killtcp);
1528 vnn->killtcp = NULL;
1533 kill a TCP connection.
1535 int32_t ctdb_control_kill_tcp(struct ctdb_context *ctdb, TDB_DATA indata)
1537 struct ctdb_control_killtcp *killtcp = (struct ctdb_control_killtcp *)indata.dptr;
1539 return ctdb_killtcp_add_connection(ctdb, &killtcp->src, &killtcp->dst);
1543 called by a daemon to inform us of the entire list of TCP tickles for
1544 a particular public address.
1545 this control should only be sent by the node that is currently serving
1546 that public address.
1548 int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata)
1550 struct ctdb_control_tcp_tickle_list *list = (struct ctdb_control_tcp_tickle_list *)indata.dptr;
1551 struct ctdb_tcp_array *tcparray;
1552 struct ctdb_vnn *vnn;
1554 /* We must at least have tickles.num or else we cant verify the size
1555 of the received data blob
1557 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
1558 tickles.connections)) {
1559 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list. Not enough data for the tickle.num field\n"));
1563 /* verify that the size of data matches what we expect */
1564 if (indata.dsize < offsetof(struct ctdb_control_tcp_tickle_list,
1565 tickles.connections)
1566 + sizeof(struct ctdb_tcp_connection)
1567 * list->tickles.num) {
1568 DEBUG(DEBUG_ERR,("Bad indata in ctdb_control_set_tcp_tickle_list\n"));
1572 vnn = find_public_ip_vnn(ctdb, list->ip);
1574 DEBUG(DEBUG_ERR,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n",
1575 inet_ntoa(list->ip.sin_addr)));
1579 /* remove any old ticklelist we might have */
1580 talloc_free(vnn->tcp_array);
1581 vnn->tcp_array = NULL;
1583 tcparray = talloc(ctdb->nodes, struct ctdb_tcp_array);
1584 CTDB_NO_MEMORY(ctdb, tcparray);
1586 tcparray->num = list->tickles.num;
1588 tcparray->connections = talloc_array(tcparray, struct ctdb_tcp_connection, tcparray->num);
1589 CTDB_NO_MEMORY(ctdb, tcparray->connections);
1591 memcpy(tcparray->connections, &list->tickles.connections[0],
1592 sizeof(struct ctdb_tcp_connection)*tcparray->num);
1594 /* We now have a new fresh tickle list array for this vnn */
1595 vnn->tcp_array = talloc_steal(vnn, tcparray);
1601 called to return the full list of tickles for the puclic address associated
1602 with the provided vnn
1604 int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata)
1606 struct sockaddr_in *ip = (struct sockaddr_in *)indata.dptr;
1607 struct ctdb_control_tcp_tickle_list *list;
1608 struct ctdb_tcp_array *tcparray;
1610 struct ctdb_vnn *vnn;
1612 vnn = find_public_ip_vnn(ctdb, *ip);
1614 DEBUG(DEBUG_ERR,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n",
1615 inet_ntoa(ip->sin_addr)));
1619 tcparray = vnn->tcp_array;
1621 num = tcparray->num;
1626 outdata->dsize = offsetof(struct ctdb_control_tcp_tickle_list,
1627 tickles.connections)
1628 + sizeof(struct ctdb_tcp_connection) * num;
1630 outdata->dptr = talloc_size(outdata, outdata->dsize);
1631 CTDB_NO_MEMORY(ctdb, outdata->dptr);
1632 list = (struct ctdb_control_tcp_tickle_list *)outdata->dptr;
1635 list->tickles.num = num;
1637 memcpy(&list->tickles.connections[0], tcparray->connections,
1638 sizeof(struct ctdb_tcp_connection) * num);
1646 set the list of all tcp tickles for a public address
1648 static int ctdb_ctrl_set_tcp_tickles(struct ctdb_context *ctdb,
1649 struct timeval timeout, uint32_t destnode,
1650 struct sockaddr_in *ip,
1651 struct ctdb_tcp_array *tcparray)
1655 struct ctdb_control_tcp_tickle_list *list;
1658 num = tcparray->num;
1663 data.dsize = offsetof(struct ctdb_control_tcp_tickle_list,
1664 tickles.connections) +
1665 sizeof(struct ctdb_tcp_connection) * num;
1666 data.dptr = talloc_size(ctdb, data.dsize);
1667 CTDB_NO_MEMORY(ctdb, data.dptr);
1669 list = (struct ctdb_control_tcp_tickle_list *)data.dptr;
1671 list->tickles.num = num;
1673 memcpy(&list->tickles.connections[0], tcparray->connections, sizeof(struct ctdb_tcp_connection) * num);
1676 ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
1677 CTDB_CONTROL_SET_TCP_TICKLE_LIST,
1678 0, CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL);
1680 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set tcp tickles failed\n"));
1684 talloc_free(data.dptr);
1691 perform tickle updates if required
1693 static void ctdb_update_tcp_tickles(struct event_context *ev,
1694 struct timed_event *te,
1695 struct timeval t, void *private_data)
1697 struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
1699 struct ctdb_vnn *vnn;
1701 for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
1702 /* we only send out updates for public addresses that
1705 if (ctdb->pnn != vnn->pnn) {
1708 /* We only send out the updates if we need to */
1709 if (!vnn->tcp_update_needed) {
1712 ret = ctdb_ctrl_set_tcp_tickles(ctdb,
1714 CTDB_BROADCAST_CONNECTED,
1715 &vnn->public_address,
1718 DEBUG(DEBUG_ERR,("Failed to send the tickle update for public address %s\n",
1719 inet_ntoa(vnn->public_address.sin_addr)));
1723 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
1724 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
1725 ctdb_update_tcp_tickles, ctdb);
1730 start periodic update of tcp tickles
1732 void ctdb_start_tcp_tickle_update(struct ctdb_context *ctdb)
1734 ctdb->tickle_update_context = talloc_new(ctdb);
1736 event_add_timed(ctdb->ev, ctdb->tickle_update_context,
1737 timeval_current_ofs(ctdb->tunable.tickle_update_interval, 0),
1738 ctdb_update_tcp_tickles, ctdb);
1744 struct control_gratious_arp {
1745 struct ctdb_context *ctdb;
1746 struct sockaddr_in sin;
1752 send a control_gratuitous arp
1754 static void send_gratious_arp(struct event_context *ev, struct timed_event *te,
1755 struct timeval t, void *private_data)
1758 struct control_gratious_arp *arp = talloc_get_type(private_data,
1759 struct control_gratious_arp);
1761 ret = ctdb_sys_send_arp(&arp->sin, arp->iface);
1763 DEBUG(DEBUG_ERR,(__location__ " sending of gratious arp failed (%s)\n", strerror(errno)));
1768 if (arp->count == CTDB_ARP_REPEAT) {
1773 event_add_timed(arp->ctdb->ev, arp,
1774 timeval_current_ofs(CTDB_ARP_INTERVAL, 0),
1775 send_gratious_arp, arp);
1782 int32_t ctdb_control_send_gratious_arp(struct ctdb_context *ctdb, TDB_DATA indata)
1784 struct ctdb_control_gratious_arp *gratious_arp = (struct ctdb_control_gratious_arp *)indata.dptr;
1785 struct control_gratious_arp *arp;
1788 /* verify the size of indata */
1789 if (indata.dsize < offsetof(struct ctdb_control_gratious_arp, iface)) {
1790 DEBUG(DEBUG_ERR,(__location__ " Too small indata to hold a ctdb_control_gratious_arp structure\n"));
1794 ( offsetof(struct ctdb_control_gratious_arp, iface)
1795 + gratious_arp->len ) ){
1797 DEBUG(DEBUG_ERR,(__location__ " Wrong size of indata. Was %u bytes "
1798 "but should be %u bytes\n",
1799 (unsigned)indata.dsize,
1800 (unsigned)(offsetof(struct ctdb_control_gratious_arp, iface)+gratious_arp->len)));
1805 arp = talloc(ctdb, struct control_gratious_arp);
1806 CTDB_NO_MEMORY(ctdb, arp);
1809 arp->sin = gratious_arp->sin;
1810 arp->iface = talloc_strdup(arp, gratious_arp->iface);
1811 CTDB_NO_MEMORY(ctdb, arp->iface);
1814 event_add_timed(arp->ctdb->ev, arp,
1815 timeval_zero(), send_gratious_arp, arp);