[SCM] CTDB repository - branch master updated -
a63825e32658b36e0964584758b9a276c18056b8
Ronnie Sahlberg
sahlberg at samba.org
Wed Apr 23 11:09:34 GMT 2008
The branch, master has been updated
via a63825e32658b36e0964584758b9a276c18056b8 (commit)
from 0a4e667f42c6fb23be13651f7b0d0a545a49900b (commit)
http://gitweb.samba.org/?p=sahlberg/ctdb.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit a63825e32658b36e0964584758b9a276c18056b8
Author: Ronnie Sahlberg <sahlberg at samba.org>
Date: Wed Apr 23 21:05:36 2008 +1000
when adding a new public ip address to a running node using the 'ctdb addip' command,
If no other node is hosting this public ip at the moment, then assign it immediately to the current node.
-----------------------------------------------------------------------
Summary of changes:
tools/ctdb.c | 255 +++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 153 insertions(+), 102 deletions(-)
Changeset truncated at 500 lines:
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 2a3228b..6e94417 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -417,6 +417,40 @@ static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char *
return 0;
}
+/* send a release ip to all nodes */
+static int control_send_release(struct ctdb_context *ctdb, uint32_t pnn,
+struct sockaddr_in *sin)
+{
+ int ret;
+ struct ctdb_public_ip pip;
+ TDB_DATA data;
+ struct ctdb_node_map *nodemap=NULL;
+
+ ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
+ return ret;
+ }
+
+ /* send a moveip message to the recovery master */
+ pip.pnn = pnn;
+ pip.sin.sin_family = AF_INET;
+ pip.sin.sin_addr = sin->sin_addr;
+ data.dsize = sizeof(pip);
+ data.dptr = (unsigned char *)&pip;
+
+
+ /* send release ip to all nodes */
+ if (ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
+ list_of_active_nodes(ctdb, nodemap, ctdb, true),
+ TIMELIMIT(), false, data) != 0) {
+ DEBUG(DEBUG_ERR, (__location__ " Unable to send 'ReleaseIP' to all nodes.\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
/*
move/failover an ip address to a specific node
*/
@@ -426,9 +460,6 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
struct sockaddr_in ip;
uint32_t value;
struct ctdb_all_public_ips *ips;
- struct ctdb_public_ip pip;
- TDB_DATA data;
- struct ctdb_node_map *nodemap=NULL;
int i, ret;
if (argc < 2) {
@@ -442,12 +473,6 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
}
- ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
- if (ret != 0) {
- DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
- return ret;
- }
-
if (sscanf(argv[1], "%u", &pnn) != 1) {
DEBUG(DEBUG_ERR, ("Badly formed pnn\n"));
return -1;
@@ -496,47 +521,128 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
return -1;
}
- /* send a moveip message to the recovery master */
- pip.pnn = pnn;
- pip.sin.sin_family = AF_INET;
- pip.sin.sin_addr = ips->ips[i].sin.sin_addr;
- data.dsize = sizeof(pip);
- data.dptr = (unsigned char *)&pip;
+ ret = control_send_release(ctdb, pnn, &ips->ips[i].sin);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));;
+ return -1;
+ }
+ return 0;
+}
- /* send release ip to all nodes */
- if (ctdb_client_async_control(ctdb, CTDB_CONTROL_RELEASE_IP,
- list_of_active_nodes(ctdb, nodemap, ctdb, true),
- TIMELIMIT(), false, data) != 0) {
- DEBUG(DEBUG_ERR, (__location__ " Unable to send 'ReleaseIP' to all nodes.\n"));
- return -1;
+struct node_ip {
+ uint32_t pnn;
+ struct sockaddr_in sin;
+};
+
+void getips_store_callback(void *param, void *data)
+{
+ struct node_ip *node_ip = (struct node_ip *)data;
+ struct ctdb_all_public_ips *ips = param;
+ int i;
+
+ i = ips->num++;
+ ips->ips[i].pnn = node_ip->pnn;
+ ips->ips[i].sin = node_ip->sin;
+}
+
+void getips_count_callback(void *param, void *data)
+{
+ uint32_t *count = param;
+
+ (*count)++;
+}
+
+static int
+control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
+{
+ struct ctdb_all_public_ips *tmp_ips;
+ struct ctdb_node_map *nodemap=NULL;
+ trbt_tree_t *tree;
+ int i, j, len, ret;
+ uint32_t count;
+
+ ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
+ return ret;
+ }
+
+ tree = trbt_create(tmp_ctx, 0);
+
+ for(i=0;i<nodemap->num;i++){
+ if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
+ continue;
+ }
+
+ /* read the public ip list from this node */
+ ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
+ return -1;
+ }
+
+ for (j=0; j<tmp_ips->num;j++) {
+ struct node_ip *node_ip;
+
+ node_ip = talloc(tmp_ctx, struct node_ip);
+ node_ip->pnn = tmp_ips->ips[j].pnn;
+ node_ip->sin = tmp_ips->ips[j].sin;
+
+ trbt_insert32(tree, tmp_ips->ips[j].sin.sin_addr.s_addr, node_ip);
+ }
+ talloc_free(tmp_ips);
}
+ /* traverse */
+ count = 0;
+ trbt_traversearray32(tree, 1, getips_count_callback, &count);
+
+ len = offsetof(struct ctdb_all_public_ips, ips) +
+ count*sizeof(struct ctdb_public_ip);
+ tmp_ips = talloc_zero_size(tmp_ctx, len);
+ trbt_traversearray32(tree, 1, getips_store_callback, tmp_ips);
+
+ *ips = tmp_ips;
+
return 0;
}
+
/*
add a public ip address to a node
*/
static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
{
- int ret;
+ int i, ret;
int len;
unsigned mask;
struct sockaddr_in addr;
struct ctdb_control_ip_iface *pub;
+ TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+ struct ctdb_all_public_ips *ips;
if (argc != 2) {
+ talloc_free(tmp_ctx);
usage();
}
if (!parse_ip_mask(argv[0], &addr, &mask)) {
DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
+ talloc_free(tmp_ctx);
return -1;
}
+ ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+
len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
- pub = talloc_size(ctdb, len);
+ pub = talloc_size(tmp_ctx, len);
CTDB_NO_MEMORY(ctdb, pub);
pub->sin = addr;
@@ -547,9 +653,32 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
if (ret != 0) {
DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
+ talloc_free(tmp_ctx);
return ret;
}
+
+ /* check if some other node is already serving this ip, if not,
+ * we will claim it
+ */
+ for (i=0;i<ips->num;i++) {
+ if (ctdb_same_ip(&addr, &ips->ips[i].sin)) {
+ break;
+ }
+ }
+ /* no one has this ip so we claim it */
+ if (i == ips->num) {
+ ret = control_send_release(ctdb, options.pnn, &addr);
+ } else {
+ ret = control_send_release(ctdb, ips->ips[i].pnn, &addr);
+ }
+
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));
+ return -1;
+ }
+
+ talloc_free(tmp_ctx);
return 0;
}
@@ -786,84 +915,6 @@ static int tickle_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
}
-struct node_ip {
- uint32_t pnn;
- struct sockaddr_in sin;
-};
-
-void getips_store_callback(void *param, void *data)
-{
- struct node_ip *node_ip = (struct node_ip *)data;
- struct ctdb_all_public_ips *ips = param;
- int i;
-
- i = ips->num++;
- ips->ips[i].pnn = node_ip->pnn;
- ips->ips[i].sin = node_ip->sin;
-}
-
-void getips_count_callback(void *param, void *data)
-{
- uint32_t *count = param;
-
- (*count)++;
-}
-
-static int
-control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struct ctdb_all_public_ips **ips)
-{
- struct ctdb_all_public_ips *tmp_ips;
- struct ctdb_node_map *nodemap=NULL;
- trbt_tree_t *tree;
- int i, j, len, ret;
- uint32_t count;
-
- ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap);
- if (ret != 0) {
- DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn));
- return ret;
- }
-
- tree = trbt_create(tmp_ctx, 0);
-
- for(i=0;i<nodemap->num;i++){
- if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
- continue;
- }
-
- /* read the public ip list from this node */
- ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &tmp_ips);
- if (ret != 0) {
- DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn));
- return -1;
- }
-
- for (j=0; j<tmp_ips->num;j++) {
- struct node_ip *node_ip;
-
- node_ip = talloc(tmp_ctx, struct node_ip);
- node_ip->pnn = tmp_ips->ips[j].pnn;
- node_ip->sin = tmp_ips->ips[j].sin;
-
- trbt_insert32(tree, tmp_ips->ips[j].sin.sin_addr.s_addr, node_ip);
- }
- talloc_free(tmp_ips);
- }
-
- /* traverse */
- count = 0;
- trbt_traversearray32(tree, 1, getips_count_callback, &count);
-
- len = offsetof(struct ctdb_all_public_ips, ips) +
- count*sizeof(struct ctdb_public_ip);
- tmp_ips = talloc_zero_size(tmp_ctx, len);
- trbt_traversearray32(tree, 1, getips_store_callback, tmp_ips);
-
- *ips = tmp_ips;
-
- return 0;
-}
-
/*
display public ip status
*/
@@ -1707,7 +1758,7 @@ static const struct {
{ "reloadnodes", control_reload_nodes_file, false, "reload the nodes file and restart the transport on all nodes"},
{ "getreclock", control_getreclock, false, "get the path to the reclock file" },
{ "moveip", control_moveip, false, "move/failover an ip address to another node", "<ip> <node>"},
- { "addip", control_addip, false, "add a ip address to a node", "<ip/mask> <iface>"},
+ { "addip", control_addip, true, "add a ip address to a node", "<ip/mask> <iface>"},
{ "delip", control_delip, false, "delete an ip address from a node", "<ip>"},
{ "eventscript", control_eventscript, true, "run the eventscript with the given parameters on a node", "<arguments>"},
};
--
CTDB repository
More information about the samba-cvs
mailing list