summaryrefslogtreecommitdiff
path: root/src/testbed/gnunet_testbed_mpi_spawn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testbed/gnunet_testbed_mpi_spawn.c')
-rw-r--r--src/testbed/gnunet_testbed_mpi_spawn.c293
1 files changed, 147 insertions, 146 deletions
diff --git a/src/testbed/gnunet_testbed_mpi_spawn.c b/src/testbed/gnunet_testbed_mpi_spawn.c
index d69812cd2..b79c431c4 100644
--- a/src/testbed/gnunet_testbed_mpi_spawn.c
+++ b/src/testbed/gnunet_testbed_mpi_spawn.c
@@ -6,14 +6,14 @@
6/** 6/**
7 * Generic logging shorthand 7 * Generic logging shorthand
8 */ 8 */
9#define LOG(kind,...) \ 9#define LOG(kind, ...) \
10 GNUNET_log (kind, __VA_ARGS__) 10 GNUNET_log(kind, __VA_ARGS__)
11 11
12/** 12/**
13 * Debug logging shorthand 13 * Debug logging shorthand
14 */ 14 */
15#define LOG_DEBUG(...) \ 15#define LOG_DEBUG(...) \
16 LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) 16 LOG(GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
17 17
18/** 18/**
19 * Global result 19 * Global result
@@ -69,53 +69,54 @@ static struct GNUNET_SCHEDULER_Task * child_death_task_id;
69 * The shutdown task 69 * The shutdown task
70 */ 70 */
71static void 71static void
72shutdown_task (void *cls) 72shutdown_task(void *cls)
73{ 73{
74 if (0 != child_exit_code) 74 if (0 != child_exit_code)
75 { 75 {
76 LOG (GNUNET_ERROR_TYPE_WARNING, "Child exited with error code: %lu\n", 76 LOG(GNUNET_ERROR_TYPE_WARNING, "Child exited with error code: %lu\n",
77 child_exit_code); 77 child_exit_code);
78 ret = 128 + (int) child_exit_code; 78 ret = 128 + (int)child_exit_code;
79 } 79 }
80 if (0 != fh) 80 if (0 != fh)
81 { 81 {
82 close (fh); 82 close(fh);
83 } 83 }
84 if ((NULL != fn) && (0 != unlink (fn))) 84 if ((NULL != fn) && (0 != unlink(fn)))
85 { 85 {
86 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "open"); 86 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "open");
87 ret = GNUNET_SYSERR; 87 ret = GNUNET_SYSERR;
88 } 88 }
89} 89}
90 90
91 91
92static void 92static void
93terminate_task (void *cls) 93terminate_task(void *cls)
94{ 94{
95 static int hard_kill; 95 static int hard_kill;
96 96
97 GNUNET_assert (NULL != child); 97 GNUNET_assert(NULL != child);
98 terminate_task_id = 98 terminate_task_id =
99 GNUNET_SCHEDULER_add_shutdown (&terminate_task, NULL); 99 GNUNET_SCHEDULER_add_shutdown(&terminate_task, NULL);
100 if (0 != hard_kill) 100 if (0 != hard_kill)
101 {
102 switch (hard_kill)
103 { 101 {
104 case 1: 102 switch (hard_kill)
105 case 2: 103 {
106 LOG (GNUNET_ERROR_TYPE_WARNING, 104 case 1:
107 "%d more interrupts needed to send SIGKILL to the child\n", 105 case 2:
108 3 - hard_kill); 106 LOG(GNUNET_ERROR_TYPE_WARNING,
109 hard_kill++; 107 "%d more interrupts needed to send SIGKILL to the child\n",
110 return; 108 3 - hard_kill);
111 case 3: 109 hard_kill++;
112 GNUNET_break (0 == GNUNET_OS_process_kill (child, SIGKILL)); 110 return;
113 return; 111
112 case 3:
113 GNUNET_break(0 == GNUNET_OS_process_kill(child, SIGKILL));
114 return;
115 }
114 } 116 }
115 }
116 hard_kill++; 117 hard_kill++;
117 GNUNET_break (0 == GNUNET_OS_process_kill (child, GNUNET_TERM_SIG)); 118 GNUNET_break(0 == GNUNET_OS_process_kill(child, GNUNET_TERM_SIG));
118 LOG (GNUNET_ERROR_TYPE_INFO, _("Waiting for child to exit.\n")); 119 LOG(GNUNET_ERROR_TYPE_INFO, _("Waiting for child to exit.\n"));
119} 120}
120 121
121 122
@@ -126,33 +127,33 @@ terminate_task (void *cls)
126 * @param cls closure, NULL if we need to self-restart 127 * @param cls closure, NULL if we need to self-restart
127 */ 128 */
128static void 129static void
129child_death_task (void *cls) 130child_death_task(void *cls)
130{ 131{
131 const struct GNUNET_DISK_FileHandle *pr; 132 const struct GNUNET_DISK_FileHandle *pr;
132 char c[16]; 133 char c[16];
133 const struct GNUNET_SCHEDULER_TaskContext *tc; 134 const struct GNUNET_SCHEDULER_TaskContext *tc;
134 135
135 136
136 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); 137 pr = GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ);
137 child_death_task_id = NULL; 138 child_death_task_id = NULL;
138 tc = GNUNET_SCHEDULER_get_task_context (); 139 tc = GNUNET_SCHEDULER_get_task_context();
139 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) 140 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
140 { 141 {
141 child_death_task_id = 142 child_death_task_id =
142 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 143 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL,
143 pr, &child_death_task, NULL); 144 pr, &child_death_task, NULL);
144 return; 145 return;
145 } 146 }
146 /* consume the signal */ 147 /* consume the signal */
147 GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c))); 148 GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c)));
148 LOG_DEBUG ("Child died\n"); 149 LOG_DEBUG("Child died\n");
149 GNUNET_SCHEDULER_cancel (terminate_task_id); 150 GNUNET_SCHEDULER_cancel(terminate_task_id);
150 terminate_task_id = NULL; 151 terminate_task_id = NULL;
151 GNUNET_assert (GNUNET_OK == GNUNET_OS_process_status (child, &child_status, 152 GNUNET_assert(GNUNET_OK == GNUNET_OS_process_status(child, &child_status,
152 &child_exit_code)); 153 &child_exit_code));
153 GNUNET_OS_process_destroy (child); 154 GNUNET_OS_process_destroy(child);
154 child = NULL; 155 child = NULL;
155 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); 156 GNUNET_SCHEDULER_add_now(&shutdown_task, NULL);
156} 157}
157 158
158 159
@@ -161,11 +162,11 @@ destroy_hosts(struct GNUNET_TESTBED_Host **hosts, unsigned int nhosts)
161{ 162{
162 unsigned int host; 163 unsigned int host;
163 164
164 GNUNET_assert (NULL != hosts); 165 GNUNET_assert(NULL != hosts);
165 for (host = 0; host < nhosts; host++) 166 for (host = 0; host < nhosts; host++)
166 if (NULL != hosts[host]) 167 if (NULL != hosts[host])
167 GNUNET_TESTBED_host_destroy (hosts[host]); 168 GNUNET_TESTBED_host_destroy(hosts[host]);
168 GNUNET_free (hosts); 169 GNUNET_free(hosts);
169 hosts = NULL; 170 hosts = NULL;
170} 171}
171 172
@@ -176,7 +177,7 @@ destroy_hosts(struct GNUNET_TESTBED_Host **hosts, unsigned int nhosts)
176 * @param cls NULL 177 * @param cls NULL
177 */ 178 */
178static void 179static void
179run (void *cls) 180run(void *cls)
180{ 181{
181 struct GNUNET_TESTBED_Host **hosts; 182 struct GNUNET_TESTBED_Host **hosts;
182 const struct GNUNET_CONFIGURATION_Handle *null_cfg; 183 const struct GNUNET_CONFIGURATION_Handle *null_cfg;
@@ -185,78 +186,78 @@ run (void *cls)
185 size_t hostname_len; 186 size_t hostname_len;
186 unsigned int nhosts; 187 unsigned int nhosts;
187 188
188 null_cfg = GNUNET_CONFIGURATION_create (); 189 null_cfg = GNUNET_CONFIGURATION_create();
189 nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler (null_cfg, &hosts); 190 nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler(null_cfg, &hosts);
190 if (0 == nhosts) 191 if (0 == nhosts)
191 { 192 {
192 GNUNET_break (0); 193 GNUNET_break(0);
193 ret = GNUNET_SYSERR; 194 ret = GNUNET_SYSERR;
194 return; 195 return;
195 } 196 }
196 hostname_len = GNUNET_OS_get_hostname_max_length (); 197 hostname_len = GNUNET_OS_get_hostname_max_length();
197 hostname = GNUNET_malloc (hostname_len); 198 hostname = GNUNET_malloc(hostname_len);
198 if (0 != gethostname (hostname, hostname_len)) 199 if (0 != gethostname(hostname, hostname_len))
199 { 200 {
200 LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot get hostname. Exiting\n"); 201 LOG(GNUNET_ERROR_TYPE_ERROR, "Cannot get hostname. Exiting\n");
201 GNUNET_free (hostname); 202 GNUNET_free(hostname);
202 destroy_hosts (hosts, nhosts); 203 destroy_hosts(hosts, nhosts);
203 ret = GNUNET_SYSERR; 204 ret = GNUNET_SYSERR;
204 return; 205 return;
205 } 206 }
206 if (NULL == strstr (GNUNET_TESTBED_host_get_hostname (hosts[0]), hostname)) 207 if (NULL == strstr(GNUNET_TESTBED_host_get_hostname(hosts[0]), hostname))
207 { 208 {
208 LOG_DEBUG ("Exiting as `%s' is not the lowest host\n", hostname); 209 LOG_DEBUG("Exiting as `%s' is not the lowest host\n", hostname);
209 GNUNET_free (hostname); 210 GNUNET_free(hostname);
210 ret = GNUNET_OK; 211 ret = GNUNET_OK;
211 return; 212 return;
212 } 213 }
213 LOG_DEBUG ("Will be executing `%s' on host `%s'\n", argv2[0], hostname); 214 LOG_DEBUG("Will be executing `%s' on host `%s'\n", argv2[0], hostname);
214 GNUNET_free (hostname); 215 GNUNET_free(hostname);
215 destroy_hosts (hosts, nhosts); 216 destroy_hosts(hosts, nhosts);
216 tmpdir = getenv ("TMPDIR"); 217 tmpdir = getenv("TMPDIR");
217 if (NULL == tmpdir) 218 if (NULL == tmpdir)
218 tmpdir = getenv ("TMP"); 219 tmpdir = getenv("TMP");
219 if (NULL == tmpdir) 220 if (NULL == tmpdir)
220 tmpdir = getenv ("TEMP"); 221 tmpdir = getenv("TEMP");
221 if (NULL == tmpdir) 222 if (NULL == tmpdir)
222 tmpdir = "/tmp"; 223 tmpdir = "/tmp";
223 (void) GNUNET_asprintf (&fn, "%s/gnunet-testbed-spawn.lock", tmpdir); 224 (void)GNUNET_asprintf(&fn, "%s/gnunet-testbed-spawn.lock", tmpdir);
224 /* Open the unique file; we can create it then we can spawn the child process 225 /* Open the unique file; we can create it then we can spawn the child process
225 else we exit */ 226 else we exit */
226 fh = open (fn, O_CREAT | O_EXCL | O_CLOEXEC, 227 fh = open(fn, O_CREAT | O_EXCL | O_CLOEXEC,
227 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); 228 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
228 if (-1 == fh) 229 if (-1 == fh)
229 {
230 if (EEXIST == errno)
231 { 230 {
232 LOG_DEBUG ("Lock file already created by other process. Exiting\n"); 231 if (EEXIST == errno)
233 ret = GNUNET_OK; 232 {
233 LOG_DEBUG("Lock file already created by other process. Exiting\n");
234 ret = GNUNET_OK;
235 return;
236 }
237 GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "open");
238 ret = GNUNET_SYSERR;
234 return; 239 return;
235 } 240 }
236 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "open");
237 ret = GNUNET_SYSERR;
238 return;
239 }
240 /* Spawn the new process here */ 241 /* Spawn the new process here */
241 LOG (GNUNET_ERROR_TYPE_INFO, _("Spawning process `%s'\n"), argv2[0]); 242 LOG(GNUNET_ERROR_TYPE_INFO, _("Spawning process `%s'\n"), argv2[0]);
242 child = GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, 243 child = GNUNET_OS_start_process_vap(GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL,
243 NULL, NULL, 244 NULL, NULL,
244 argv2[0], argv2); 245 argv2[0], argv2);
245 if (NULL == child) 246 if (NULL == child)
246 { 247 {
247 GNUNET_break (0); 248 GNUNET_break(0);
248 ret = GNUNET_SYSERR; 249 ret = GNUNET_SYSERR;
249 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); 250 GNUNET_SCHEDULER_add_now(&shutdown_task, NULL);
250 return; 251 return;
251 } 252 }
252 ret = GNUNET_OK; 253 ret = GNUNET_OK;
253 terminate_task_id = 254 terminate_task_id =
254 GNUNET_SCHEDULER_add_shutdown (&terminate_task, NULL); 255 GNUNET_SCHEDULER_add_shutdown(&terminate_task, NULL);
255 child_death_task_id = 256 child_death_task_id =
256 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 257 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL,
257 GNUNET_DISK_pipe_handle (sigpipe, 258 GNUNET_DISK_pipe_handle(sigpipe,
258 GNUNET_DISK_PIPE_END_READ), 259 GNUNET_DISK_PIPE_END_READ),
259 &child_death_task, NULL); 260 &child_death_task, NULL);
260} 261}
261 262
262 263
@@ -264,16 +265,16 @@ run (void *cls)
264 * Signal handler called for SIGCHLD. 265 * Signal handler called for SIGCHLD.
265 */ 266 */
266static void 267static void
267sighandler_child_death () 268sighandler_child_death()
268{ 269{
269 static char c; 270 static char c;
270 int old_errno = errno; /* back-up errno */ 271 int old_errno = errno; /* back-up errno */
271 272
272 GNUNET_break (1 == 273 GNUNET_break(1 ==
273 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle 274 GNUNET_DISK_file_write(GNUNET_DISK_pipe_handle
274 (sigpipe, GNUNET_DISK_PIPE_END_WRITE), 275 (sigpipe, GNUNET_DISK_PIPE_END_WRITE),
275 &c, sizeof (c))); 276 &c, sizeof(c)));
276 errno = old_errno; /* restore errno */ 277 errno = old_errno; /* restore errno */
277} 278}
278 279
279 280
@@ -281,45 +282,45 @@ sighandler_child_death ()
281 * Execution start point 282 * Execution start point
282 */ 283 */
283int 284int
284main (int argc, char *argv[]) 285main(int argc, char *argv[])
285{ 286{
286 struct GNUNET_SIGNAL_Context *shc_chld; 287 struct GNUNET_SIGNAL_Context *shc_chld;
287 unsigned int cnt; 288 unsigned int cnt;
288 289
289 ret = -1; 290 ret = -1;
290 if (argc < 2) 291 if (argc < 2)
291 { 292 {
292 printf ("Need arguments: gnunet-testbed-mpi-spawn <cmd> <cmd_args>"); 293 printf("Need arguments: gnunet-testbed-mpi-spawn <cmd> <cmd_args>");
293 return 1; 294 return 1;
294 } 295 }
295 if (GNUNET_OK != GNUNET_log_setup ("gnunet-testbed-spawn", NULL, NULL)) 296 if (GNUNET_OK != GNUNET_log_setup("gnunet-testbed-spawn", NULL, NULL))
296 { 297 {
297 GNUNET_break (0); 298 GNUNET_break(0);
298 return 1; 299 return 1;
299 } 300 }
300 if (NULL == (sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 301 if (NULL == (sigpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO,
301 GNUNET_NO, GNUNET_NO))) 302 GNUNET_NO, GNUNET_NO)))
302 { 303 {
303 GNUNET_break (0); 304 GNUNET_break(0);
304 ret = GNUNET_SYSERR; 305 ret = GNUNET_SYSERR;
305 return 1; 306 return 1;
306 } 307 }
307 shc_chld = 308 shc_chld =
308 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); 309 GNUNET_SIGNAL_handler_install(GNUNET_SIGCHLD, &sighandler_child_death);
309 if (NULL == shc_chld) 310 if (NULL == shc_chld)
310 { 311 {
311 LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot install a signal handler\n"); 312 LOG(GNUNET_ERROR_TYPE_ERROR, "Cannot install a signal handler\n");
312 return 1; 313 return 1;
313 } 314 }
314 argv2 = GNUNET_malloc (sizeof (char *) * argc); 315 argv2 = GNUNET_malloc(sizeof(char *) * argc);
315 for (cnt = 1; cnt < argc; cnt++) 316 for (cnt = 1; cnt < argc; cnt++)
316 argv2[cnt - 1] = argv[cnt]; 317 argv2[cnt - 1] = argv[cnt];
317 GNUNET_SCHEDULER_run (run, NULL); 318 GNUNET_SCHEDULER_run(run, NULL);
318 GNUNET_free (argv2); 319 GNUNET_free(argv2);
319 GNUNET_SIGNAL_handler_uninstall (shc_chld); 320 GNUNET_SIGNAL_handler_uninstall(shc_chld);
320 shc_chld = NULL; 321 shc_chld = NULL;
321 GNUNET_DISK_pipe_close (sigpipe); 322 GNUNET_DISK_pipe_close(sigpipe);
322 GNUNET_free_non_null (fn); 323 GNUNET_free_non_null(fn);
323 if (GNUNET_OK != ret) 324 if (GNUNET_OK != ret)
324 return ret; 325 return ret;
325 return 0; 326 return 0;