Add a --node-ip argument so that one can specify which ip address a
authorRonnie Sahlberg <sahlberg@ronnie>
Sun, 25 Nov 2007 23:52:55 +0000 (10:52 +1100)
committerRonnie Sahlberg <sahlberg@ronnie>
Sun, 25 Nov 2007 23:52:55 +0000 (10:52 +1100)
specific instance of ctdbd should bind to. This helps when running a
"virtual" cluster on a single machine where all instcances bind to
different alias interfaces.

If --node-ip is specified, then we will only try to bind to this ip
address only. Othervise we fall back to the original method trying the
ip addresses in /etc/ctdb/nodes one by one until we find one we can bind
to.

No variable in /etc/sysconfig/ctdb added since this parameter only makes
sense in a virtual test/debug cluster.

(This used to be ctdb commit d96cb02c2c24f9eabbc53d3d38e90dea49cff3e0)

ctdb/include/ctdb.h
ctdb/include/ctdb_private.h
ctdb/server/ctdb_server.c
ctdb/server/ctdbd.c
ctdb/tcp/tcp_connect.c

index b3a65a36ab2a8227862c75085ee19b9c47c52775..a2245d220b850088cf539ed42bcd3dd55fc38072 100644 (file)
@@ -159,6 +159,12 @@ int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname);
 */
 int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist);
 
+/*
+  Check that a specific ip address exists in the node list and returns
+  the id for the node or -1
+*/
+int ctdb_ip_to_nodeid(struct ctdb_context *ctdb, const char *nodeip);
+
 /*
   start the ctdb protocol
 */
index cb76bb0074cb68a6a69dbf98e931859b0ebe5d6a..10abafa1d93b99f59c890f50843d92df1655940a 100644 (file)
@@ -367,6 +367,7 @@ struct ctdb_context {
        const char *default_public_interface;
        pid_t recoverd_pid;
        bool done_startup;
+       const char *node_ip;
 };
 
 struct ctdb_db_context {
index dddf90753bd7bce15f3e46b38929783afb8052a1..2a80798dd93e6c058cd4be99e6e34f270254a0e6 100644 (file)
@@ -34,6 +34,23 @@ int ctdb_set_transport(struct ctdb_context *ctdb, const char *transport)
        return 0;
 }
 
+/*
+  Check whether an ip is a valid node ip
+  Returns the node id for this ip address or -1
+*/
+int ctdb_ip_to_nodeid(struct ctdb_context *ctdb, const char *nodeip)
+{
+       int nodeid;
+
+       for (nodeid=0;nodeid<ctdb->num_nodes;nodeid++) {
+               if (!strcmp(ctdb->nodes[nodeid]->address.address, nodeip)) {
+                       return nodeid;
+               }
+       }
+
+       return -1;
+}
+
 /*
   choose the recovery lock file
 */
index eaf79a0ed7d45b39fbbd43143d54143b0d81174d..ba0eac42fb8a7a53164d8ef6cd0672d82511e77f 100644 (file)
@@ -50,6 +50,7 @@ static struct {
        const char *db_dir_persistent;
        const char *public_interface;
        const char *single_public_ip;
+       const char *node_ip;
        int         no_setsched;
 } options = {
        .nlist = ETCDIR "/ctdb/nodes",
@@ -110,6 +111,7 @@ int main(int argc, const char *argv[])
                { "event-script-dir", 0, POPT_ARG_STRING, &options.event_script_dir, 0, "event script directory", "dirname" },
                { "logfile", 0, POPT_ARG_STRING, &options.logfile, 0, "log file location", "filename" },
                { "nlist", 0, POPT_ARG_STRING, &options.nlist, 0, "node list file", "filename" },
+               { "node-ip", 0, POPT_ARG_STRING, &options.node_ip, 0, "node ip", "ip-address"},
                { "listen", 0, POPT_ARG_STRING, &options.myaddress, 0, "address to listen on", "address" },
                { "transport", 0, POPT_ARG_STRING, &options.transport, 0, "protocol transport", NULL },
                { "dbdir", 0, POPT_ARG_STRING, &options.db_dir, 0, "directory for the tdb files", NULL },
@@ -198,6 +200,20 @@ int main(int argc, const char *argv[])
                exit(1);
        }
 
+       /* if a node-ip was specified, verify that it exists in the
+          nodes file
+       */
+       if (options.node_ip != NULL) {
+               DEBUG(0,("IP for this node is %s\n", options.node_ip));
+               ret = ctdb_ip_to_nodeid(ctdb, options.node_ip);
+               if (ret == -1) {
+                       DEBUG(0,("The specified node-ip:%s is not a valid node address. Exiting.\n", options.node_ip));
+                       exit(1);
+               }
+               ctdb->node_ip = options.node_ip;
+               DEBUG(0,("This is node %d\n", ret));
+       }
+
        if (options.db_dir) {
                ret = ctdb_set_tdb_dir(ctdb, options.db_dir);
                if (ret == -1) {
index 3548f82ed705b66ebe6c2be22dd1251e439013c9..3c4e7bfb10dc5a1bfac4617f237f099dab49b750 100644 (file)
@@ -214,13 +214,9 @@ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde,
        if (fd == -1) return;
 
        incoming_node = inet_ntoa(addr.sin_addr);
-       for (nodeid=0;nodeid<ctdb->num_nodes;nodeid++) {
-               if (!strcmp(incoming_node, ctdb->nodes[nodeid]->address.address)) {
-                       DEBUG(0, ("Incoming connection from node:%d %s\n",nodeid,incoming_node));
-                       break;
-               }
-       }
-       if (nodeid>=ctdb->num_nodes) {
+       nodeid = ctdb_ip_to_nodeid(ctdb, incoming_node);
+
+       if (nodeid == -1) {
                DEBUG(0, ("Refused connection from unknown node %s\n", incoming_node));
                close(fd);
                return;
@@ -275,17 +271,27 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
        }
 
        for (i=0;i<ctdb->num_nodes;i++) {
+               /* if node_ip is specified we will only try to bind to that
+                  ip.
+               */
+               if (ctdb->node_ip != NULL) {
+                       if (strcmp(ctdb->node_ip, ctdb->nodes[i]->address.address)) {
+                               continue;
+                       }
+               }
+
                ZERO_STRUCT(sock);
 #ifdef HAVE_SOCK_SIN_LEN
                sock.sin_len = sizeof(sock);
 #endif
                sock.sin_port = htons(ctdb->nodes[i]->address.port);
                sock.sin_family = PF_INET;
-               if (ctdb_tcp_get_address(ctdb, ctdb->nodes[i]->address.address, 
-                                        &sock.sin_addr) != 0) {
+               if (ctdb_tcp_get_address(ctdb,
+                               ctdb->nodes[i]->address.address, 
+                               &sock.sin_addr) != 0) {
                        continue;
                }
-               
+       
                if (bind(ctcp->listen_fd, (struct sockaddr * )&sock, 
                         sizeof(sock)) == 0) {
                        break;