From 79b54a624e320a4eb0c20d910b6107ba3cbea393 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 4 Jun 2007 20:07:37 +1000 Subject: [PATCH] change the takoverip/releaseip controls to pass a structure containing both the nodenumber and the id of the node that has taken over that address in addition to the public address itself so that all nodes can learn which node is currently hosting each of the public addresses (This used to be ctdb commit 53e9ff790387b85a36fa9c3c44cd4c95cbdf35da) --- ctdb/common/ctdb_client.c | 30 ++++++----------------------- ctdb/common/ctdb_control.c | 4 ++-- ctdb/include/ctdb_private.h | 12 +++++++++--- ctdb/takeover/ctdb_takeover.c | 36 +++++++++++++++++++++++++++++------ 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index 154ce86129c..0f3396dda43 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -1825,23 +1825,14 @@ int ctdb_ctrl_delete_low_rsn(struct ctdb_context *ctdb, struct timeval timeout, sent to a node to make it take over an ip address */ int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout, - uint32_t destnode, const char *ip) + uint32_t destnode, struct ctdb_public_ip *ip) { TDB_DATA data; int ret; int32_t res; - struct sockaddr sa; - struct sockaddr_in *sin = (struct sockaddr_in *)&sa; - ZERO_STRUCT(sa); -#ifdef HAVE_SOCK_SIN_LEN - sin->sin_len = sizeof(*sin); -#endif - sin->sin_family = AF_INET; - inet_aton(ip, &sin->sin_addr); - - data.dsize = sizeof(sa); - data.dptr = (uint8_t *)&sa; + data.dsize = sizeof(*ip); + data.dptr = (uint8_t *)ip; ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL, NULL, &res, &timeout, NULL); @@ -1859,23 +1850,14 @@ int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout, sent to a node to make it release an ip address */ int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout, - uint32_t destnode, const char *ip) + uint32_t destnode, struct ctdb_public_ip *ip) { TDB_DATA data; int ret; int32_t res; - struct sockaddr sa; - struct sockaddr_in *sin = (struct sockaddr_in *)&sa; - ZERO_STRUCT(sa); -#ifdef HAVE_SOCK_SIN_LEN - sin->sin_len = sizeof(*sin); -#endif - sin->sin_family = AF_INET; - inet_aton(ip, &sin->sin_addr); - - data.dsize = sizeof(sa); - data.dptr = (uint8_t *)&sa; + data.dsize = sizeof(*ip); + data.dptr = (uint8_t *)ip; ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL, NULL, &res, &timeout, NULL); diff --git a/ctdb/common/ctdb_control.c b/ctdb/common/ctdb_control.c index f73672796e6..2cd3ac57a7b 100644 --- a/ctdb/common/ctdb_control.c +++ b/ctdb/common/ctdb_control.c @@ -265,11 +265,11 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, return ctdb_control_set_rsn_nonempty(ctdb, indata, outdata); case CTDB_CONTROL_TAKEOVER_IP: - CHECK_CONTROL_DATA_SIZE(sizeof(struct sockaddr)); + CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip)); return ctdb_control_takeover_ip(ctdb, c, indata, async_reply); case CTDB_CONTROL_RELEASE_IP: - CHECK_CONTROL_DATA_SIZE(sizeof(struct sockaddr)); + CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip)); return ctdb_control_release_ip(ctdb, c, indata, async_reply); case CTDB_CONTROL_DELETE_LOW_RSN: diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 9f0224288f2..86bee8b4bcc 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -942,14 +942,20 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA indata, bool *async_reply); -int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout, - uint32_t destnode, const char *ip); int32_t ctdb_control_release_ip(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA indata, bool *async_reply); + +struct ctdb_public_ip { + uint32_t vnn; + uint32_t takeover_vnn; + struct sockaddr_in sin; +}; +int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout, + uint32_t destnode, struct ctdb_public_ip *ip); int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout, - uint32_t destnode, const char *ip); + uint32_t destnode, struct ctdb_public_ip *ip); /* from takeover/system.c */ int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface); diff --git a/ctdb/takeover/ctdb_takeover.c b/ctdb/takeover/ctdb_takeover.c index af250f570bc..d4c51dcd5e0 100644 --- a/ctdb/takeover/ctdb_takeover.c +++ b/ctdb/takeover/ctdb_takeover.c @@ -162,8 +162,12 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb, { int ret; struct takeover_callback_state *state; - struct sockaddr_in *sin = (struct sockaddr_in *)indata.dptr; - char *ip = inet_ntoa(sin->sin_addr); + struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr; + char *ip = inet_ntoa(pip->sin.sin_addr); + + + /* update out node table */ + ctdb->nodes[pip->vnn]->takeover_vnn = pip->takeover_vnn; /* if our kernel already has this IP, do nothing */ if (ctdb_sys_have_ip(ip)) { @@ -256,8 +260,11 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb, { int ret; struct takeover_callback_state *state; - struct sockaddr_in *sin = (struct sockaddr_in *)indata.dptr; - char *ip = inet_ntoa(sin->sin_addr); + struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr; + char *ip = inet_ntoa(pip->sin.sin_addr); + + /* update out node table */ + ctdb->nodes[pip->vnn]->takeover_vnn = pip->takeover_vnn; if (!ctdb_sys_have_ip(ip)) { return 0; @@ -392,6 +399,7 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap) { int i, j; int ret; + struct ctdb_public_ip ip; /* work out which node will look after each public IP */ for (i=0;inum;i++) { @@ -431,9 +439,17 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap) /* tell this node to delete all of the aliases that it should not have */ for (j=0;jnum;j++) { if (ctdb->nodes[j]->takeover_vnn != nodemap->nodes[i].vnn) { + ip.vnn = j; + ip.takeover_vnn = ctdb->nodes[j]->takeover_vnn; +#ifdef HAVE_SOCK_SIN_LEN + ip.sin.sin_len = sizeof(*sin); +#endif + ip.sin.sin_family = AF_INET; + inet_aton(ctdb->nodes[j]->public_address, &ip.sin.sin_addr); + ret = ctdb_ctrl_release_ip(ctdb, TAKEOVER_TIMEOUT(), nodemap->nodes[i].vnn, - ctdb->nodes[j]->public_address); + &ip); if (ret != 0) { DEBUG(0,("Failed to tell vnn %u to release IP %s\n", nodemap->nodes[i].vnn, @@ -450,9 +466,17 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap) /* this IP won't be taken over */ continue; } + ip.vnn = i; + ip.takeover_vnn = ctdb->nodes[i]->takeover_vnn; +#ifdef HAVE_SOCK_SIN_LEN + ip.sin.sin_len = sizeof(*sin); +#endif + ip.sin.sin_family = AF_INET; + inet_aton(ctdb->nodes[i]->public_address, &ip.sin.sin_addr); + ret = ctdb_ctrl_takeover_ip(ctdb, TAKEOVER_TIMEOUT(), ctdb->nodes[i]->takeover_vnn, - ctdb->nodes[i]->public_address); + &ip); if (ret != 0) { DEBUG(0,("Failed asking vnn %u to take over IP %s\n", ctdb->nodes[i]->takeover_vnn,