Find the vnn of the node that has a public ip address
returns -1 if the address is not known as a public address
*/
- static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, char *ip)
-static int32_t find_public_ip_vnn(struct ctdb_context *ctdb, char *ip)
++static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, struct sockaddr_in ip)
{
- int32_t vnn = -1;
- int i;
+ struct ctdb_vnn *vnn;
- for (i=0;i<ctdb->num_nodes;i++) {
- if (ctdb->nodes[i]->public_address && !strcmp(ip, ctdb->nodes[i]->public_address)) {
- vnn = i;
- break;
+ for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
- if (!strcmp(vnn->public_address, ip)) {
++ if (ctdb_same_ip(&vnn->public_address, &ip)) {
+ return vnn;
}
}
int ret;
struct takeover_callback_state *state;
struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
- char *ip = inet_ntoa(pip->sin.sin_addr);
- struct ctdb_node *node = ctdb->nodes[pip->vnn];
-
- /* update out node table */
- node->takeover_vnn = pip->takeover_vnn;
+ struct ctdb_vnn *vnn;
- char *ip = talloc_strdup(tmp_ctx, inet_ntoa(pip->sin.sin_addr));
+ bool have_ip, is_loopback;
+ char *ifname = NULL;
+
+ /* update out vnn list */
- vnn = find_public_ip_vnn(ctdb, ip);
++ vnn = find_public_ip_vnn(ctdb, pip->sin);
+ if (vnn == NULL) {
- DEBUG(0,("takeoverip called for an ip '%s' that is not a public address\n", ip));
++ DEBUG(0,("takeoverip called for an ip '%s' that is not a public address\n",
++ inet_ntoa(pip->sin.sin_addr)));
+ talloc_free(tmp_ctx);
+ return 0;
+ }
+ vnn->pnn = pip->pnn;
/* if our kernel already has this IP, do nothing */
- have_ip = ctdb_sys_have_ip(ip, &is_loopback, tmp_ctx, &ifname);
- if (ctdb_sys_have_ip(ip)) {
++ have_ip = ctdb_sys_have_ip(pip->sin, &is_loopback, tmp_ctx, &ifname);
+ /* if we have the ip and it is not set to a loopback address */
+ if (have_ip && !is_loopback) {
+ talloc_free(tmp_ctx);
return 0;
}
CTDB_NO_MEMORY(ctdb, state->sin);
*state->sin = pip->sin;
- state->node = node;
+ state->vnn = vnn;
- DEBUG(0,("Takover of IP %s/%u on interface %s\n",
- ip, ctdb->nodes[ctdb->vnn]->public_netmask_bits,
- ctdb->takeover.interface));
+ DEBUG(0,("Takeover of IP %s/%u on interface %s\n",
- ip, vnn->public_netmask_bits,
++ inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
+ vnn->iface));
ctdb_stop_monitoring(ctdb);
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
state, takeover_ip_callback, state,
"takeip %s %s %u",
- ctdb->takeover.interface,
- ip,
- ctdb->nodes[ctdb->vnn]->public_netmask_bits);
+ vnn->iface,
- ip,
++ inet_ntoa(pip->sin.sin_addr),
+ vnn->public_netmask_bits);
if (ret != 0) {
DEBUG(0,(__location__ " Failed to takeover IP %s on interface %s\n",
- ip, vnn->iface));
- ip, ctdb->takeover.interface));
++ inet_ntoa(pip->sin.sin_addr), vnn->iface));
+ talloc_free(tmp_ctx);
talloc_free(state);
return -1;
}
/*
kill any clients that are registered with a IP that is being released
*/
--static void release_kill_clients(struct ctdb_context *ctdb, struct in_addr in)
++static void release_kill_clients(struct ctdb_context *ctdb, struct sockaddr_in in)
{
struct ctdb_client_ip *ip;
for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
-- if (ip->ip.sin_addr.s_addr == in.s_addr) {
++ if (ctdb_same_ip(&ip->ip, &in)) {
struct ctdb_client *client = ctdb_reqid_find(ctdb,
ip->client_id,
struct ctdb_client);
if (client->pid != 0) {
DEBUG(0,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
-- (unsigned)client->pid, inet_ntoa(in),
++ (unsigned)client->pid, inet_ntoa(in.sin_addr),
ip->client_id));
kill(client->pid, SIGKILL);
}
data.dptr = (uint8_t *)ip;
data.dsize = strlen(ip)+1;
- ctdb_daemon_send_message(ctdb, ctdb->vnn, CTDB_SRVID_RELEASE_IP, data);
+ ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data);
/* kill clients that have registered with this IP */
-- release_kill_clients(ctdb, state->sin->sin_addr);
++ release_kill_clients(ctdb, *state->sin);
/* the control succeeded */
ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
int ret;
struct takeover_callback_state *state;
struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
- char *ip = talloc_strdup(tmp_ctx, inet_ntoa(pip->sin.sin_addr));
- char *ip = inet_ntoa(pip->sin.sin_addr);
- struct ctdb_node *node = ctdb->nodes[pip->vnn];
-
- /* update out node table */
- ctdb->nodes[pip->vnn]->takeover_vnn = pip->takeover_vnn;
-
- if (!ctdb_sys_have_ip(ip)) {
+ struct ctdb_vnn *vnn;
+ bool have_ip, is_loopback;
+ char *ifname = NULL;
+
+ /* update our vnn list */
- vnn = find_public_ip_vnn(ctdb, ip);
++ vnn = find_public_ip_vnn(ctdb, pip->sin);
+ if (vnn == NULL) {
- DEBUG(0,("releaseip called for an ip '%s' that is not a public address\n", ip));
++ DEBUG(0,("releaseip called for an ip '%s' that is not a public address\n",
++ inet_ntoa(pip->sin.sin_addr)));
+ talloc_free(tmp_ctx);
+ return 0;
+ }
+ vnn->pnn = pip->pnn;
+
- have_ip = ctdb_sys_have_ip(ip, &is_loopback, tmp_ctx, &ifname);
++ have_ip = ctdb_sys_have_ip(pip->sin, &is_loopback, tmp_ctx, &ifname);
+ if ( (!have_ip) || is_loopback) {
+ DEBUG(0,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
- ip, vnn->public_netmask_bits,
++ inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
+ vnn->iface));
+ talloc_free(tmp_ctx);
return 0;
}
DEBUG(0,("Release of IP %s/%u on interface %s\n",
- ip, vnn->public_netmask_bits,
- ip, ctdb->nodes[ctdb->vnn]->public_netmask_bits,
- ctdb->takeover.interface));
++ inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
+ vnn->iface));
/* stop any previous arps */
- talloc_free(ctdb->takeover.last_ctx);
- ctdb->takeover.last_ctx = NULL;
+ talloc_free(vnn->takeover_ctx);
+ vnn->takeover_ctx = NULL;
state = talloc(ctdb, struct takeover_callback_state);
CTDB_NO_MEMORY(ctdb, state);
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
state, release_ip_callback, state,
"releaseip %s %s %u",
- ctdb->takeover.interface,
- ip,
- ctdb->nodes[ctdb->vnn]->public_netmask_bits);
+ vnn->iface,
- ip,
++ inet_ntoa(pip->sin.sin_addr),
+ vnn->public_netmask_bits);
if (ret != 0) {
DEBUG(0,(__location__ " Failed to release IP %s on interface %s\n",
- ip, vnn->iface));
- ip, ctdb->takeover.interface));
++ inet_ntoa(pip->sin.sin_addr), vnn->iface));
+ talloc_free(tmp_ctx);
talloc_free(state);
return -1;
}
/* tell the control that we will be reply asynchronously */
*async_reply = true;
- static int add_public_address(struct ctdb_context *ctdb, int ip0, int ip1, int ip2, int ip3, int nm, char *iface)
+ talloc_free(tmp_ctx);
+ return 0;
+}
+
+
+
- char *public_address;
++static int add_public_address(struct ctdb_context *ctdb, struct sockaddr_in addr, unsigned mask, const char *iface)
+{
+ struct ctdb_vnn *vnn;
- public_address = talloc_asprintf(ctdb, "%d.%d.%d.%d", ip0, ip1, ip2, ip3);
- CTDB_NO_MEMORY_FATAL(ctdb, public_address);
+
+ /* Verify that we dont have an entry for this ip yet */
- if (!strcmp(public_address, vnn->public_address)) {
- DEBUG(0,("Same ip '%s' specified multiple times in the public address list \n", public_address));
- talloc_free(public_address);
+ for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
-
- /* make sure the netmask is ok */
- if (nm > 32) {
- DEBUG(0, ("Illegal netmask for IP %s\n", public_address));
- talloc_free(public_address);
- exit(1);
- }
-
++ if (ctdb_same_sockaddr(&addr, &vnn->public_address)) {
++ DEBUG(0,("Same ip '%s' specified multiple times in the public address list \n",
++ inet_ntoa(addr.sin_addr)));
+ exit(1);
+ }
+ }
+
- if (iface) {
- vnn->iface = talloc_strdup(vnn, iface);
- }
- vnn->public_address = talloc_steal(vnn, public_address);
- vnn->public_netmask_bits = nm;
- vnn->pnn = -1;
+ /* create a new vnn structure for this ip address */
+ vnn = talloc_zero(ctdb, struct ctdb_vnn);
+ CTDB_NO_MEMORY_FATAL(ctdb, vnn);
++ vnn->iface = talloc_strdup(vnn, iface);
++ vnn->public_address = addr;
++ vnn->public_netmask_bits = mask;
++ vnn->pnn = -1;
+
+ DLIST_ADD(ctdb->vnn, vnn);
+
return 0;
}
nlines--;
}
- if (nlines != ctdb->num_nodes) {
- DEBUG(0,("Number of lines in %s does not match number of nodes!\n", alist));
- talloc_free(lines);
- return -1;
- }
-
for (i=0;i<nlines;i++) {
- int ip0, ip1, ip2, ip3, nm;
- char iface[256];
- char *p;
- struct in_addr in;
--
- if (sscanf(lines[i], "%d.%d.%d.%d/%d %255s", &ip0, &ip1, &ip2, &ip3, &nm, iface) != 6) {
- DEBUG(0,("Badly formed line '%s' in public address list\n", lines[i]));
- ctdb->nodes[i]->public_address = talloc_strdup(ctdb->nodes[i], lines[i]);
- CTDB_NO_MEMORY(ctdb, ctdb->nodes[i]->public_address);
- ctdb->nodes[i]->takeover_vnn = -1;
-
- /* see if they supplied a netmask length */
- p = strchr(ctdb->nodes[i]->public_address, '/');
- if (!p) {
- DEBUG(0,("You must supply a netmask for public address %s\n",
- ctdb->nodes[i]->public_address));
++ unsigned mask;
++ struct sockaddr_in addr;
++ char ifacebuf[100];
++ const char *iface;
++ char *tok;
++
++ tok = strtok(lines[i], " \t");
++ if (!tok || !parse_ip_mask(tok, &addr, &mask)) {
++ DEBUG(0,("Badly formed line %u in public address list\n", i+1));
+ talloc_free(lines);
return -1;
}
- *p = 0;
- ctdb->nodes[i]->public_netmask_bits = atoi(p+1);
-
- if (ctdb->nodes[i]->public_netmask_bits > 32) {
- DEBUG(0, ("Illegal netmask for IP %s\n", ctdb->nodes[i]->public_address));
- return -1;
++ tok = strtok(NULL, " \t");
++ if (tok == NULL) {
++ if (NULL == ctdb->default_public_interface) {
++ DEBUG(0,("No default public interface and no interface specified at line %u of public address list\n",
++ i+1));
++ talloc_free(lines);
++ return -1;
++ }
++ iface = ctdb->default_public_interface;
++ } else {
++ iface = ifacebuf;
+ }
- if (add_public_address(ctdb, ip0, ip1, ip2, ip3, nm, iface)) {
- DEBUG(0,("Failed to add '%s' to the public address list\n", lines[i]));
- if (inet_aton(ctdb->nodes[i]->public_address, &in) == 0) {
- DEBUG(0,("Badly formed IP '%s' in public address list\n", ctdb->nodes[i]->public_address));
++ if (add_public_address(ctdb, addr, mask, iface)) {
++ DEBUG(0,("Failed to add line %u to the public address list\n", i+1));
+ talloc_free(lines);
return -1;
}
}
}
-/*
- try to find an available node to take a given nodes IP that meets the
- criterion given by the flags
- */
-static void ctdb_takeover_find_node(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap,
- int node, uint32_t mask_flags)
+/* search the node lists list for a node to takeover this ip.
+ pick the node that currently are serving the least number of ips
+ so that the ips get spread out evenly.
+*/
+static int find_takeover_node(struct ctdb_context *ctdb,
+ struct ctdb_node_map *nodemap, uint32_t mask,
+ struct ctdb_public_ip_list *ip,
+ struct ctdb_public_ip_list *all_ips)
{
- int pnn, min, num;
- static int start_node=0;
- int j;
++ int pnn, min=0, num;
+ int i;
- /* If we add facilities to add/remove nodes to a cluster at runtime
- we must make sure that start_node is suddently not beyond the
- end of the nodelist
- */
- if (start_node >= nodemap->num) {
- start_node = 0;
- }
-
- j=start_node;
- while (1) {
- if (!(nodemap->nodes[j].flags & mask_flags) &&
- ctdb_same_subnet(ctdb->nodes[j]->public_address,
- ctdb->nodes[node]->public_address,
- ctdb->nodes[j]->public_netmask_bits)) {
- ctdb->nodes[node]->takeover_vnn = nodemap->nodes[j].vnn;
- /* We found a node to take over
- also update the startnode so that we start at a
- different node next time we are called.
- */
- start_node = (j+1)%nodemap->num;;
- return;
+ pnn = -1;
+ for (i=0;i<nodemap->num;i++) {
+ if (nodemap->nodes[i].flags & mask) {
+ /* This node is not healty and can not be used to serve
+ a public address
+ */
+ continue;
}
- /* Try the next node */
- j=(j+1)%nodemap->num;
+ /* verify that this node can serve this ip */
+ if (can_node_serve_ip(ctdb, i, ip)) {
+ /* no it couldnt so skip to the next node */
+ continue;
+ }
- /* We tried all the nodes and got back to where we started,
- there is no node that can take over
- */
- if (j == start_node) {
- break;
+ num = node_ip_coverage(ctdb, i, all_ips);
+ /* was this the first node we checked ? */
+ if (pnn == -1) {
+ pnn = i;
+ min = num;
+ } else {
+ if (num < min) {
+ pnn = i;
+ min = num;
+ }
}
+ }
+ if (pnn == -1) {
+ DEBUG(0,(__location__ " Could not find node to take over public address '%s'\n", inet_ntoa(ip->sin.sin_addr)));
+ return -1;
}
- /* No takeover node found */
- return;
+ ip->pnn = pnn;
+ return 0;
+}
+
+struct ctdb_public_ip_list *
+add_ip_to_merged_list(struct ctdb_context *ctdb,
+ TALLOC_CTX *tmp_ctx,
+ struct ctdb_public_ip_list *ip_list,
+ struct ctdb_public_ip *ip)
+{
+ struct ctdb_public_ip_list *tmp_ip;
+
+ /* do we already have this ip in our merged list ?*/
+ for (tmp_ip=ip_list;tmp_ip;tmp_ip=tmp_ip->next) {
+
+ /* we already have this public ip in the list */
+ if (tmp_ip->sin.sin_addr.s_addr == ip->sin.sin_addr.s_addr) {
+ return ip_list;
+ }
+ }
+
+ /* this is a new public ip, we must add it to the list */
+ tmp_ip = talloc_zero(tmp_ctx, struct ctdb_public_ip_list);
+ CTDB_NO_MEMORY_NULL(ctdb, tmp_ip);
+ tmp_ip->pnn = ip->pnn;
+ tmp_ip->sin = ip->sin;
+ tmp_ip->next = ip_list;
+
+ return tmp_ip;
}
+struct ctdb_public_ip_list *
+create_merged_ip_list(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx)
+{
+ int i, j;
+ struct ctdb_public_ip_list *ip_list = NULL;
+ struct ctdb_all_public_ips *public_ips;
+
+ for (i=0;i<ctdb->num_nodes;i++) {
+ public_ips = ctdb->nodes[i]->public_ips;
+
+ /* there were no public ips for this node */
+ if (public_ips == NULL) {
+ continue;
+ }
+
+ for (j=0;j<public_ips->num;j++) {
+ ip_list = add_ip_to_merged_list(ctdb, tmp_ctx,
+ ip_list, &public_ips->ips[j]);
+ }
+ }
+
+ return ip_list;
+}
/*
make any IP alias changes for public addresses that are necessary
*/
int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
{
- int i, j;
+ int i, num_healthy, retries;
int ret;
struct ctdb_public_ip ip;
- int maxnode, maxnum, minnode, minnum, num;
+ uint32_t mask;
+ struct ctdb_public_ip_list *all_ips, *tmp_ip;
++ int maxnode, maxnum=0, minnode, minnum=0, num;
+ TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+
ZERO_STRUCT(ip);
int ret;
TDB_DATA data;
struct ctdb_client_ip *ip;
-- char *addr;
- int32_t takeover_vnn;
+ struct ctdb_vnn *vnn;
-- addr = inet_ntoa(p->dest.sin_addr);
--
- vnn = find_public_ip_vnn(ctdb, addr);
- takeover_vnn = find_public_ip_vnn(ctdb, addr);
- if (takeover_vnn == -1) {
- DEBUG(3,("Could not add client IP %s. This is not a public address.\n", addr));
++ vnn = find_public_ip_vnn(ctdb, p->dest);
+ if (vnn == NULL) {
- DEBUG(3,("Could not add client IP %s. This is not a public address.\n", addr));
++ DEBUG(3,("Could not add client IP %s. This is not a public address.\n", inet_ntoa(p->dest.sin_addr)));
return 0;
}
struct ctdb_control_tcp_vnn *p = (struct ctdb_control_tcp_vnn *)indata.dptr;
struct ctdb_tcp_array *tcparray;
struct ctdb_tcp_connection tcp;
- char *addr;
+ struct ctdb_vnn *vnn;
- addr = inet_ntoa(p->dest.sin_addr);
- vnn = find_public_ip_vnn(ctdb, addr);
+
- DEBUG(0,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n", addr));
++ vnn = find_public_ip_vnn(ctdb, p->dest);
+ if (vnn == NULL) {
++ DEBUG(0,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
++ inet_ntoa(p->dest.sin_addr)));
+ return-1;
+ }
- tcparray = ctdb->nodes[p->vnn]->tcp_array;
+
+ tcparray = vnn->tcp_array;
/* If this is the first tickle */
if (tcparray == NULL) {
static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tcp_connection *conn)
{
struct ctdb_tcp_connection *tcpp;
- struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, inet_ntoa(conn->daddr.sin_addr));
- int32_t vnn = find_public_ip_vnn(ctdb, inet_ntoa(conn->daddr.sin_addr));
- struct ctdb_node *node;
++ struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, conn->daddr);
- if (vnn == -1) {
+ if (vnn == NULL) {
DEBUG(0,(__location__ " unable to find public address %s\n", inet_ntoa(conn->daddr.sin_addr)));
return;
}
*/
void ctdb_release_all_ips(struct ctdb_context *ctdb)
{
- int i;
-
- if (!ctdb->takeover.enabled) {
- return;
- }
-
- for (i=0;i<ctdb->num_nodes;i++) {
- struct ctdb_node *node = ctdb->nodes[i];
- if (ctdb_sys_have_ip(node->public_address)) {
- struct in_addr in;
+ struct ctdb_vnn *vnn;
+ TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+ bool have_ip, is_loopback;
+ char *ifname = NULL;
+
+ for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
+ have_ip = ctdb_sys_have_ip(vnn->public_address, &is_loopback, tmp_ctx, &ifname);
+ if (have_ip && !is_loopback) {
- struct in_addr in;
-
ctdb_event_script(ctdb, "releaseip %s %s %u",
- ctdb->takeover.interface,
- node->public_address,
- node->public_netmask_bits);
- if (inet_aton(node->public_address, &in) != 0) {
- release_kill_clients(ctdb, in);
- }
+ vnn->iface,
- vnn->public_address,
++ inet_ntoa(vnn->public_address.sin_addr),
+ vnn->public_netmask_bits);
- if (inet_aton(vnn->public_address, &in) != 0) {
- release_kill_clients(ctdb, in);
- }
++ release_kill_clients(ctdb, vnn->public_address);
}
}
+ talloc_free(tmp_ctx);
}
outdata->dsize = len;
outdata->dptr = (uint8_t *)ips;
- ips->num = ctdb->num_nodes;
- for(i=0;i<ctdb->num_nodes;i++){
- ips->ips[i].vnn = i;
- ips->ips[i].takeover_vnn = ctdb->nodes[i]->takeover_vnn;
- ips->ips[i].sin.sin_family = AF_INET;
- if (ctdb->nodes[i]->public_address) {
- inet_aton(ctdb->nodes[i]->public_address,
- &ips->ips[i].sin.sin_addr);
- }
+ ips->num = num;
+ i = 0;
+ for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
- ips->ips[i].pnn = vnn->pnn;
- ips->ips[i].sin.sin_family = AF_INET;
- inet_aton(vnn->public_address,
- &ips->ips[i].sin.sin_addr);
++ ips->ips[i].pnn = vnn->pnn;
++ ips->ips[i].sin = vnn->public_address;
+ i++;
}
return 0;
static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
struct sockaddr_in *src, struct sockaddr_in *dst)
{
- struct ctdb_kill_tcp *killtcp = ctdb->killtcp;
+ struct ctdb_kill_tcp *killtcp;
struct ctdb_killtcp_con *con;
- vnn = find_public_ip_vnn(ctdb, inet_ntoa(dst->sin_addr));
+ struct ctdb_vnn *vnn;
+
- vnn = find_public_ip_vnn(ctdb, inet_ntoa(src->sin_addr));
++ vnn = find_public_ip_vnn(ctdb, *dst);
+ if (vnn == NULL) {
++ vnn = find_public_ip_vnn(ctdb, *src);
+ }
+ if (vnn == NULL) {
+ DEBUG(0,(__location__ " Could not killtcp, not a public address\n"));
+ return -1;
+ }
+
+ killtcp = vnn->killtcp;
/* If this is the first connection to kill we must allocate
a new structure
{
struct ctdb_control_tcp_tickle_list *list = (struct ctdb_control_tcp_tickle_list *)indata.dptr;
struct ctdb_tcp_array *tcparray;
- char *addr;
+ struct ctdb_vnn *vnn;
/* We must at least have tickles.num or else we cant verify the size
of the received data blob
return -1;
}
- addr = inet_ntoa(list->ip.sin_addr);
-
- vnn = find_public_ip_vnn(ctdb, addr);
- /* Make sure the vnn looks sane */
- if (!ctdb_validate_vnn(ctdb, list->vnn)) {
- DEBUG(0,("Bad indata in ctdb_control_set_tcp_tickle_list. Invalid vnn: %u\n", list->vnn));
- return -1;
++ vnn = find_public_ip_vnn(ctdb, list->ip);
+ if (vnn == NULL) {
- DEBUG(0,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n", addr));
++ DEBUG(0,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n",
++ inet_ntoa(list->ip.sin_addr)));
+ return 1;
}
-
/* remove any old ticklelist we might have */
- talloc_free(ctdb->nodes[list->vnn]->tcp_array);
- ctdb->nodes[list->vnn]->tcp_array = NULL;
+ talloc_free(vnn->tcp_array);
+ vnn->tcp_array = NULL;
tcparray = talloc(ctdb->nodes, struct ctdb_tcp_array);
CTDB_NO_MEMORY(ctdb, tcparray);
struct ctdb_control_tcp_tickle_list *list;
struct ctdb_tcp_array *tcparray;
int num;
- char *addr;
+ struct ctdb_vnn *vnn;
-
- addr = inet_ntoa(ip->sin_addr);
--
- vnn = find_public_ip_vnn(ctdb, addr);
- /* Make sure the vnn looks sane */
- if (!ctdb_validate_vnn(ctdb, vnn)) {
- DEBUG(0,("Bad indata in ctdb_control_get_tcp_tickle_list. Invalid vnn: %u\n", vnn));
- return -1;
++ vnn = find_public_ip_vnn(ctdb, *ip);
+ if (vnn == NULL) {
- DEBUG(0,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n", addr));
++ DEBUG(0,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n",
++ inet_ntoa(ip->sin_addr)));
+ return 1;
}
- tcparray = ctdb->nodes[vnn]->tcp_array;
+ tcparray = vnn->tcp_array;
if (tcparray) {
num = tcparray->num;
} else {
struct timeval t, void *private_data)
{
struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
- int i, ret;
-
- for (i=0;i<ctdb->num_nodes;i++) {
- struct ctdb_node *node = ctdb->nodes[i];
+ int ret;
+ struct ctdb_vnn *vnn;
- struct sockaddr_in ip;
- /* we only send out updates for public addresses that we
- have taken over
+ for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
+ /* we only send out updates for public addresses that
+ we have taken over
*/
- if (ctdb->vnn != node->takeover_vnn) {
+ if (ctdb->pnn != vnn->pnn) {
continue;
}
/* We only send out the updates if we need to */
- if (!node->tcp_update_needed) {
+ if (!vnn->tcp_update_needed) {
continue;
}
- inet_aton(vnn->public_address, &ip.sin_addr);
-
ret = ctdb_ctrl_set_tcp_tickles(ctdb,
TAKEOVER_TIMEOUT(),
CTDB_BROADCAST_CONNECTED,
- &ip,
- node->takeover_vnn,
- node->tcp_array);
++ &vnn->public_address,
+ vnn->tcp_array);
if (ret != 0) {
- DEBUG(0,("Failed to send the tickle update for public address %s\n", vnn->public_address));
- DEBUG(0,("Failed to send the tickle update for public address %s\n", node->public_address));
++ DEBUG(0,("Failed to send the tickle update for public address %s\n",
++ inet_ntoa(vnn->public_address.sin_addr)));
}
}