[mpich2-commits] r3979 - in mpich2/trunk/src/pm/hydra: . bootstrap/ssh include pm pm/central utils/sock

balaji at mcs.anl.gov balaji at mcs.anl.gov
Mon Mar 9 03:17:35 CDT 2009


Author: balaji
Date: 2009-03-09 03:17:32 -0500 (Mon, 09 Mar 2009)
New Revision: 3979

Added:
   mpich2/trunk/src/pm/hydra/pm/central/proxy.c
   mpich2/trunk/src/pm/hydra/pm/central/proxy.h
   mpich2/trunk/src/pm/hydra/pm/central/proxy_cb.c
   mpich2/trunk/src/pm/hydra/pm/central/proxy_utils.c
Modified:
   mpich2/trunk/src/pm/hydra/Makefile.sm
   mpich2/trunk/src/pm/hydra/bootstrap/ssh/ssh_launch.c
   mpich2/trunk/src/pm/hydra/include/hydra_sock.h
   mpich2/trunk/src/pm/hydra/pm/Makefile.sm
   mpich2/trunk/src/pm/hydra/pm/central/Makefile.sm
   mpich2/trunk/src/pm/hydra/pm/central/central.h
   mpich2/trunk/src/pm/hydra/pm/central/central_launch.c
   mpich2/trunk/src/pm/hydra/utils/sock/sock.c
Log:
Adding the first cut of the proxy. However, the launcher currently bypasses it.

Modified: mpich2/trunk/src/pm/hydra/Makefile.sm
===================================================================
--- mpich2/trunk/src/pm/hydra/Makefile.sm	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/Makefile.sm	2009-03-09 08:17:32 UTC (rev 3979)
@@ -4,10 +4,11 @@
 #     See COPYRIGHT in top-level directory.
 #
 
-SUBDIRS = utils control pm bootstrap demux launcher .
+SUBDIRS = utils control bootstrap demux pm launcher .
 
 all-preamble:
 	@if [ ! -d lib ] ; then mkdir lib ; fi
 
 mpich2-build-install mpich2-build-uninstall install install-alt:
 	cd launcher && ${MAKE} $@
+	cd pm && ${MAKE} $@

Modified: mpich2/trunk/src/pm/hydra/bootstrap/ssh/ssh_launch.c
===================================================================
--- mpich2/trunk/src/pm/hydra/bootstrap/ssh/ssh_launch.c	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/bootstrap/ssh/ssh_launch.c	2009-03-09 08:17:32 UTC (rev 3979)
@@ -35,6 +35,10 @@
         goto fn_fail;
     }
 
+    /* FIXME: Instead of directly reading from the HYD_Handle
+     * structure, the upper layers should be able to pass what exactly
+     * they want launched. Without this functionality, the proxy
+     * cannot use this and will have to perfom its own launch. */
     process_id = 0;
     for (proc_params = handle.proc_params; proc_params; proc_params = proc_params->next) {
         for (partition = proc_params->partition; partition; partition = partition->next) {

Modified: mpich2/trunk/src/pm/hydra/include/hydra_sock.h
===================================================================
--- mpich2/trunk/src/pm/hydra/include/hydra_sock.h	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/include/hydra_sock.h	2009-03-09 08:17:32 UTC (rev 3979)
@@ -19,7 +19,7 @@
 #define size_t unsigned int
 #endif /* size_t */
 
-HYD_Status HYDU_Sock_listen(int *listen_fd, uint16_t low_port, uint16_t high_port, uint16_t * port);
+HYD_Status HYDU_Sock_listen(int *listen_fd, char *port_range, uint16_t * port);
 HYD_Status HYDU_Sock_connect(const char *host, uint16_t port, int *fd);
 HYD_Status HYDU_Sock_accept(int listen_fd, int *fd);
 HYD_Status HYDU_Sock_readline(int fd, char *buf, int maxlen, int *linelen);

Modified: mpich2/trunk/src/pm/hydra/pm/Makefile.sm
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/Makefile.sm	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/pm/Makefile.sm	2009-03-09 08:17:32 UTC (rev 3979)
@@ -6,3 +6,6 @@
 
 SUBDIRS_HYDRA_PM = central
 SUBDIRS = utils @HYDRA_PM@ .
+
+mpich2-build-install mpich2-build-uninstall install install-alt:
+	cd @HYDRA_PM@ && ${MAKE} $@

Modified: mpich2/trunk/src/pm/hydra/pm/central/Makefile.sm
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/central/Makefile.sm	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/pm/central/Makefile.sm	2009-03-09 08:17:32 UTC (rev 3979)
@@ -17,3 +17,19 @@
 	-I${abs_srcdir}/../utils \
 	-I${abs_srcdir}/../../bootstrap/include \
 	-I${abs_srcdir}/../../demux
+
+proxy_SOURCES = proxy.c proxy_utils.c proxy_cb.c
+proxy_LDADD = -L../../lib -lhydra -L../../../util -lmpiexec -L../../../../../lib -lmpich
+proxy_DEPADD = ../../../util/libmpiexec.a
+install_BIN = proxy
+
+# Use the mpich2-build-install target to include mpiexec in the build bin
+# directory (all pm's require these targets)
+mpich2-build-install: install
+mpich2-build-uninstall: uninstall
+
+# We use a dummy dependency to ensure that we always go to the util
+# directory to see if anything needs to be done
+../../../util/libmpiexec.a: dummy
+dummy:
+	cd ../../../util && $(MAKE)

Modified: mpich2/trunk/src/pm/hydra/pm/central/central.h
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/central/central.h	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/pm/central/central.h	2009-03-09 08:17:32 UTC (rev 3979)
@@ -7,6 +7,11 @@
 #ifndef CENTRAL_H_INCLUDED
 #define CENTRAL_H_INCLUDED
 
+/* Currently we only have one command */
+enum HYD_Proxy_cmds {
+    KILLALL_PROCS
+};
+
 extern int HYD_PMCD_Central_listenfd;
 
 HYD_Status HYD_PMCD_Central_cb(int fd, HYD_Event_t events);

Modified: mpich2/trunk/src/pm/hydra/pm/central/central_launch.c
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/central/central_launch.c	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/pm/central/central_launch.c	2009-03-09 08:17:32 UTC (rev 3979)
@@ -58,34 +58,8 @@
     if (!port_range)
         port_range = getenv("MPICH_PORT_RANGE");
 
-    low_port = 0;
-    high_port = 0;
-    if (port_range) {
-        port_str = strtok(port_range, ":");
-        if (port_str == NULL) {
-            HYDU_Error_printf("error parsing port range string\n");
-            status = HYD_INTERNAL_ERROR;
-            goto fn_fail;
-        }
-        low_port = atoi(port_str);
-
-        port_str = strtok(NULL, ":");
-        if (port_str == NULL) {
-            HYDU_Error_printf("error parsing port range string\n");
-            status = HYD_INTERNAL_ERROR;
-            goto fn_fail;
-        }
-        high_port = atoi(port_str);
-
-        if (high_port < low_port) {
-            HYDU_Error_printf("high port is smaller than low port\n");
-            status = HYD_INTERNAL_ERROR;
-            goto fn_fail;
-        }
-    }
-
     /* Listen on a port in the port range */
-    status = HYDU_Sock_listen(&HYD_PMCD_Central_listenfd, low_port, high_port, &port);
+    status = HYDU_Sock_listen(&HYD_PMCD_Central_listenfd, port_range, &port);
     if (status != HYD_SUCCESS) {
         HYDU_Error_printf("sock utils returned listen error\n");
         goto fn_fail;

Added: mpich2/trunk/src/pm/hydra/pm/central/proxy.c
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/central/proxy.c	                        (rev 0)
+++ mpich2/trunk/src/pm/hydra/pm/central/proxy.c	2009-03-09 08:17:32 UTC (rev 3979)
@@ -0,0 +1,103 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2008 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include "hydra.h"
+#include "hydra_mem.h"
+#include "hydra_sock.h"
+#include "demux.h"
+#include "proxy.h"
+
+struct HYD_Proxy_params HYD_Proxy_params;
+int HYD_Proxy_listenfd;
+
+int main(int argc, char **argv)
+{
+    int i, high_port, low_port, port;
+    int HYD_Proxy_listenfd;
+    char *port_range, *port_str;
+    HYD_Status status = HYD_SUCCESS;
+
+    status = HYD_Proxy_get_params(argc, argv);
+    if (status != HYD_SUCCESS) {
+        HYDU_Error_printf("Bad parameters passed to the proxy\n");
+        goto fn_fail;
+    }
+
+    /* Check if the user wants us to use a port within a certain
+     * range. */
+    port_range = getenv("MPIEXEC_PORTRANGE");
+    if (!port_range)
+        port_range = getenv("MPIEXEC_PORT_RANGE");
+    if (!port_range)
+        port_range = getenv("MPICH_PORT_RANGE");
+
+    /* Listen on a port in the port range */
+    status = HYDU_Sock_listen(&HYD_Proxy_listenfd, port_range, &port);
+    if (status != HYD_SUCCESS) {
+        HYDU_Error_printf("sock utils returned listen error\n");
+        goto fn_fail;
+    }
+
+    /* Register the listening socket with the demux engine */
+    status = HYD_DMX_Register_fd(1, &HYD_Proxy_listenfd, HYD_STDOUT, HYD_Proxy_listen_cb);
+    if (status != HYD_SUCCESS) {
+        HYDU_Error_printf("demux engine returned error for registering fd\n");
+        goto fn_fail;
+    }
+
+    /* FIXME: We do not use the bootstrap server right now, as the
+     * current implementation of the bootstrap launch directly reads
+     * the executable information from the HYD_Handle structure. Since
+     * we are a different process, we don't share this
+     * structure. Without the bootstrap server, we can only launch
+     * local processes. That is, we can only have a single-level
+     * hierarchy of proxies. */
+
+    HYDU_MALLOC(HYD_Proxy_params.out, int *, HYD_Proxy_params.proc_count * sizeof(int), status);
+    HYDU_MALLOC(HYD_Proxy_params.err, int *, HYD_Proxy_params.proc_count * sizeof(int), status);
+
+    /* Spawn the processes */
+    for (i = 0; i < HYD_Proxy_params.proc_count; i++) {
+        if ((i & HYD_Proxy_params.pmi_id) == 0) {
+            status = HYDU_Create_process(HYD_Proxy_params.args, &HYD_Proxy_params.in,
+                                         &HYD_Proxy_params.out[i], &HYD_Proxy_params.err[i],
+                                         &HYD_Proxy_params.pid[i]);
+        }
+        else {
+            status = HYDU_Create_process(HYD_Proxy_params.args, NULL,
+                                         &HYD_Proxy_params.out[i], &HYD_Proxy_params.err[i],
+                                         &HYD_Proxy_params.pid[i]);
+        }
+        if (status != HYD_SUCCESS) {
+            HYDU_Error_printf("spawn process returned error\n");
+            goto fn_fail;
+        }
+    }
+
+    /* Everything is spawned, now wait for I/O */
+    status = HYD_DMX_Register_fd(HYD_Proxy_params.proc_count, HYD_Proxy_params.out,
+                                 HYD_STDOUT, HYD_Proxy_stdout_cb);
+    if (status != HYD_SUCCESS) {
+        HYDU_Error_printf("demux engine returned error when registering fd\n");
+        goto fn_fail;
+    }
+    status = HYD_DMX_Register_fd(HYD_Proxy_params.proc_count, HYD_Proxy_params.err,
+                                 HYD_STDOUT, HYD_Proxy_stderr_cb);
+    if (status != HYD_SUCCESS) {
+        HYDU_Error_printf("demux engine returned error when registering fd\n");
+        goto fn_fail;
+    }
+
+    /* FIXME: Handle stdin */
+    HYD_Proxy_params.stdin_buf_offset = 0;
+    HYD_Proxy_params.stdin_buf_count = 0;
+
+  fn_exit:
+    return status;
+
+  fn_fail:
+    goto fn_exit;
+}

Added: mpich2/trunk/src/pm/hydra/pm/central/proxy.h
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/central/proxy.h	                        (rev 0)
+++ mpich2/trunk/src/pm/hydra/pm/central/proxy.h	2009-03-09 08:17:32 UTC (rev 3979)
@@ -0,0 +1,38 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2008 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#ifndef PROXY_H_INCLUDED
+#define PROXY_H_INCLUDED
+
+#include "hydra.h"
+
+struct HYD_Proxy_params {
+    HYD_Env_t *global_env;
+    int proc_count;
+    int pmi_id;
+    char *args[HYD_EXEC_ARGS];
+    struct HYD_Partition_list *partition;
+
+    int * pid;
+    int * out;
+    int * err;
+    int in;
+
+    int stdin_buf_offset;
+    int stdin_buf_count;
+    char stdin_tmp_buf[HYD_TMPBUF_SIZE];
+};
+
+extern struct HYD_Proxy_params HYD_Proxy_params;
+extern int HYD_Proxy_listenfd;
+
+HYD_Status HYD_Proxy_get_params(int t_argc, char ** t_argv);
+HYD_Status HYD_Proxy_listen_cb(int fd, HYD_Event_t events);
+HYD_Status HYD_Proxy_stdout_cb(int fd, HYD_Event_t events);
+HYD_Status HYD_Proxy_stderr_cb(int fd, HYD_Event_t events);
+HYD_Status HYD_Proxy_stdin_cb(int fd, HYD_Event_t events);
+
+#endif /* PROXY_H_INCLUDED */

Added: mpich2/trunk/src/pm/hydra/pm/central/proxy_cb.c
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/central/proxy_cb.c	                        (rev 0)
+++ mpich2/trunk/src/pm/hydra/pm/central/proxy_cb.c	2009-03-09 08:17:32 UTC (rev 3979)
@@ -0,0 +1,234 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2008 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include "hydra.h"
+#include "hydra_sig.h"
+#include "proxy.h"
+#include "central.h"
+
+struct HYD_Proxy_params HYD_Proxy_params;
+int HYD_Proxy_listenfd;
+
+/* FIXME: A lot of this content is copied from the mpiexec
+ * callback. This needs to be moved to utility functions instead. */
+
+HYD_Status HYD_Proxy_listen_cb(int fd, HYD_Event_t events)
+{
+    int accept_fd, count, i;
+    enum HYD_Proxy_cmds cmd;
+    HYD_Status status = HYD_SUCCESS;
+
+    HYDU_FUNC_ENTER();
+
+    if (events & HYD_STDIN) {
+        HYDU_Error_printf("stdout handler got an stdin event: %d\n", events);
+        status = HYD_INTERNAL_ERROR;
+        goto fn_fail;
+    }
+
+    if (fd == HYD_Proxy_listenfd) { /* mpiexec is trying to connect */
+        status = HYDU_Sock_accept(fd, &accept_fd);
+        if (status != HYD_SUCCESS) {
+            HYDU_Error_printf("sock utils returned error when accepting connection\n");
+            goto fn_fail;
+        }
+
+        status = HYD_DMX_Register_fd(1, &accept_fd, HYD_STDOUT, HYD_Proxy_listen_cb);
+        if (status != HYD_SUCCESS) {
+            HYDU_Error_printf("demux engine returned error when registering fd\n");
+            goto fn_fail;
+        }
+    }
+    else { /* We got a command from mpiexec */
+        count = read(fd, &cmd, HYD_TMPBUF_SIZE);
+        if (count < 0) {
+            HYDU_Error_printf("socket read error on fd: %d (errno: %d)\n", fd, errno);
+            status = HYD_SOCK_ERROR;
+            goto fn_fail;
+        }
+        else if (count == 0) {
+            /* The connection has closed */
+            status = HYD_DMX_Deregister_fd(fd);
+            if (status != HYD_SUCCESS) {
+                HYDU_Error_printf("demux engine returned error when deregistering fd\n");
+                goto fn_fail;
+            }
+            goto fn_exit;
+        }
+
+        if (cmd == KILLALL_PROCS) { /* Got the killall command */
+            for (i = 0; i < HYD_Proxy_params.proc_count; i++)
+                kill(HYD_Proxy_params.pid[i], SIGKILL);
+        }
+        else {
+            HYDU_Error_printf("got unrecognized command from mpiexec\n");
+            status = HYD_INTERNAL_ERROR;
+            goto fn_fail;
+        }
+    }
+
+  fn_exit:
+    HYDU_FUNC_EXIT();
+    return status;
+
+  fn_fail:
+    goto fn_exit;
+}
+
+
+HYD_Status HYD_Proxy_stdout_cb(int fd, HYD_Event_t events)
+{
+    int count;
+    char buf[HYD_TMPBUF_SIZE];
+    HYD_Status status = HYD_SUCCESS;
+
+    HYDU_FUNC_ENTER();
+
+    if (events & HYD_STDIN) {
+        HYDU_Error_printf("stdout handler got an stdin event: %d\n", events);
+        status = HYD_INTERNAL_ERROR;
+        goto fn_fail;
+    }
+
+    count = read(fd, buf, HYD_TMPBUF_SIZE);
+    if (count < 0) {
+        HYDU_Error_printf("socket read error on fd: %d (errno: %d)\n", fd, errno);
+        status = HYD_SOCK_ERROR;
+        goto fn_fail;
+    }
+    else if (count == 0) {
+        /* The connection has closed */
+        status = HYD_DMX_Deregister_fd(fd);
+        if (status != HYD_SUCCESS) {
+            HYDU_Error_printf("demux engine returned error when deregistering fd\n");
+            goto fn_fail;
+        }
+        goto fn_exit;
+    }
+
+    count = write(1, buf, count);
+    if (count < 0) {
+        HYDU_Error_printf("socket write error on fd: %d (errno: %d)\n", fd, errno);
+        status = HYD_SOCK_ERROR;
+        goto fn_fail;
+    }
+
+  fn_exit:
+    HYDU_FUNC_EXIT();
+    return status;
+
+  fn_fail:
+    goto fn_exit;
+}
+
+
+HYD_Status HYD_Proxy_stderr_cb(int fd, HYD_Event_t events)
+{
+    int count;
+    char buf[HYD_TMPBUF_SIZE];
+    HYD_Status status = HYD_SUCCESS;
+
+    HYDU_FUNC_ENTER();
+
+    if (events & HYD_STDIN) {
+        HYDU_Error_printf("stderr handler got an stdin event: %d\n", events);
+        status = HYD_INTERNAL_ERROR;
+        goto fn_fail;
+    }
+
+    count = read(fd, buf, HYD_TMPBUF_SIZE);
+    if (count < 0) {
+        HYDU_Error_printf("socket read error on fd: %d (errno: %d)\n", fd, errno);
+        status = HYD_SOCK_ERROR;
+        goto fn_fail;
+    }
+    else if (count == 0) {
+        /* The connection has closed */
+        status = HYD_DMX_Deregister_fd(fd);
+        if (status != HYD_SUCCESS) {
+            HYDU_Error_printf("demux engine returned error when deregistering fd\n");
+            goto fn_fail;
+        }
+        goto fn_exit;
+    }
+
+    count = write(2, buf, count);
+    if (count < 0) {
+        HYDU_Error_printf("socket write error on fd: %d (errno: %d)\n", fd, errno);
+        status = HYD_SOCK_ERROR;
+        goto fn_fail;
+    }
+
+  fn_exit:
+    HYDU_FUNC_EXIT();
+    return status;
+
+  fn_fail:
+    goto fn_exit;
+}
+
+
+HYD_Status HYD_Proxy_stdin_cb(int fd, HYD_Event_t events)
+{
+    int count;
+    HYD_Status status = HYD_SUCCESS;
+
+    HYDU_FUNC_ENTER();
+
+    if (events & HYD_STDIN) {
+        HYDU_Error_printf("stdin handler got a writeable event on local stdin: %d\n", events);
+        status = HYD_INTERNAL_ERROR;
+        goto fn_fail;
+    }
+
+    while (1) {
+        /* If we already have buffered data, send it out */
+        if (HYD_Proxy_params.stdin_buf_count) {
+            count = write(HYD_Proxy_params.in, HYD_Proxy_params.stdin_tmp_buf +
+                          HYD_Proxy_params.stdin_buf_offset, HYD_Proxy_params.stdin_buf_count);
+            if (count < 0) {
+                /* We can't get an EAGAIN as we just got out of poll */
+                HYDU_Error_printf("socket write error on fd: %d (errno: %d)\n",
+                                  HYD_Proxy_params.in, errno);
+                status = HYD_SOCK_ERROR;
+                goto fn_fail;
+            }
+            HYD_Proxy_params.stdin_buf_offset += count;
+            HYD_Proxy_params.stdin_buf_count -= count;
+            break;
+        }
+
+        /* If we are still here, we need to refill our temporary buffer */
+        count = read(0, HYD_Proxy_params.stdin_tmp_buf, HYD_TMPBUF_SIZE);
+        if (count < 0) {
+            if (errno == EINTR || errno == EAGAIN) {
+                /* This call was interrupted or there was no data to read; just break out. */
+                break;
+            }
+
+            HYDU_Error_printf("socket read error on fd: %d (errno: %d)\n", fd, errno);
+            status = HYD_SOCK_ERROR;
+            goto fn_fail;
+        }
+        else if (count == 0) {
+            /* The connection has closed */
+            status = HYD_DMX_Deregister_fd(fd);
+            if (status != HYD_SUCCESS) {
+                HYDU_Error_printf("demux engine returned error when deregistering fd\n");
+                goto fn_fail;
+            }
+            break;
+        }
+        HYD_Proxy_params.stdin_buf_count += count;
+    }
+
+  fn_exit:
+    HYDU_FUNC_EXIT();
+    return status;
+
+  fn_fail:
+    goto fn_exit;
+}

Added: mpich2/trunk/src/pm/hydra/pm/central/proxy_utils.c
===================================================================
--- mpich2/trunk/src/pm/hydra/pm/central/proxy_utils.c	                        (rev 0)
+++ mpich2/trunk/src/pm/hydra/pm/central/proxy_utils.c	2009-03-09 08:17:32 UTC (rev 3979)
@@ -0,0 +1,81 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2008 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+
+#include "hydra.h"
+#include "proxy.h"
+
+struct HYD_Proxy_params HYD_Proxy_params;
+
+HYD_Status HYD_Proxy_get_params(int t_argc, char **t_argv)
+{
+    int argc = t_argc;
+    char **argv = t_argv;
+    int app_params = 0, arg;
+    struct HYD_Partition_list *partition, *run;
+    HYD_Status status = HYD_SUCCESS;
+
+    HYDU_FUNC_ENTER();
+
+    HYD_Proxy_params.global_env = NULL;
+    HYD_Proxy_params.partition = NULL;
+
+    status = HYDU_Env_global_list(&HYD_Proxy_params.global_env);
+    if (status != HYD_SUCCESS) {
+        HYDU_Error_printf("unable to get the global env list\n");
+        goto fn_fail;
+    }
+
+    app_params = 0;
+    while (--argc && ++argv) {
+
+        /* Process count */
+        if (!strcmp(*argv, "--proc-count")) {
+            argv++;
+            HYD_Proxy_params.proc_count = atoi(*argv);
+            continue;
+        }
+
+        /* PMI_ID: This is the PMI_ID for the first process;
+         * everything else is incremented from here. */
+        if (!strcmp(*argv, "--pmi-id")) {
+            argv++;
+            HYD_Proxy_params.pmi_id = atoi(*argv);
+            continue;
+        }
+
+        /* Partition information is passed as two parameters; name
+         * followed by proc count. Multiple partitions are specified
+         * as multiple parameters. */
+        if (!strcmp(*argv, "--partition")) {
+            argv++;
+            HYDU_Allocate_Partition(&partition);
+            partition->name = MPIU_Strdup(*argv);
+            argv++;
+            partition->proc_count = atoi(*argv);
+
+            if (!HYD_Proxy_params.partition)
+                HYD_Proxy_params.partition = partition;
+            else {
+                for (run = HYD_Proxy_params.partition; run->next; run = run->next);
+                run->next = partition;
+            }
+            continue;
+        }
+
+        /* Fall through case is application parameters. Load
+         * everything into the args variable. */
+        for (arg = 0; argv;)
+            HYD_Proxy_params.args[arg++] = MPIU_Strdup(argv++);
+        HYD_Proxy_params.args[arg++] = NULL;
+    }
+
+  fn_exit:
+    HYDU_FUNC_EXIT();
+    return status;
+
+  fn_fail:
+    goto fn_exit;
+}

Modified: mpich2/trunk/src/pm/hydra/utils/sock/sock.c
===================================================================
--- mpich2/trunk/src/pm/hydra/utils/sock/sock.c	2009-03-09 06:26:52 UTC (rev 3978)
+++ mpich2/trunk/src/pm/hydra/utils/sock/sock.c	2009-03-09 08:17:32 UTC (rev 3979)
@@ -7,15 +7,43 @@
 #include "hydra_sock.h"
 #include "hydra_dbg.h"
 
-HYD_Status HYDU_Sock_listen(int *listen_fd, uint16_t low_port, uint16_t high_port, uint16_t * port)
+HYD_Status HYDU_Sock_listen(int *listen_fd, char *port_range, uint16_t * port)
 {
     struct sockaddr_in sa;
     int one = 1;
+    uint16_t low_port, high_port;
+    char *port_str;
     uint16_t i;
     HYD_Status status = HYD_SUCCESS;
 
     HYDU_FUNC_ENTER();
 
+    low_port = 0;
+    high_port = 0;
+    if (port_range) {
+        port_str = strtok(port_range, ":");
+        if (port_str == NULL) {
+            HYDU_Error_printf("error parsing port range string\n");
+            status = HYD_INTERNAL_ERROR;
+            goto fn_fail;
+        }
+        low_port = atoi(port_str);
+
+        port_str = strtok(NULL, ":");
+        if (port_str == NULL) {
+            HYDU_Error_printf("error parsing port range string\n");
+            status = HYD_INTERNAL_ERROR;
+            goto fn_fail;
+        }
+        high_port = atoi(port_str);
+
+        if (high_port < low_port) {
+            HYDU_Error_printf("high port is smaller than low port\n");
+            status = HYD_INTERNAL_ERROR;
+            goto fn_fail;
+        }
+    }
+
     *listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (*listen_fd < 0) {
         HYDU_Error_printf("unable to create a stream socket (errno: %d)\n", errno);



More information about the mpich2-commits mailing list