diff options
Diffstat (limited to 'src/arm/gnunet-service-arm.c')
-rw-r--r-- | src/arm/gnunet-service-arm.c | 744 |
1 files changed, 353 insertions, 391 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index 05c6fb438..e4a8e7c6c 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -188,7 +188,7 @@ static struct GNUNET_SERVER_Handle *server; | |||
188 | * @param cls closure, NULL if we need to self-restart | 188 | * @param cls closure, NULL if we need to self-restart |
189 | * @param tc context | 189 | * @param tc context |
190 | */ | 190 | */ |
191 | static void | 191 | static void |
192 | config_change_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 192 | config_change_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
193 | { | 193 | { |
194 | struct ServiceList *pos; | 194 | struct ServiceList *pos; |
@@ -196,21 +196,21 @@ config_change_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
196 | 196 | ||
197 | pos = running_head; | 197 | pos = running_head; |
198 | while (pos != NULL) | 198 | while (pos != NULL) |
199 | { | ||
200 | /* FIXME: this test for config change may be a bit too coarse grained */ | ||
201 | if ((0 == STAT (pos->config, &sbuf)) && | ||
202 | (pos->mtime < sbuf.st_mtime) && (pos->proc != NULL)) | ||
199 | { | 203 | { |
200 | /* FIXME: this test for config change may be a bit too coarse grained */ | 204 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
201 | if ( (0 == STAT (pos->config, &sbuf)) && | 205 | _ |
202 | (pos->mtime < sbuf.st_mtime) && | 206 | ("Restarting service `%s' due to configuration file change.\n")); |
203 | (pos->proc != NULL) ) | 207 | if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) |
204 | { | 208 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
205 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 209 | else |
206 | _("Restarting service `%s' due to configuration file change.\n")); | 210 | pos->backoff = GNUNET_TIME_UNIT_MILLISECONDS; |
207 | if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) | ||
208 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
209 | else | ||
210 | pos->backoff = GNUNET_TIME_UNIT_MILLISECONDS; | ||
211 | } | ||
212 | pos = pos->next; | ||
213 | } | 211 | } |
212 | pos = pos->next; | ||
213 | } | ||
214 | } | 214 | } |
215 | 215 | ||
216 | 216 | ||
@@ -229,15 +229,14 @@ write_result (void *cls, size_t size, void *buf) | |||
229 | struct GNUNET_MessageHeader *msg; | 229 | struct GNUNET_MessageHeader *msg; |
230 | 230 | ||
231 | if (buf == NULL) | 231 | if (buf == NULL) |
232 | { | 232 | { |
233 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 233 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
234 | _("Could not send status result to client\n")); | 234 | _("Could not send status result to client\n")); |
235 | return 0; /* error, not much we can do */ | 235 | return 0; /* error, not much we can do */ |
236 | } | 236 | } |
237 | #if DEBUG_ARM | 237 | #if DEBUG_ARM |
238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
239 | "Sending status response %u to client\n", | 239 | "Sending status response %u to client\n", (unsigned int) *res); |
240 | (unsigned int) *res); | ||
241 | #endif | 240 | #endif |
242 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | 241 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); |
243 | msg = buf; | 242 | msg = buf; |
@@ -259,29 +258,27 @@ write_result (void *cls, size_t size, void *buf) | |||
259 | */ | 258 | */ |
260 | static void | 259 | static void |
261 | signal_result (struct GNUNET_SERVER_Client *client, | 260 | signal_result (struct GNUNET_SERVER_Client *client, |
262 | const char *name, uint16_t result) | 261 | const char *name, uint16_t result) |
263 | { | 262 | { |
264 | uint16_t *res; | 263 | uint16_t *res; |
265 | 264 | ||
266 | if (NULL == client) | 265 | if (NULL == client) |
267 | { | 266 | { |
268 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 267 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
269 | _ | 268 | _("Not sending status result to client: no client known\n")); |
270 | ("Not sending status result to client: no client known\n")); | 269 | return; |
271 | return; | 270 | } |
272 | } | ||
273 | #if DEBUG_ARM | 271 | #if DEBUG_ARM |
274 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 272 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
275 | "Telling client that service `%s' is now %s\n", | 273 | "Telling client that service `%s' is now %s\n", |
276 | name, | 274 | name, result == GNUNET_MESSAGE_TYPE_ARM_IS_DOWN ? "down" : "up"); |
277 | result == GNUNET_MESSAGE_TYPE_ARM_IS_DOWN ? "down" : "up"); | ||
278 | #endif | 275 | #endif |
279 | res = GNUNET_malloc (sizeof (uint16_t)); | 276 | res = GNUNET_malloc (sizeof (uint16_t)); |
280 | *res = result; | 277 | *res = result; |
281 | GNUNET_SERVER_notify_transmit_ready (client, | 278 | GNUNET_SERVER_notify_transmit_ready (client, |
282 | sizeof (struct GNUNET_MessageHeader), | 279 | sizeof (struct GNUNET_MessageHeader), |
283 | GNUNET_TIME_UNIT_FOREVER_REL, | 280 | GNUNET_TIME_UNIT_FOREVER_REL, |
284 | &write_result, res); | 281 | &write_result, res); |
285 | } | 282 | } |
286 | 283 | ||
287 | 284 | ||
@@ -299,11 +296,11 @@ find_service (const char *name) | |||
299 | 296 | ||
300 | pos = running_head; | 297 | pos = running_head; |
301 | while (pos != NULL) | 298 | while (pos != NULL) |
302 | { | 299 | { |
303 | if (0 == strcmp (pos->name, name)) | 300 | if (0 == strcmp (pos->name, name)) |
304 | return pos; | 301 | return pos; |
305 | pos = pos->next; | 302 | pos = pos->next; |
306 | } | 303 | } |
307 | return NULL; | 304 | return NULL; |
308 | } | 305 | } |
309 | 306 | ||
@@ -316,9 +313,7 @@ find_service (const char *name) | |||
316 | static void | 313 | static void |
317 | free_service (struct ServiceList *pos) | 314 | free_service (struct ServiceList *pos) |
318 | { | 315 | { |
319 | GNUNET_CONTAINER_DLL_remove (running_head, | 316 | GNUNET_CONTAINER_DLL_remove (running_head, running_tail, pos); |
320 | running_tail, | ||
321 | pos); | ||
322 | GNUNET_free_non_null (pos->config); | 317 | GNUNET_free_non_null (pos->config); |
323 | GNUNET_free_non_null (pos->binary); | 318 | GNUNET_free_non_null (pos->binary); |
324 | GNUNET_free (pos->name); | 319 | GNUNET_free (pos->name); |
@@ -336,8 +331,7 @@ free_service (struct ServiceList *pos) | |||
336 | * @param lsocks -1 terminated list of listen sockets to pass (systemd style), or NULL | 331 | * @param lsocks -1 terminated list of listen sockets to pass (systemd style), or NULL |
337 | */ | 332 | */ |
338 | static void | 333 | static void |
339 | start_process (struct ServiceList *sl, | 334 | start_process (struct ServiceList *sl, const int *lsocks) |
340 | const int *lsocks) | ||
341 | { | 335 | { |
342 | char *loprefix; | 336 | char *loprefix; |
343 | char *options; | 337 | char *options; |
@@ -351,85 +345,70 @@ start_process (struct ServiceList *sl, | |||
351 | /* start service */ | 345 | /* start service */ |
352 | if (GNUNET_OK != | 346 | if (GNUNET_OK != |
353 | GNUNET_CONFIGURATION_get_value_string (cfg, | 347 | GNUNET_CONFIGURATION_get_value_string (cfg, |
354 | sl->name, "PREFIX", &loprefix)) | 348 | sl->name, "PREFIX", &loprefix)) |
355 | loprefix = GNUNET_strdup (prefix_command); | 349 | loprefix = GNUNET_strdup (prefix_command); |
356 | if (GNUNET_OK != | 350 | if (GNUNET_OK != |
357 | GNUNET_CONFIGURATION_get_value_string (cfg, | 351 | GNUNET_CONFIGURATION_get_value_string (cfg, |
358 | sl->name, "OPTIONS", &options)) | 352 | sl->name, "OPTIONS", &options)) |
359 | { | 353 | { |
360 | options = GNUNET_strdup (final_option); | 354 | options = GNUNET_strdup (final_option); |
361 | if (NULL == strstr (options, "%")) | 355 | if (NULL == strstr (options, "%")) |
362 | { | 356 | { |
363 | /* replace '{}' with service name */ | 357 | /* replace '{}' with service name */ |
364 | while (NULL != (optpos = strstr (options, "{}"))) | 358 | while (NULL != (optpos = strstr (options, "{}"))) |
365 | { | 359 | { |
366 | optpos[0] = '%'; | 360 | optpos[0] = '%'; |
367 | optpos[1] = 's'; | 361 | optpos[1] = 's'; |
368 | GNUNET_asprintf (&optpos, | 362 | GNUNET_asprintf (&optpos, options, sl->name); |
369 | options, | 363 | GNUNET_free (options); |
370 | sl->name); | 364 | options = optpos; |
371 | GNUNET_free (options); | 365 | } |
372 | options = optpos; | 366 | /* replace '$PATH' with value associated with "PATH" */ |
373 | } | 367 | while (NULL != (optpos = strstr (options, "$"))) |
374 | /* replace '$PATH' with value associated with "PATH" */ | 368 | { |
375 | while (NULL != (optpos = strstr (options, "$"))) | 369 | optend = optpos + 1; |
376 | { | 370 | while (isupper ((unsigned char) *optend)) |
377 | optend = optpos + 1; | 371 | optend++; |
378 | while (isupper ( (unsigned char) *optend)) optend++; | 372 | b = *optend; |
379 | b = *optend; | 373 | if ('\0' == b) |
380 | if ('\0' == b) | 374 | next = ""; |
381 | next = ""; | 375 | else |
382 | else | 376 | next = optend + 1; |
383 | next = optend+1; | 377 | *optend = '\0'; |
384 | *optend = '\0'; | 378 | if (GNUNET_OK != |
385 | if (GNUNET_OK != | 379 | GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", |
386 | GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", | 380 | optpos + 1, &val)) |
387 | optpos+1, | 381 | val = GNUNET_strdup (""); |
388 | &val)) | 382 | *optpos = '\0'; |
389 | val = GNUNET_strdup (""); | 383 | GNUNET_asprintf (&optpos, "%s%s%c%s", options, val, b, next); |
390 | *optpos = '\0'; | 384 | GNUNET_free (options); |
391 | GNUNET_asprintf (&optpos, | 385 | GNUNET_free (val); |
392 | "%s%s%c%s", | 386 | options = optpos; |
393 | options, | 387 | } |
394 | val, | ||
395 | b, | ||
396 | next); | ||
397 | GNUNET_free (options); | ||
398 | GNUNET_free (val); | ||
399 | options = optpos; | ||
400 | } | ||
401 | } | ||
402 | } | 388 | } |
389 | } | ||
403 | use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG"); | 390 | use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG"); |
404 | 391 | ||
405 | #if DEBUG_ARM | 392 | #if DEBUG_ARM |
406 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 393 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
407 | "Starting service `%s' using binary `%s' and configuration `%s'\n", | 394 | "Starting service `%s' using binary `%s' and configuration `%s'\n", |
408 | sl->name, sl->binary, sl->config); | 395 | sl->name, sl->binary, sl->config); |
409 | #endif | 396 | #endif |
410 | if (GNUNET_YES == use_debug) | 397 | if (GNUNET_YES == use_debug) |
411 | sl->proc = do_start_process (lsocks, | 398 | sl->proc = do_start_process (lsocks, |
412 | loprefix, | 399 | loprefix, |
413 | sl->binary, | 400 | sl->binary, |
414 | "-c", sl->config, | 401 | "-c", sl->config, |
415 | "-L", "DEBUG", | 402 | "-L", "DEBUG", options, NULL); |
416 | options, | ||
417 | NULL); | ||
418 | else | 403 | else |
419 | sl->proc = do_start_process (lsocks, | 404 | sl->proc = do_start_process (lsocks, |
420 | loprefix, | 405 | loprefix, |
421 | sl->binary, | 406 | sl->binary, "-c", sl->config, options, NULL); |
422 | "-c", sl->config, | ||
423 | options, | ||
424 | NULL); | ||
425 | if (sl->proc == NULL) | 407 | if (sl->proc == NULL) |
426 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 408 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
427 | _("Failed to start service `%s'\n"), | 409 | _("Failed to start service `%s'\n"), sl->name); |
428 | sl->name); | ||
429 | else | 410 | else |
430 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 411 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting service `%s'\n"), sl->name); |
431 | _("Starting service `%s'\n"), | ||
432 | sl->name); | ||
433 | GNUNET_free (loprefix); | 412 | GNUNET_free (loprefix); |
434 | GNUNET_free (options); | 413 | GNUNET_free (options); |
435 | } | 414 | } |
@@ -444,9 +423,8 @@ start_process (struct ServiceList *sl, | |||
444 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 423 | * @return GNUNET_OK on success, GNUNET_SYSERR on error |
445 | */ | 424 | */ |
446 | int | 425 | int |
447 | start_service (struct GNUNET_SERVER_Client *client, | 426 | start_service (struct GNUNET_SERVER_Client *client, |
448 | const char *servicename, | 427 | const char *servicename, const int *lsocks) |
449 | const int *lsocks) | ||
450 | { | 428 | { |
451 | struct ServiceList *sl; | 429 | struct ServiceList *sl; |
452 | char *binary; | 430 | char *binary; |
@@ -454,46 +432,46 @@ start_service (struct GNUNET_SERVER_Client *client, | |||
454 | struct stat sbuf; | 432 | struct stat sbuf; |
455 | 433 | ||
456 | if (GNUNET_YES == in_shutdown) | 434 | if (GNUNET_YES == in_shutdown) |
457 | { | 435 | { |
458 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 436 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
459 | _("ARM is shutting down, service `%s' not started.\n"), | 437 | _("ARM is shutting down, service `%s' not started.\n"), |
460 | servicename); | 438 | servicename); |
461 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 439 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
462 | return GNUNET_SYSERR; | 440 | return GNUNET_SYSERR; |
463 | } | 441 | } |
464 | sl = find_service (servicename); | 442 | sl = find_service (servicename); |
465 | if (sl != NULL) | 443 | if (sl != NULL) |
466 | { | 444 | { |
467 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 445 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
468 | _("Service `%s' already running.\n"), servicename); | 446 | _("Service `%s' already running.\n"), servicename); |
469 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); | 447 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); |
470 | return GNUNET_SYSERR; | 448 | return GNUNET_SYSERR; |
471 | } | 449 | } |
472 | if (GNUNET_OK != | 450 | if (GNUNET_OK != |
473 | GNUNET_CONFIGURATION_get_value_string (cfg, | 451 | GNUNET_CONFIGURATION_get_value_string (cfg, |
474 | servicename, "BINARY", &binary)) | 452 | servicename, "BINARY", &binary)) |
475 | { | 453 | { |
476 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 454 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
477 | _("Binary implementing service `%s' not known!\n"), | 455 | _("Binary implementing service `%s' not known!\n"), |
478 | servicename); | 456 | servicename); |
479 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 457 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
480 | return GNUNET_SYSERR; | 458 | return GNUNET_SYSERR; |
481 | } | 459 | } |
482 | if ((GNUNET_OK != | 460 | if ((GNUNET_OK != |
483 | GNUNET_CONFIGURATION_get_value_filename (cfg, | 461 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
484 | servicename, | 462 | servicename, |
485 | "CONFIG", | 463 | "CONFIG", |
486 | &config)) || | 464 | &config)) || |
487 | (0 != STAT (config, &sbuf))) | 465 | (0 != STAT (config, &sbuf))) |
488 | { | 466 | { |
489 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 467 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
490 | _("Configuration file `%s' for service `%s' not known!\n"), | 468 | _("Configuration file `%s' for service `%s' not known!\n"), |
491 | config, servicename); | 469 | config, servicename); |
492 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 470 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
493 | GNUNET_free (binary); | 471 | GNUNET_free (binary); |
494 | GNUNET_free_non_null (config); | 472 | GNUNET_free_non_null (config); |
495 | return GNUNET_SYSERR; | 473 | return GNUNET_SYSERR; |
496 | } | 474 | } |
497 | (void) stop_listening (servicename); | 475 | (void) stop_listening (servicename); |
498 | sl = GNUNET_malloc (sizeof (struct ServiceList)); | 476 | sl = GNUNET_malloc (sizeof (struct ServiceList)); |
499 | sl->name = GNUNET_strdup (servicename); | 477 | sl->name = GNUNET_strdup (servicename); |
@@ -502,9 +480,7 @@ start_service (struct GNUNET_SERVER_Client *client, | |||
502 | sl->mtime = sbuf.st_mtime; | 480 | sl->mtime = sbuf.st_mtime; |
503 | sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; | 481 | sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; |
504 | sl->restartAt = GNUNET_TIME_UNIT_FOREVER_ABS; | 482 | sl->restartAt = GNUNET_TIME_UNIT_FOREVER_ABS; |
505 | GNUNET_CONTAINER_DLL_insert (running_head, | 483 | GNUNET_CONTAINER_DLL_insert (running_head, running_tail, sl); |
506 | running_tail, | ||
507 | sl); | ||
508 | start_process (sl, lsocks); | 484 | start_process (sl, lsocks); |
509 | if (NULL != client) | 485 | if (NULL != client) |
510 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); | 486 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); |
@@ -519,58 +495,57 @@ start_service (struct GNUNET_SERVER_Client *client, | |||
519 | * @param servicename name of the service to stop | 495 | * @param servicename name of the service to stop |
520 | */ | 496 | */ |
521 | static void | 497 | static void |
522 | stop_service (struct GNUNET_SERVER_Client *client, | 498 | stop_service (struct GNUNET_SERVER_Client *client, const char *servicename) |
523 | const char *servicename) | ||
524 | { | 499 | { |
525 | struct ServiceList *pos; | 500 | struct ServiceList *pos; |
526 | 501 | ||
527 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 502 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
528 | _("Preparing to stop `%s'\n"), servicename); | 503 | _("Preparing to stop `%s'\n"), servicename); |
529 | pos = find_service (servicename); | 504 | pos = find_service (servicename); |
530 | if (pos == NULL) | 505 | if (pos == NULL) |
531 | { | 506 | { |
532 | if (GNUNET_OK == stop_listening (servicename)) | 507 | if (GNUNET_OK == stop_listening (servicename)) |
533 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 508 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
534 | else | 509 | else |
535 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UNKNOWN); | 510 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UNKNOWN); |
536 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 511 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
537 | return; | 512 | return; |
538 | } | 513 | } |
539 | if (pos->killing_client != NULL) | 514 | if (pos->killing_client != NULL) |
540 | { | 515 | { |
541 | /* killing already in progress */ | 516 | /* killing already in progress */ |
542 | #if DEBUG_ARM | 517 | #if DEBUG_ARM |
543 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 518 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
544 | "Service `%s' is already down\n", servicename); | 519 | "Service `%s' is already down\n", servicename); |
545 | #endif | 520 | #endif |
546 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 521 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
547 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 522 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
548 | return; | 523 | return; |
549 | } | 524 | } |
550 | 525 | ||
551 | if (GNUNET_YES == in_shutdown) | 526 | if (GNUNET_YES == in_shutdown) |
552 | { | 527 | { |
553 | #if DEBUG_ARM | 528 | #if DEBUG_ARM |
554 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 529 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
555 | "Termination request already sent to `%s' (since ARM is in shutdown).\n", | 530 | "Termination request already sent to `%s' (since ARM is in shutdown).\n", |
556 | servicename); | 531 | servicename); |
557 | #endif | 532 | #endif |
558 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 533 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
559 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 534 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
560 | return; | 535 | return; |
561 | } | 536 | } |
562 | if (pos->proc == NULL) | 537 | if (pos->proc == NULL) |
563 | { | 538 | { |
564 | /* process is in delayed restart, simply remove it! */ | 539 | /* process is in delayed restart, simply remove it! */ |
565 | free_service (pos); | 540 | free_service (pos); |
566 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 541 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
567 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 542 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
568 | return; | 543 | return; |
569 | } | 544 | } |
570 | #if DEBUG_ARM | 545 | #if DEBUG_ARM |
571 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 546 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
572 | "Sending kill signal to service `%s', waiting for process to die.\n", | 547 | "Sending kill signal to service `%s', waiting for process to die.\n", |
573 | servicename); | 548 | servicename); |
574 | #endif | 549 | #endif |
575 | if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) | 550 | if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) |
576 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 551 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
@@ -590,8 +565,8 @@ stop_service (struct GNUNET_SERVER_Client *client, | |||
590 | */ | 565 | */ |
591 | static void | 566 | static void |
592 | handle_start (void *cls, | 567 | handle_start (void *cls, |
593 | struct GNUNET_SERVER_Client *client, | 568 | struct GNUNET_SERVER_Client *client, |
594 | const struct GNUNET_MessageHeader *message) | 569 | const struct GNUNET_MessageHeader *message) |
595 | { | 570 | { |
596 | const char *servicename; | 571 | const char *servicename; |
597 | uint16_t size; | 572 | uint16_t size; |
@@ -600,11 +575,11 @@ handle_start (void *cls, | |||
600 | size -= sizeof (struct GNUNET_MessageHeader); | 575 | size -= sizeof (struct GNUNET_MessageHeader); |
601 | servicename = (const char *) &message[1]; | 576 | servicename = (const char *) &message[1]; |
602 | if ((size == 0) || (servicename[size - 1] != '\0')) | 577 | if ((size == 0) || (servicename[size - 1] != '\0')) |
603 | { | 578 | { |
604 | GNUNET_break (0); | 579 | GNUNET_break (0); |
605 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 580 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
606 | return; | 581 | return; |
607 | } | 582 | } |
608 | start_service (client, servicename, NULL); | 583 | start_service (client, servicename, NULL); |
609 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 584 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
610 | } | 585 | } |
@@ -621,8 +596,8 @@ handle_start (void *cls, | |||
621 | */ | 596 | */ |
622 | static void | 597 | static void |
623 | handle_stop (void *cls, | 598 | handle_stop (void *cls, |
624 | struct GNUNET_SERVER_Client *client, | 599 | struct GNUNET_SERVER_Client *client, |
625 | const struct GNUNET_MessageHeader *message) | 600 | const struct GNUNET_MessageHeader *message) |
626 | { | 601 | { |
627 | const char *servicename; | 602 | const char *servicename; |
628 | uint16_t size; | 603 | uint16_t size; |
@@ -631,11 +606,11 @@ handle_stop (void *cls, | |||
631 | size -= sizeof (struct GNUNET_MessageHeader); | 606 | size -= sizeof (struct GNUNET_MessageHeader); |
632 | servicename = (const char *) &message[1]; | 607 | servicename = (const char *) &message[1]; |
633 | if ((size == 0) || (servicename[size - 1] != '\0')) | 608 | if ((size == 0) || (servicename[size - 1] != '\0')) |
634 | { | 609 | { |
635 | GNUNET_break (0); | 610 | GNUNET_break (0); |
636 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 611 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
637 | return; | 612 | return; |
638 | } | 613 | } |
639 | stop_service (client, servicename); | 614 | stop_service (client, servicename); |
640 | } | 615 | } |
641 | 616 | ||
@@ -650,14 +625,14 @@ clean_up_running () | |||
650 | { | 625 | { |
651 | struct ServiceList *pos; | 626 | struct ServiceList *pos; |
652 | struct ServiceList *next; | 627 | struct ServiceList *next; |
653 | 628 | ||
654 | next = running_head; | 629 | next = running_head; |
655 | while (NULL != (pos = next)) | 630 | while (NULL != (pos = next)) |
656 | { | 631 | { |
657 | next = pos->next; | 632 | next = pos->next; |
658 | if (pos->proc == NULL) | 633 | if (pos->proc == NULL) |
659 | free_service (pos); | 634 | free_service (pos); |
660 | } | 635 | } |
661 | } | 636 | } |
662 | 637 | ||
663 | 638 | ||
@@ -669,15 +644,15 @@ static void | |||
669 | do_shutdown () | 644 | do_shutdown () |
670 | { | 645 | { |
671 | if (NULL != server) | 646 | if (NULL != server) |
672 | { | 647 | { |
673 | GNUNET_SERVER_destroy (server); | 648 | GNUNET_SERVER_destroy (server); |
674 | server = NULL; | 649 | server = NULL; |
675 | } | 650 | } |
676 | if (GNUNET_SCHEDULER_NO_TASK != child_death_task) | 651 | if (GNUNET_SCHEDULER_NO_TASK != child_death_task) |
677 | { | 652 | { |
678 | GNUNET_SCHEDULER_cancel (child_death_task); | 653 | GNUNET_SCHEDULER_cancel (child_death_task); |
679 | child_death_task = GNUNET_SCHEDULER_NO_TASK; | 654 | child_death_task = GNUNET_SCHEDULER_NO_TASK; |
680 | } | 655 | } |
681 | } | 656 | } |
682 | 657 | ||
683 | 658 | ||
@@ -688,35 +663,31 @@ do_shutdown () | |||
688 | * @param tc context | 663 | * @param tc context |
689 | */ | 664 | */ |
690 | static void | 665 | static void |
691 | shutdown_task (void *cls, | 666 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
692 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
693 | { | 667 | { |
694 | struct ServiceList *pos; | 668 | struct ServiceList *pos; |
695 | 669 | ||
696 | #if DEBUG_ARM | 670 | #if DEBUG_ARM |
697 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 671 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Stopping all services\n")); |
698 | _("Stopping all services\n")); | ||
699 | #endif | 672 | #endif |
700 | if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) | 673 | if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) |
701 | { | 674 | { |
702 | GNUNET_SCHEDULER_cancel (child_restart_task); | 675 | GNUNET_SCHEDULER_cancel (child_restart_task); |
703 | child_restart_task = GNUNET_SCHEDULER_NO_TASK; | 676 | child_restart_task = GNUNET_SCHEDULER_NO_TASK; |
704 | } | 677 | } |
705 | in_shutdown = GNUNET_YES; | 678 | in_shutdown = GNUNET_YES; |
706 | stop_listening (NULL); | 679 | stop_listening (NULL); |
707 | pos = running_head; | 680 | pos = running_head; |
708 | while (NULL != pos) | 681 | while (NULL != pos) |
682 | { | ||
683 | if (pos->proc != NULL) | ||
709 | { | 684 | { |
710 | if (pos->proc != NULL) | 685 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); |
711 | { | 686 | if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) |
712 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 687 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
713 | "Stopping service `%s'\n", | ||
714 | pos->name); | ||
715 | if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) | ||
716 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
717 | } | ||
718 | pos = pos->next; | ||
719 | } | 688 | } |
689 | pos = pos->next; | ||
690 | } | ||
720 | if (running_head == NULL) | 691 | if (running_head == NULL) |
721 | do_shutdown (); | 692 | do_shutdown (); |
722 | } | 693 | } |
@@ -741,40 +712,39 @@ delayed_restart_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
741 | lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; | 712 | lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; |
742 | 713 | ||
743 | /* check for services that need to be restarted due to | 714 | /* check for services that need to be restarted due to |
744 | configuration changes or because the last restart failed */ | 715 | * configuration changes or because the last restart failed */ |
745 | pos = running_head; | 716 | pos = running_head; |
746 | while (pos != NULL) | 717 | while (pos != NULL) |
718 | { | ||
719 | if (pos->proc == NULL) | ||
747 | { | 720 | { |
748 | if (pos->proc == NULL) | 721 | if (GNUNET_TIME_absolute_get_remaining (pos->restartAt).rel_value == 0) |
749 | { | 722 | { |
750 | if (GNUNET_TIME_absolute_get_remaining (pos->restartAt).rel_value == 0) | 723 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
751 | { | 724 | _("Restarting service `%s'.\n"), pos->name); |
752 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 725 | start_process (pos, NULL); |
753 | _("Restarting service `%s'.\n"), pos->name); | 726 | } |
754 | start_process (pos, NULL); | 727 | else |
755 | } | 728 | { |
756 | else | 729 | lowestRestartDelay |
757 | { | 730 | = GNUNET_TIME_relative_min (lowestRestartDelay, |
758 | lowestRestartDelay | 731 | GNUNET_TIME_absolute_get_remaining |
759 | = GNUNET_TIME_relative_min (lowestRestartDelay, | 732 | (pos->restartAt)); |
760 | GNUNET_TIME_absolute_get_remaining | 733 | } |
761 | (pos->restartAt)); | 734 | } |
762 | } | 735 | pos = pos->next; |
763 | } | 736 | } |
764 | pos = pos->next; | ||
765 | } | ||
766 | if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) | 737 | if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) |
767 | { | 738 | { |
768 | #if DEBUG_ARM | 739 | #if DEBUG_ARM |
769 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 740 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
770 | "Will restart process in %llums\n", | 741 | "Will restart process in %llums\n", |
771 | (unsigned long long) lowestRestartDelay.rel_value); | 742 | (unsigned long long) lowestRestartDelay.rel_value); |
772 | #endif | 743 | #endif |
773 | child_restart_task | 744 | child_restart_task |
774 | = GNUNET_SCHEDULER_add_delayed (lowestRestartDelay, | 745 | = GNUNET_SCHEDULER_add_delayed (lowestRestartDelay, |
775 | &delayed_restart_task, | 746 | &delayed_restart_task, NULL); |
776 | NULL); | 747 | } |
777 | } | ||
778 | } | 748 | } |
779 | 749 | ||
780 | 750 | ||
@@ -786,8 +756,7 @@ delayed_restart_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
786 | * @param tc context | 756 | * @param tc context |
787 | */ | 757 | */ |
788 | static void | 758 | static void |
789 | maint_child_death (void *cls, | 759 | maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
790 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
791 | { | 760 | { |
792 | struct ServiceList *pos; | 761 | struct ServiceList *pos; |
793 | struct ServiceList *next; | 762 | struct ServiceList *next; |
@@ -800,93 +769,89 @@ maint_child_death (void *cls, | |||
800 | 769 | ||
801 | child_death_task = GNUNET_SCHEDULER_NO_TASK; | 770 | child_death_task = GNUNET_SCHEDULER_NO_TASK; |
802 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) | 771 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) |
803 | { | 772 | { |
804 | /* shutdown scheduled us, ignore! */ | 773 | /* shutdown scheduled us, ignore! */ |
805 | child_death_task = | 774 | child_death_task = |
806 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr, | 775 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr, |
807 | &maint_child_death, NULL); | 776 | &maint_child_death, NULL); |
808 | return; | 777 | return; |
809 | } | 778 | } |
810 | /* consume the signal */ | 779 | /* consume the signal */ |
811 | GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c))); | 780 | GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c))); |
812 | 781 | ||
813 | /* check for services that died (WAITPID) */ | 782 | /* check for services that died (WAITPID) */ |
814 | next = running_head; | 783 | next = running_head; |
815 | while (NULL != (pos = next)) | 784 | while (NULL != (pos = next)) |
785 | { | ||
786 | next = pos->next; | ||
787 | if (pos->proc == NULL) | ||
788 | continue; | ||
789 | if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc, | ||
790 | &statusType, | ||
791 | &statusCode))) || | ||
792 | ((ret == GNUNET_NO) || | ||
793 | (statusType == GNUNET_OS_PROCESS_STOPPED) || | ||
794 | (statusType == GNUNET_OS_PROCESS_RUNNING))) | ||
795 | continue; | ||
796 | |||
797 | if (statusType == GNUNET_OS_PROCESS_EXITED) | ||
816 | { | 798 | { |
817 | next = pos->next; | 799 | statstr = _( /* process termination method */ "exit"); |
818 | if (pos->proc == NULL) | 800 | statcode = statusCode; |
819 | continue; | 801 | } |
820 | if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc, | 802 | else if (statusType == GNUNET_OS_PROCESS_SIGNALED) |
821 | &statusType, | 803 | { |
822 | &statusCode))) || | 804 | statstr = _( /* process termination method */ "signal"); |
823 | ( (ret == GNUNET_NO) || | 805 | statcode = statusCode; |
824 | (statusType == GNUNET_OS_PROCESS_STOPPED) || | 806 | } |
825 | (statusType == GNUNET_OS_PROCESS_RUNNING)) ) | 807 | else |
826 | continue; | 808 | { |
827 | 809 | statstr = _( /* process termination method */ "unknown"); | |
828 | if (statusType == GNUNET_OS_PROCESS_EXITED) | 810 | statcode = 0; |
829 | { | 811 | } |
830 | statstr = _( /* process termination method */ "exit"); | 812 | GNUNET_OS_process_close (pos->proc); |
831 | statcode = statusCode; | 813 | pos->proc = NULL; |
832 | } | 814 | if (NULL != pos->killing_client) |
833 | else if (statusType == GNUNET_OS_PROCESS_SIGNALED) | 815 | { |
834 | { | 816 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
835 | statstr = _( /* process termination method */ "signal"); | 817 | _("Service `%s' stopped\n"), pos->name); |
836 | statcode = statusCode; | 818 | signal_result (pos->killing_client, |
837 | } | 819 | pos->name, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
838 | else | 820 | GNUNET_SERVER_receive_done (pos->killing_client, GNUNET_OK); |
839 | { | 821 | GNUNET_SERVER_client_drop (pos->killing_client); |
840 | statstr = _( /* process termination method */ "unknown"); | 822 | free_service (pos); |
841 | statcode = 0; | 823 | continue; |
842 | } | 824 | } |
843 | GNUNET_OS_process_close (pos->proc); | 825 | if (GNUNET_YES != in_shutdown) |
844 | pos->proc = NULL; | 826 | { |
845 | if (NULL != pos->killing_client) | 827 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
846 | { | 828 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
847 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 829 | _ |
848 | _("Service `%s' stopped\n"), | 830 | ("Service `%s' terminated with status %s/%d, will try to restart it!\n"), |
849 | pos->name); | 831 | pos->name, statstr, statcode); |
850 | signal_result (pos->killing_client, | 832 | /* schedule restart */ |
851 | pos->name, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 833 | pos->restartAt = GNUNET_TIME_relative_to_absolute (pos->backoff); |
852 | GNUNET_SERVER_receive_done (pos->killing_client, GNUNET_OK); | 834 | if (pos->backoff.rel_value < EXPONENTIAL_BACKOFF_THRESHOLD) |
853 | GNUNET_SERVER_client_drop (pos->killing_client); | 835 | pos->backoff = GNUNET_TIME_relative_multiply (pos->backoff, 2); |
854 | free_service (pos); | 836 | if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) |
855 | continue; | 837 | GNUNET_SCHEDULER_cancel (child_restart_task); |
856 | } | 838 | child_restart_task |
857 | if (GNUNET_YES != in_shutdown) | 839 | = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, |
858 | { | 840 | &delayed_restart_task, NULL); |
859 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 841 | } |
860 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
861 | _("Service `%s' terminated with status %s/%d, will try to restart it!\n"), | ||
862 | pos->name, statstr, statcode); | ||
863 | /* schedule restart */ | ||
864 | pos->restartAt | ||
865 | = GNUNET_TIME_relative_to_absolute (pos->backoff); | ||
866 | if (pos->backoff.rel_value < EXPONENTIAL_BACKOFF_THRESHOLD) | ||
867 | pos->backoff | ||
868 | = GNUNET_TIME_relative_multiply (pos->backoff, 2); | ||
869 | if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) | ||
870 | GNUNET_SCHEDULER_cancel (child_restart_task); | ||
871 | child_restart_task | ||
872 | = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
873 | &delayed_restart_task, | ||
874 | NULL); | ||
875 | } | ||
876 | #if DEBUG_ARM | 842 | #if DEBUG_ARM |
877 | else | 843 | else |
878 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 844 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
879 | "Service `%s' terminated with status %s/%d\n", | 845 | "Service `%s' terminated with status %s/%d\n", |
880 | pos->name, statstr, statcode); | 846 | pos->name, statstr, statcode); |
881 | #endif | 847 | #endif |
882 | } | 848 | } |
883 | child_death_task = | 849 | child_death_task = |
884 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr, | 850 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr, |
885 | &maint_child_death, NULL); | 851 | &maint_child_death, NULL); |
886 | if (GNUNET_YES == in_shutdown) | 852 | if (GNUNET_YES == in_shutdown) |
887 | clean_up_running (); | 853 | clean_up_running (); |
888 | if ( (NULL == running_head) && | 854 | if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) |
889 | (GNUNET_YES == in_shutdown) ) | ||
890 | do_shutdown (); | 855 | do_shutdown (); |
891 | } | 856 | } |
892 | 857 | ||
@@ -898,25 +863,24 @@ transmit_shutdown_ack (void *cls, size_t size, void *buf) | |||
898 | struct GNUNET_MessageHeader *msg; | 863 | struct GNUNET_MessageHeader *msg; |
899 | 864 | ||
900 | if (size < sizeof (struct GNUNET_MessageHeader)) | 865 | if (size < sizeof (struct GNUNET_MessageHeader)) |
901 | { | 866 | { |
902 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 867 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
903 | _("Failed to transmit shutdown ACK.\n")); | 868 | _("Failed to transmit shutdown ACK.\n")); |
904 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 869 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
905 | return 0; /* client disconnected */ | 870 | return 0; /* client disconnected */ |
906 | } | 871 | } |
907 | 872 | ||
908 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 873 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting shutdown ACK.\n")); |
909 | _("Transmitting shutdown ACK.\n")); | ||
910 | 874 | ||
911 | /* Make the connection flushing for the purpose of ACK transmitting, | 875 | /* Make the connection flushing for the purpose of ACK transmitting, |
912 | needed on W32 to ensure that the message is even received, harmless | 876 | * needed on W32 to ensure that the message is even received, harmless |
913 | on other platforms... */ | 877 | * on other platforms... */ |
914 | GNUNET_break (GNUNET_OK == GNUNET_SERVER_client_disable_corking (client)); | 878 | GNUNET_break (GNUNET_OK == GNUNET_SERVER_client_disable_corking (client)); |
915 | msg = (struct GNUNET_MessageHeader *) buf; | 879 | msg = (struct GNUNET_MessageHeader *) buf; |
916 | msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN_ACK); | 880 | msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN_ACK); |
917 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); | 881 | msg->size = htons (sizeof (struct GNUNET_MessageHeader)); |
918 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 882 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
919 | GNUNET_SERVER_client_drop(client); | 883 | GNUNET_SERVER_client_drop (client); |
920 | return sizeof (struct GNUNET_MessageHeader); | 884 | return sizeof (struct GNUNET_MessageHeader); |
921 | } | 885 | } |
922 | 886 | ||
@@ -933,11 +897,11 @@ handle_shutdown (void *cls, | |||
933 | struct GNUNET_SERVER_Client *client, | 897 | struct GNUNET_SERVER_Client *client, |
934 | const struct GNUNET_MessageHeader *message) | 898 | const struct GNUNET_MessageHeader *message) |
935 | { | 899 | { |
936 | GNUNET_SERVER_client_keep(client); | 900 | GNUNET_SERVER_client_keep (client); |
937 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 901 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
938 | _("Initiating shutdown as requested by client.\n")); | 902 | _("Initiating shutdown as requested by client.\n")); |
939 | GNUNET_SERVER_notify_transmit_ready (client, | 903 | GNUNET_SERVER_notify_transmit_ready (client, |
940 | sizeof(struct GNUNET_MessageHeader), | 904 | sizeof (struct GNUNET_MessageHeader), |
941 | GNUNET_TIME_UNIT_FOREVER_REL, | 905 | GNUNET_TIME_UNIT_FOREVER_REL, |
942 | &transmit_shutdown_ack, client); | 906 | &transmit_shutdown_ack, client); |
943 | GNUNET_SERVER_client_persist_ (client); | 907 | GNUNET_SERVER_client_persist_ (client); |
@@ -953,12 +917,13 @@ static void | |||
953 | sighandler_child_death () | 917 | sighandler_child_death () |
954 | { | 918 | { |
955 | static char c; | 919 | static char c; |
956 | int old_errno = errno; /* back-up errno */ | 920 | int old_errno = errno; /* back-up errno */ |
957 | GNUNET_break (1 == | 921 | |
958 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle | 922 | GNUNET_break (1 == |
959 | (sigpipe, GNUNET_DISK_PIPE_END_WRITE), &c, | 923 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle |
960 | sizeof (c))); | 924 | (sigpipe, GNUNET_DISK_PIPE_END_WRITE), |
961 | errno = old_errno; /* restore errno */ | 925 | &c, sizeof (c))); |
926 | errno = old_errno; /* restore errno */ | ||
962 | } | 927 | } |
963 | 928 | ||
964 | 929 | ||
@@ -991,63 +956,59 @@ run (void *cls, | |||
991 | GNUNET_assert (pr != NULL); | 956 | GNUNET_assert (pr != NULL); |
992 | GNUNET_SERVER_ignore_shutdown (serv, GNUNET_YES); | 957 | GNUNET_SERVER_ignore_shutdown (serv, GNUNET_YES); |
993 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 958 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
994 | &shutdown_task, | 959 | &shutdown_task, NULL); |
995 | NULL); | ||
996 | child_death_task = | 960 | child_death_task = |
997 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr, | 961 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr, |
998 | &maint_child_death, NULL); | 962 | &maint_child_death, NULL); |
999 | 963 | ||
1000 | if (GNUNET_OK != | 964 | if (GNUNET_OK != |
1001 | GNUNET_CONFIGURATION_get_value_string (cfg, | 965 | GNUNET_CONFIGURATION_get_value_string (cfg, |
1002 | "ARM", | 966 | "ARM", |
1003 | "GLOBAL_PREFIX", | 967 | "GLOBAL_PREFIX", &prefix_command)) |
1004 | &prefix_command)) | ||
1005 | prefix_command = GNUNET_strdup (""); | 968 | prefix_command = GNUNET_strdup (""); |
1006 | if (GNUNET_OK != | 969 | if (GNUNET_OK != |
1007 | GNUNET_CONFIGURATION_get_value_string (cfg, | 970 | GNUNET_CONFIGURATION_get_value_string (cfg, |
1008 | "ARM", | 971 | "ARM", |
1009 | "GLOBAL_POSTFIX", | 972 | "GLOBAL_POSTFIX", &final_option)) |
1010 | &final_option)) | ||
1011 | final_option = GNUNET_strdup (""); | 973 | final_option = GNUNET_strdup (""); |
1012 | /* start default services... */ | 974 | /* start default services... */ |
1013 | if (GNUNET_OK == | 975 | if (GNUNET_OK == |
1014 | GNUNET_CONFIGURATION_get_value_string (cfg, | 976 | GNUNET_CONFIGURATION_get_value_string (cfg, |
1015 | "ARM", | 977 | "ARM", |
1016 | "DEFAULTSERVICES", | 978 | "DEFAULTSERVICES", |
1017 | &defaultservices)) | 979 | &defaultservices)) |
1018 | { | 980 | { |
1019 | #if DEBUG_ARM | 981 | #if DEBUG_ARM |
1020 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 982 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1021 | "Starting default services `%s'\n", defaultservices); | 983 | "Starting default services `%s'\n", defaultservices); |
1022 | #endif | 984 | #endif |
1023 | if (0 < strlen (defaultservices)) | 985 | if (0 < strlen (defaultservices)) |
1024 | { | 986 | { |
1025 | pos = strtok (defaultservices, " "); | 987 | pos = strtok (defaultservices, " "); |
1026 | while (pos != NULL) | 988 | while (pos != NULL) |
1027 | { | 989 | { |
1028 | start_service (NULL, pos, NULL); | 990 | start_service (NULL, pos, NULL); |
1029 | pos = strtok (NULL, " "); | 991 | pos = strtok (NULL, " "); |
1030 | } | 992 | } |
1031 | } | ||
1032 | GNUNET_free (defaultservices); | ||
1033 | } | 993 | } |
994 | GNUNET_free (defaultservices); | ||
995 | } | ||
1034 | else | 996 | else |
1035 | { | 997 | { |
1036 | #if DEBUG_ARM | 998 | #if DEBUG_ARM |
1037 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 999 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No default services configured.\n"); |
1038 | "No default services configured.\n"); | ||
1039 | #endif | 1000 | #endif |
1040 | } | 1001 | } |
1041 | 1002 | ||
1042 | /* create listening sockets for future services*/ | 1003 | /* create listening sockets for future services */ |
1043 | prepareServices (cfg); | 1004 | prepareServices (cfg); |
1044 | 1005 | ||
1045 | /* process client requests */ | 1006 | /* process client requests */ |
1046 | GNUNET_SERVER_add_handlers (server, handlers); | 1007 | GNUNET_SERVER_add_handlers (server, handlers); |
1047 | 1008 | ||
1048 | /* manage services */ | 1009 | /* manage services */ |
1049 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, | 1010 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, |
1050 | &config_change_task, NULL); | 1011 | &config_change_task, NULL); |
1051 | } | 1012 | } |
1052 | 1013 | ||
1053 | 1014 | ||
@@ -1066,10 +1027,11 @@ main (int argc, char *const *argv) | |||
1066 | 1027 | ||
1067 | sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO); | 1028 | sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO); |
1068 | GNUNET_assert (sigpipe != NULL); | 1029 | GNUNET_assert (sigpipe != NULL); |
1069 | shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); | 1030 | shc_chld = |
1070 | ret = (GNUNET_OK == | 1031 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); |
1071 | GNUNET_SERVICE_run (argc, | 1032 | ret = |
1072 | argv, "arm", GNUNET_YES, &run, NULL)) ? 0 : 1; | 1033 | (GNUNET_OK == |
1034 | GNUNET_SERVICE_run (argc, argv, "arm", GNUNET_YES, &run, NULL)) ? 0 : 1; | ||
1073 | GNUNET_SIGNAL_handler_uninstall (shc_chld); | 1035 | GNUNET_SIGNAL_handler_uninstall (shc_chld); |
1074 | shc_chld = NULL; | 1036 | shc_chld = NULL; |
1075 | GNUNET_DISK_pipe_close (sigpipe); | 1037 | GNUNET_DISK_pipe_close (sigpipe); |
@@ -1085,8 +1047,8 @@ main (int argc, char *const *argv) | |||
1085 | */ | 1047 | */ |
1086 | void __attribute__ ((constructor)) GNUNET_ARM_memory_init () | 1048 | void __attribute__ ((constructor)) GNUNET_ARM_memory_init () |
1087 | { | 1049 | { |
1088 | mallopt (M_TRIM_THRESHOLD, 4*1024); | 1050 | mallopt (M_TRIM_THRESHOLD, 4 * 1024); |
1089 | mallopt (M_TOP_PAD, 1*1024); | 1051 | mallopt (M_TOP_PAD, 1 * 1024); |
1090 | malloc_trim (0); | 1052 | malloc_trim (0); |
1091 | } | 1053 | } |
1092 | #endif | 1054 | #endif |