2ff1972a6037179710687fa9acc1df700bb53c26
[oweals/gnunet.git] / src / testbed / gnunet_testbed_mpi_spawn.c
1 #include "platform.h"
2 #include "gnunet_util_lib.h"
3 #include "gnunet_resolver_service.h"
4 #include "gnunet_testbed_service.h"
5 #include <mpi.h>
6
7 /**
8  * Generic logging shorthand
9  */
10 #define LOG(kind,...)                                           \
11   GNUNET_log_from (kind, "gnunet-mpi-test", __VA_ARGS__)
12
13 /**
14  * Debug logging shorthand
15  */
16 #define LOG_DEBUG(...)                          \
17   LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
18
19 /**
20  * Timeout for resolving IPs
21  */
22 #define RESOLVE_TIMEOUT                         \
23   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
24
25 /**
26  * Global result
27  */
28 static int ret;
29
30 /**
31  * The host list
32  */
33 static struct GNUNET_TESTBED_Host **hosts;
34
35 /**
36  * Number of hosts in the host list
37  */
38 static unsigned int nhosts;
39
40 /**
41  * Main function that will be run by the scheduler.
42  *
43  * @param cls closure
44  * @param args remaining command-line arguments
45  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
46  * @param config configuration
47  */
48 static void
49 run (void *cls, char *const *args, const char *cfgfile,
50      const struct GNUNET_CONFIGURATION_Handle *config)
51 {
52   struct GNUNET_OS_Process *proc;
53   unsigned long code;
54   enum GNUNET_OS_ProcessStatusType proc_status;
55   int rank;
56   unsigned int host;
57   
58   if (MPI_SUCCESS != MPI_Comm_rank (MPI_COMM_WORLD, &rank))
59   {
60     GNUNET_break (0);
61     return;
62   }
63   if (0 != rank)
64   {
65     ret = GNUNET_OK;
66     return;
67   }
68   PRINTF ("Spawning process\n");
69   proc =
70       GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL,
71                                    NULL, args[0], args);
72   if (NULL == proc)
73   {
74     printf ("Cannot exec\n");
75     return;
76   }
77   do
78   {
79     (void) sleep (1);
80     ret = GNUNET_OS_process_status (proc, &proc_status, &code);
81   }
82   while (GNUNET_NO == ret);
83   GNUNET_assert (GNUNET_NO != ret);
84   if (GNUNET_OK == ret)
85   {
86     if (0 != code)
87     {
88       LOG (GNUNET_ERROR_TYPE_WARNING, "Child terminated abnormally\n");
89       ret = GNUNET_SYSERR;
90       GNUNET_break (0);
91       return;
92     }
93   }
94   else
95   {
96     ret = GNUNET_SYSERR;
97     GNUNET_break (0);
98     return;
99   }
100   if (0 == (nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler (config, &hosts)))
101   {
102     GNUNET_break (0);
103     ret = GNUNET_SYSERR;
104     return;
105   }
106   for (host = 0; host < nhosts; host++)
107     GNUNET_TESTBED_host_destroy (hosts[host]);
108   GNUNET_free (hosts);
109   hosts = NULL;
110   ret = GNUNET_OK;
111 }
112
113
114 /**
115  * Execution start point
116  */
117 int
118 main (int argc, char *argv[])
119 {
120   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
121     GNUNET_GETOPT_OPTION_END
122   };
123   unsigned int host;
124   int rres;
125   
126   ret = GNUNET_SYSERR;
127   if (argc < 2)
128   {
129     printf ("Need arguments: gnunet-testbed-mpi-spawn <cmd> <cmd_args>");
130     return 1;
131   }
132   if (MPI_SUCCESS != MPI_Init (&argc, &argv))
133   {
134     GNUNET_break (0);
135     return 1;
136   }
137   rres =
138       GNUNET_PROGRAM_run (argc, argv,
139                           "gnunet-testbed-mpi-spawn <cmd> <cmd_args>",
140                           _("Spawns cmd after starting my the MPI run-time"),
141                           options, &run, NULL);
142   (void) MPI_Finalize ();
143   if ((GNUNET_OK == rres) && (GNUNET_OK == ret))
144     return 0;
145   printf ("Something went wrong\n");
146   return 1;
147 }