aboutsummaryrefslogtreecommitdiff
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.c295
1 files changed, 148 insertions, 147 deletions
diff --git a/src/testbed/gnunet_testbed_mpi_spawn.c b/src/testbed/gnunet_testbed_mpi_spawn.c
index b79c431c4..8b67523a1 100644
--- a/src/testbed/gnunet_testbed_mpi_spawn.c
+++ b/src/testbed/gnunet_testbed_mpi_spawn.c
@@ -7,13 +7,13 @@
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
@@ -58,65 +58,65 @@ static enum GNUNET_OS_ProcessStatusType child_status;
58/** 58/**
59 * Task to kill the child 59 * Task to kill the child
60 */ 60 */
61static struct GNUNET_SCHEDULER_Task * terminate_task_id; 61static struct GNUNET_SCHEDULER_Task *terminate_task_id;
62 62
63/** 63/**
64 * Task to kill the child 64 * Task to kill the child
65 */ 65 */
66static struct GNUNET_SCHEDULER_Task * child_death_task_id; 66static struct GNUNET_SCHEDULER_Task *child_death_task_id;
67 67
68/** 68/**
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)
101 { 103 {
102 switch (hard_kill) 104 case 1:
103 { 105 case 2:
104 case 1: 106 LOG (GNUNET_ERROR_TYPE_WARNING,
105 case 2: 107 "%d more interrupts needed to send SIGKILL to the child\n",
106 LOG(GNUNET_ERROR_TYPE_WARNING, 108 3 - hard_kill);
107 "%d more interrupts needed to send SIGKILL to the child\n", 109 hard_kill++;
108 3 - hard_kill); 110 return;
109 hard_kill++; 111
110 return; 112 case 3:
111 113 GNUNET_break (0 == GNUNET_OS_process_kill (child, SIGKILL));
112 case 3: 114 return;
113 GNUNET_break(0 == GNUNET_OS_process_kill(child, SIGKILL));
114 return;
115 }
116 } 115 }
116 }
117 hard_kill++; 117 hard_kill++;
118 GNUNET_break(0 == GNUNET_OS_process_kill(child, GNUNET_TERM_SIG)); 118 GNUNET_break (0 == GNUNET_OS_process_kill (child, GNUNET_TERM_SIG));
119 LOG(GNUNET_ERROR_TYPE_INFO, _("Waiting for child to exit.\n")); 119 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Waiting for child to exit.\n"));
120} 120}
121 121
122 122
@@ -127,46 +127,46 @@ terminate_task(void *cls)
127 * @param cls closure, NULL if we need to self-restart 127 * @param cls closure, NULL if we need to self-restart
128 */ 128 */
129static void 129static void
130child_death_task(void *cls) 130child_death_task (void *cls)
131{ 131{
132 const struct GNUNET_DISK_FileHandle *pr; 132 const struct GNUNET_DISK_FileHandle *pr;
133 char c[16]; 133 char c[16];
134 const struct GNUNET_SCHEDULER_TaskContext *tc; 134 const struct GNUNET_SCHEDULER_TaskContext *tc;
135 135
136 136
137 pr = GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ); 137 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
138 child_death_task_id = NULL; 138 child_death_task_id = NULL;
139 tc = GNUNET_SCHEDULER_get_task_context(); 139 tc = GNUNET_SCHEDULER_get_task_context ();
140 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) 140 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY))
141 { 141 {
142 child_death_task_id = 142 child_death_task_id =
143 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 143 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
144 pr, &child_death_task, NULL); 144 pr, &child_death_task, NULL);
145 return; 145 return;
146 } 146 }
147 /* consume the signal */ 147 /* consume the signal */
148 GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c))); 148 GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c)));
149 LOG_DEBUG("Child died\n"); 149 LOG_DEBUG ("Child died\n");
150 GNUNET_SCHEDULER_cancel(terminate_task_id); 150 GNUNET_SCHEDULER_cancel (terminate_task_id);
151 terminate_task_id = NULL; 151 terminate_task_id = NULL;
152 GNUNET_assert(GNUNET_OK == GNUNET_OS_process_status(child, &child_status, 152 GNUNET_assert (GNUNET_OK == GNUNET_OS_process_status (child, &child_status,
153 &child_exit_code)); 153 &child_exit_code));
154 GNUNET_OS_process_destroy(child); 154 GNUNET_OS_process_destroy (child);
155 child = NULL; 155 child = NULL;
156 GNUNET_SCHEDULER_add_now(&shutdown_task, NULL); 156 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
157} 157}
158 158
159 159
160static void 160static void
161destroy_hosts(struct GNUNET_TESTBED_Host **hosts, unsigned int nhosts) 161destroy_hosts (struct GNUNET_TESTBED_Host **hosts, unsigned int nhosts)
162{ 162{
163 unsigned int host; 163 unsigned int host;
164 164
165 GNUNET_assert(NULL != hosts); 165 GNUNET_assert (NULL != hosts);
166 for (host = 0; host < nhosts; host++) 166 for (host = 0; host < nhosts; host++)
167 if (NULL != hosts[host]) 167 if (NULL != hosts[host])
168 GNUNET_TESTBED_host_destroy(hosts[host]); 168 GNUNET_TESTBED_host_destroy (hosts[host]);
169 GNUNET_free(hosts); 169 GNUNET_free (hosts);
170 hosts = NULL; 170 hosts = NULL;
171} 171}
172 172
@@ -177,7 +177,7 @@ destroy_hosts(struct GNUNET_TESTBED_Host **hosts, unsigned int nhosts)
177 * @param cls NULL 177 * @param cls NULL
178 */ 178 */
179static void 179static void
180run(void *cls) 180run (void *cls)
181{ 181{
182 struct GNUNET_TESTBED_Host **hosts; 182 struct GNUNET_TESTBED_Host **hosts;
183 const struct GNUNET_CONFIGURATION_Handle *null_cfg; 183 const struct GNUNET_CONFIGURATION_Handle *null_cfg;
@@ -186,78 +186,79 @@ run(void *cls)
186 size_t hostname_len; 186 size_t hostname_len;
187 unsigned int nhosts; 187 unsigned int nhosts;
188 188
189 null_cfg = GNUNET_CONFIGURATION_create(); 189 null_cfg = GNUNET_CONFIGURATION_create ();
190 nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler(null_cfg, &hosts); 190 nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler (null_cfg, &hosts);
191 if (0 == nhosts) 191 if (0 == nhosts)
192 { 192 {
193 GNUNET_break(0); 193 GNUNET_break (0);
194 ret = GNUNET_SYSERR; 194 ret = GNUNET_SYSERR;
195 return; 195 return;
196 } 196 }
197 hostname_len = GNUNET_OS_get_hostname_max_length(); 197 hostname_len = GNUNET_OS_get_hostname_max_length ();
198 hostname = GNUNET_malloc(hostname_len); 198 hostname = GNUNET_malloc (hostname_len);
199 if (0 != gethostname(hostname, hostname_len)) 199 if (0 != gethostname (hostname, hostname_len))
200 { 200 {
201 LOG(GNUNET_ERROR_TYPE_ERROR, "Cannot get hostname. Exiting\n"); 201 LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot get hostname. Exiting\n");
202 GNUNET_free(hostname); 202 GNUNET_free (hostname);
203 destroy_hosts(hosts, nhosts); 203 destroy_hosts (hosts, nhosts);
204 ret = GNUNET_SYSERR; 204 ret = GNUNET_SYSERR;
205 return; 205 return;
206 } 206 }
207 if (NULL == strstr(GNUNET_TESTBED_host_get_hostname(hosts[0]), hostname)) 207 if (NULL == strstr (GNUNET_TESTBED_host_get_hostname (hosts[0]), hostname))
208 { 208 {
209 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);
210 GNUNET_free(hostname); 210 GNUNET_free (hostname);
211 ret = GNUNET_OK; 211 ret = GNUNET_OK;
212 return; 212 return;
213 } 213 }
214 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);
215 GNUNET_free(hostname); 215 GNUNET_free (hostname);
216 destroy_hosts(hosts, nhosts); 216 destroy_hosts (hosts, nhosts);
217 tmpdir = getenv("TMPDIR"); 217 tmpdir = getenv ("TMPDIR");
218 if (NULL == tmpdir) 218 if (NULL == tmpdir)
219 tmpdir = getenv("TMP"); 219 tmpdir = getenv ("TMP");
220 if (NULL == tmpdir) 220 if (NULL == tmpdir)
221 tmpdir = getenv("TEMP"); 221 tmpdir = getenv ("TEMP");
222 if (NULL == tmpdir) 222 if (NULL == tmpdir)
223 tmpdir = "/tmp"; 223 tmpdir = "/tmp";
224 (void)GNUNET_asprintf(&fn, "%s/gnunet-testbed-spawn.lock", tmpdir); 224 (void) GNUNET_asprintf (&fn, "%s/gnunet-testbed-spawn.lock", tmpdir);
225 /* 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
226 else we exit */ 226 else we exit */
227 fh = open(fn, O_CREAT | O_EXCL | O_CLOEXEC, 227 fh = open (fn, O_CREAT | O_EXCL | O_CLOEXEC,
228 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); 228 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
229 if (-1 == fh) 229 if (-1 == fh)
230 {
231 if (EEXIST == errno)
230 { 232 {
231 if (EEXIST == errno) 233 LOG_DEBUG ("Lock file already created by other process. Exiting\n");
232 { 234 ret = GNUNET_OK;
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;
239 return; 235 return;
240 } 236 }
237 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "open");
238 ret = GNUNET_SYSERR;
239 return;
240 }
241 /* Spawn the new process here */ 241 /* Spawn the new process here */
242 LOG(GNUNET_ERROR_TYPE_INFO, _("Spawning process `%s'\n"), argv2[0]); 242 LOG (GNUNET_ERROR_TYPE_INFO, _ ("Spawning process `%s'\n"), argv2[0]);
243 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,
244 NULL, NULL, 244 NULL,
245 argv2[0], argv2); 245 NULL, NULL,
246 argv2[0], argv2);
246 if (NULL == child) 247 if (NULL == child)
247 { 248 {
248 GNUNET_break(0); 249 GNUNET_break (0);
249 ret = GNUNET_SYSERR; 250 ret = GNUNET_SYSERR;
250 GNUNET_SCHEDULER_add_now(&shutdown_task, NULL); 251 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
251 return; 252 return;
252 } 253 }
253 ret = GNUNET_OK; 254 ret = GNUNET_OK;
254 terminate_task_id = 255 terminate_task_id =
255 GNUNET_SCHEDULER_add_shutdown(&terminate_task, NULL); 256 GNUNET_SCHEDULER_add_shutdown (&terminate_task, NULL);
256 child_death_task_id = 257 child_death_task_id =
257 GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, 258 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
258 GNUNET_DISK_pipe_handle(sigpipe, 259 GNUNET_DISK_pipe_handle (sigpipe,
259 GNUNET_DISK_PIPE_END_READ), 260 GNUNET_DISK_PIPE_END_READ),
260 &child_death_task, NULL); 261 &child_death_task, NULL);
261} 262}
262 263
263 264
@@ -265,15 +266,15 @@ run(void *cls)
265 * Signal handler called for SIGCHLD. 266 * Signal handler called for SIGCHLD.
266 */ 267 */
267static void 268static void
268sighandler_child_death() 269sighandler_child_death ()
269{ 270{
270 static char c; 271 static char c;
271 int old_errno = errno; /* back-up errno */ 272 int old_errno = errno; /* back-up errno */
272 273
273 GNUNET_break(1 == 274 GNUNET_break (1 ==
274 GNUNET_DISK_file_write(GNUNET_DISK_pipe_handle 275 GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
275 (sigpipe, GNUNET_DISK_PIPE_END_WRITE), 276 (sigpipe, GNUNET_DISK_PIPE_END_WRITE),
276 &c, sizeof(c))); 277 &c, sizeof(c)));
277 errno = old_errno; /* restore errno */ 278 errno = old_errno; /* restore errno */
278} 279}
279 280
@@ -282,45 +283,45 @@ sighandler_child_death()
282 * Execution start point 283 * Execution start point
283 */ 284 */
284int 285int
285main(int argc, char *argv[]) 286main (int argc, char *argv[])
286{ 287{
287 struct GNUNET_SIGNAL_Context *shc_chld; 288 struct GNUNET_SIGNAL_Context *shc_chld;
288 unsigned int cnt; 289 unsigned int cnt;
289 290
290 ret = -1; 291 ret = -1;
291 if (argc < 2) 292 if (argc < 2)
292 { 293 {
293 printf("Need arguments: gnunet-testbed-mpi-spawn <cmd> <cmd_args>"); 294 printf ("Need arguments: gnunet-testbed-mpi-spawn <cmd> <cmd_args>");
294 return 1; 295 return 1;
295 } 296 }
296 if (GNUNET_OK != GNUNET_log_setup("gnunet-testbed-spawn", NULL, NULL)) 297 if (GNUNET_OK != GNUNET_log_setup ("gnunet-testbed-spawn", NULL, NULL))
297 { 298 {
298 GNUNET_break(0); 299 GNUNET_break (0);
299 return 1; 300 return 1;
300 } 301 }
301 if (NULL == (sigpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, 302 if (NULL == (sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO,
302 GNUNET_NO, GNUNET_NO))) 303 GNUNET_NO, GNUNET_NO)))
303 { 304 {
304 GNUNET_break(0); 305 GNUNET_break (0);
305 ret = GNUNET_SYSERR; 306 ret = GNUNET_SYSERR;
306 return 1; 307 return 1;
307 } 308 }
308 shc_chld = 309 shc_chld =
309 GNUNET_SIGNAL_handler_install(GNUNET_SIGCHLD, &sighandler_child_death); 310 GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
310 if (NULL == shc_chld) 311 if (NULL == shc_chld)
311 { 312 {
312 LOG(GNUNET_ERROR_TYPE_ERROR, "Cannot install a signal handler\n"); 313 LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot install a signal handler\n");
313 return 1; 314 return 1;
314 } 315 }
315 argv2 = GNUNET_malloc(sizeof(char *) * argc); 316 argv2 = GNUNET_malloc (sizeof(char *) * argc);
316 for (cnt = 1; cnt < argc; cnt++) 317 for (cnt = 1; cnt < argc; cnt++)
317 argv2[cnt - 1] = argv[cnt]; 318 argv2[cnt - 1] = argv[cnt];
318 GNUNET_SCHEDULER_run(run, NULL); 319 GNUNET_SCHEDULER_run (run, NULL);
319 GNUNET_free(argv2); 320 GNUNET_free (argv2);
320 GNUNET_SIGNAL_handler_uninstall(shc_chld); 321 GNUNET_SIGNAL_handler_uninstall (shc_chld);
321 shc_chld = NULL; 322 shc_chld = NULL;
322 GNUNET_DISK_pipe_close(sigpipe); 323 GNUNET_DISK_pipe_close (sigpipe);
323 GNUNET_free_non_null(fn); 324 GNUNET_free_non_null (fn);
324 if (GNUNET_OK != ret) 325 if (GNUNET_OK != ret)
325 return ret; 326 return ret;
326 return 0; 327 return 0;