bind-specific.patch:
--------------------
This patch adds a new config file option (TCPBindSpecific) that if enabled tells the server to bind only to its specific IP address rather than using INADDR_ANY. This is particularly helpful in failover scenarios where you would like one physical machine to assume two ip addresses (and two servers) to run simultaneously when another server crashes. Without this patch you would need to select a different port on each server to prevent collisions.

-Phil
Index: pvfs2_src/src/server/pvfs2-server.c
===================================================================
--- pvfs2_src/src/server/pvfs2-server.c	(revision 2419)
+++ pvfs2_src/src/server/pvfs2-server.c	(revision 2420)
@@ -976,6 +976,7 @@
     PVFS_fs_id orig_fsid;
     PVFS_ds_flags init_flags = 0;
     int port_num = 0;
+    int bmi_flags = BMI_INIT_SERVER;
 
     /* Initialize distributions */
     ret = PINT_dist_initialize(0);
@@ -999,8 +1000,15 @@
                  "Passing %s as BMI listen address.\n",
                  server_config.host_id);
 
+    /* does the configuration dictate that we bind to a specific address? */
+    if(server_config.tcp_bind_specific)
+    {
+        bmi_flags |= BMI_TCP_BIND_SPECIFIC;
+    }
+
     ret = BMI_initialize(server_config.bmi_modules, 
-                         server_config.host_id, BMI_INIT_SERVER);
+                         server_config.host_id,
+                         bmi_flags);
     if (ret < 0)
     {
         PVFS_perror_gossip("Error: BMI_initialize", ret);
Index: pvfs2_src/src/io/bmi/bmi-types.h
===================================================================
--- pvfs2_src/src/io/bmi/bmi-types.h	(revision 2419)
+++ pvfs2_src/src/io/bmi/bmi-types.h	(revision 2420)
@@ -39,7 +39,8 @@
 /** BMI method initialization flags */
 enum
 {
-    BMI_INIT_SERVER = 1 /**< set up to listen for unexpected messages */
+    BMI_INIT_SERVER = 1, /**< set up to listen for unexpected messages */
+    BMI_TCP_BIND_SPECIFIC = 2 /**< bind to a specific IP address if INIT_SERVER */
 };
 
 enum bmi_op_type
Index: pvfs2_src/src/io/bmi/bmi_tcp/sockio.c
===================================================================
--- pvfs2_src/src/io/bmi/bmi_tcp/sockio.c	(revision 2419)
+++ pvfs2_src/src/io/bmi/bmi_tcp/sockio.c	(revision 2420)
@@ -60,6 +60,27 @@
     return (sockd);
 }
 
+int BMI_sockio_bind_sock_specific(int sockd,
+              const char *name,
+	      int service)
+{
+    struct sockaddr saddr;
+    int ret;
+
+    if ((ret = BMI_sockio_init_sock(&saddr, name, service)) != 0)
+	return (ret); /* converted to PVFS error code below */
+
+  bind_sock_restart:
+    if (bind(sockd, &saddr, sizeof(saddr)) < 0)
+    {
+	if (errno == EINTR)
+	    goto bind_sock_restart;
+	return (-1);
+    }
+    return (sockd);
+}
+
+
 int BMI_sockio_connect_sock(int sockd,
 		 const char *name,
 		 int service)
Index: pvfs2_src/src/io/bmi/bmi_tcp/bmi-tcp.c
===================================================================
--- pvfs2_src/src/io/bmi/bmi_tcp/bmi-tcp.c	(revision 2419)
+++ pvfs2_src/src/io/bmi/bmi_tcp/bmi-tcp.c	(revision 2420)
@@ -1716,6 +1716,7 @@
     int oldfl = 0;		/* old socket flags */
     struct tcp_addr *tcp_addr_data = NULL;
     int tmp_errno = bmi_tcp_errno_to_pvfs(-EINVAL);
+    int ret = 0;
 
     /* create a socket */
     tcp_addr_data = tcp_method_params.listen_addr->method_data;
@@ -1737,8 +1738,20 @@
     BMI_sockio_set_sockopt(tcp_addr_data->socket, SO_REUSEADDR, 1);
 
     /* bind it to the appropriate port */
-    if (BMI_sockio_bind_sock(tcp_addr_data->socket, tcp_addr_data->port) < 0)
+    if(tcp_method_params.method_flags & BMI_TCP_BIND_SPECIFIC)
     {
+        ret = BMI_sockio_bind_sock_specific(tcp_addr_data->socket,
+            tcp_addr_data->hostname,
+            tcp_addr_data->port);
+    }
+    else
+    {
+        ret = BMI_sockio_bind_sock(tcp_addr_data->socket,
+            tcp_addr_data->port);
+    }
+    
+    if (ret < 0)
+    {
 	tmp_errno = errno;
 	gossip_err("Error: BMI_sockio_bind_sock: %s\n", strerror(tmp_errno));
 	return (bmi_tcp_errno_to_pvfs(-tmp_errno));
Index: pvfs2_src/src/io/bmi/bmi_tcp/sockio.h
===================================================================
--- pvfs2_src/src/io/bmi/bmi_tcp/sockio.h	(revision 2419)
+++ pvfs2_src/src/io/bmi/bmi_tcp/sockio.h	(revision 2420)
@@ -32,6 +32,9 @@
 int BMI_sockio_new_sock(void);
 int BMI_sockio_bind_sock(int,
 			 int);
+int BMI_sockio_bind_sock_specific(int sockd,
+              const char *name,
+	      int service);
 int BMI_sockio_connect_sock(int,
 			    const char *,
 			    int);
Index: pvfs2_src/src/common/misc/server-config.c
===================================================================
--- pvfs2_src/src/common/misc/server-config.c	(revision 2419)
+++ pvfs2_src/src/common/misc/server-config.c	(revision 2420)
@@ -52,6 +52,7 @@
 static DOTCONF_CB(get_unexp_req);
 static DOTCONF_CB(get_tcp_buffer_send);
 static DOTCONF_CB(get_tcp_buffer_receive);
+static DOTCONF_CB(get_tcp_bind_specific);
 static DOTCONF_CB(get_perf_update_interval);
 static DOTCONF_CB(get_root_handle);
 static DOTCONF_CB(get_name);
@@ -518,6 +519,12 @@
       {"TCPBufferReceive",ARG_INT, get_tcp_buffer_receive,NULL,
          CTX_DEFAULTS|CTX_GLOBAL,"0"},
 
+     /* If enabled, specifies that the server should bind its port only on
+      * the specified address (rather than INADDR_ANY)
+      */
+     {"TCPBindSpecific",ARG_STR, get_tcp_bind_specific,NULL,
+        CTX_DEFAULTS|CTX_GLOBAL,"no"},
+
      /* Specifies the timeout value in seconds for BMI jobs on the server.
       */
      {"ServerJobBMITimeoutSecs",ARG_INT, get_server_job_bmi_timeout,NULL,
@@ -1175,7 +1182,29 @@
     return NULL;
 }
 
+DOTCONF_CB(get_tcp_bind_specific)
+{
+    struct server_configuration_s *config_s =
+        (struct server_configuration_s *)cmd->context;
 
+    if(strcasecmp(cmd->data.str, "yes") == 0)
+    {
+        config_s->tcp_bind_specific = 1;
+    }
+    else if(strcasecmp(cmd->data.str, "no") == 0)
+    {
+        config_s->tcp_bind_specific = 0;
+    }
+    else
+    {
+        return("TCPBindSpecific value must be 'yes' or 'no'.\n");
+    }
+
+    return NULL;
+}
+
+
+
 DOTCONF_CB(get_server_job_bmi_timeout)
 {
     struct server_configuration_s *config_s = 
Index: pvfs2_src/src/common/misc/server-config.h
===================================================================
--- pvfs2_src/src/common/misc/server-config.h	(revision 2419)
+++ pvfs2_src/src/common/misc/server-config.h	(revision 2420)
@@ -134,6 +134,9 @@
     int tcp_buffer_size_receive;    /* Size of TCP receive buffer, is set
                                        later with setsockopt */
     int tcp_buffer_size_send;       /* Size of TCP send buffer */
+    int tcp_bind_specific;          /* Flag indicates if we should bind to
+                                     * specific server address
+                                     */
 #ifdef USE_TRUSTED
     int           ports_enabled;    /* Should we enable trusted port connections at all? */
     unsigned long allowed_ports[2]; /* {Min, Max} value of ports from which connections will be allowed */
_______________________________________________
Pvfs2-developers mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers

Reply via email to