aboutsummaryrefslogtreecommitdiff
path: root/src/arm/gnunet-service-arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/gnunet-service-arm.c')
-rw-r--r--src/arm/gnunet-service-arm.c153
1 files changed, 69 insertions, 84 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index e4a8e7c6c..ddccb7fa0 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -198,8 +198,8 @@ config_change_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
198 while (pos != NULL) 198 while (pos != NULL)
199 { 199 {
200 /* FIXME: this test for config change may be a bit too coarse grained */ 200 /* FIXME: this test for config change may be a bit too coarse grained */
201 if ((0 == STAT (pos->config, &sbuf)) && 201 if ((0 == STAT (pos->config, &sbuf)) && (pos->mtime < sbuf.st_mtime) &&
202 (pos->mtime < sbuf.st_mtime) && (pos->proc != NULL)) 202 (pos->proc != NULL))
203 { 203 {
204 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 204 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
205 _ 205 _
@@ -235,8 +235,8 @@ write_result (void *cls, size_t size, void *buf)
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, "Sending status response %u to client\n",
239 "Sending status response %u to client\n", (unsigned int) *res); 239 (unsigned int) *res);
240#endif 240#endif
241 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); 241 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
242 msg = buf; 242 msg = buf;
@@ -257,8 +257,8 @@ write_result (void *cls, size_t size, void *buf)
257 * @return NULL if it was not found 257 * @return NULL if it was not found
258 */ 258 */
259static void 259static void
260signal_result (struct GNUNET_SERVER_Client *client, 260signal_result (struct GNUNET_SERVER_Client *client, const char *name,
261 const char *name, uint16_t result) 261 uint16_t result)
262{ 262{
263 uint16_t *res; 263 uint16_t *res;
264 264
@@ -270,8 +270,8 @@ signal_result (struct GNUNET_SERVER_Client *client,
270 } 270 }
271#if DEBUG_ARM 271#if DEBUG_ARM
272 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 272 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
273 "Telling client that service `%s' is now %s\n", 273 "Telling client that service `%s' is now %s\n", name,
274 name, result == GNUNET_MESSAGE_TYPE_ARM_IS_DOWN ? "down" : "up"); 274 result == GNUNET_MESSAGE_TYPE_ARM_IS_DOWN ? "down" : "up");
275#endif 275#endif
276 res = GNUNET_malloc (sizeof (uint16_t)); 276 res = GNUNET_malloc (sizeof (uint16_t));
277 *res = result; 277 *res = result;
@@ -344,12 +344,12 @@ start_process (struct ServiceList *sl, const int *lsocks)
344 344
345 /* start service */ 345 /* start service */
346 if (GNUNET_OK != 346 if (GNUNET_OK !=
347 GNUNET_CONFIGURATION_get_value_string (cfg, 347 GNUNET_CONFIGURATION_get_value_string (cfg, sl->name, "PREFIX",
348 sl->name, "PREFIX", &loprefix)) 348 &loprefix))
349 loprefix = GNUNET_strdup (prefix_command); 349 loprefix = GNUNET_strdup (prefix_command);
350 if (GNUNET_OK != 350 if (GNUNET_OK !=
351 GNUNET_CONFIGURATION_get_value_string (cfg, 351 GNUNET_CONFIGURATION_get_value_string (cfg, sl->name, "OPTIONS",
352 sl->name, "OPTIONS", &options)) 352 &options))
353 { 353 {
354 options = GNUNET_strdup (final_option); 354 options = GNUNET_strdup (final_option);
355 if (NULL == strstr (options, "%")) 355 if (NULL == strstr (options, "%"))
@@ -376,8 +376,8 @@ start_process (struct ServiceList *sl, const int *lsocks)
376 next = optend + 1; 376 next = optend + 1;
377 *optend = '\0'; 377 *optend = '\0';
378 if (GNUNET_OK != 378 if (GNUNET_OK !=
379 GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", 379 GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", optpos + 1,
380 optpos + 1, &val)) 380 &val))
381 val = GNUNET_strdup (""); 381 val = GNUNET_strdup ("");
382 *optpos = '\0'; 382 *optpos = '\0';
383 GNUNET_asprintf (&optpos, "%s%s%c%s", options, val, b, next); 383 GNUNET_asprintf (&optpos, "%s%s%c%s", options, val, b, next);
@@ -395,18 +395,16 @@ start_process (struct ServiceList *sl, const int *lsocks)
395 sl->name, sl->binary, sl->config); 395 sl->name, sl->binary, sl->config);
396#endif 396#endif
397 if (GNUNET_YES == use_debug) 397 if (GNUNET_YES == use_debug)
398 sl->proc = do_start_process (lsocks, 398 sl->proc =
399 loprefix, 399 do_start_process (lsocks, loprefix, sl->binary, "-c", sl->config, "-L",
400 sl->binary, 400 "DEBUG", options, NULL);
401 "-c", sl->config,
402 "-L", "DEBUG", options, NULL);
403 else 401 else
404 sl->proc = do_start_process (lsocks, 402 sl->proc =
405 loprefix, 403 do_start_process (lsocks, loprefix, sl->binary, "-c", sl->config,
406 sl->binary, "-c", sl->config, options, NULL); 404 options, NULL);
407 if (sl->proc == NULL) 405 if (sl->proc == NULL)
408 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 406 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to start service `%s'\n"),
409 _("Failed to start service `%s'\n"), sl->name); 407 sl->name);
410 else 408 else
411 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting service `%s'\n"), sl->name); 409 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting service `%s'\n"), sl->name);
412 GNUNET_free (loprefix); 410 GNUNET_free (loprefix);
@@ -423,8 +421,8 @@ start_process (struct ServiceList *sl, const int *lsocks)
423 * @return GNUNET_OK on success, GNUNET_SYSERR on error 421 * @return GNUNET_OK on success, GNUNET_SYSERR on error
424 */ 422 */
425int 423int
426start_service (struct GNUNET_SERVER_Client *client, 424start_service (struct GNUNET_SERVER_Client *client, const char *servicename,
427 const char *servicename, const int *lsocks) 425 const int *lsocks)
428{ 426{
429 struct ServiceList *sl; 427 struct ServiceList *sl;
430 char *binary; 428 char *binary;
@@ -442,14 +440,14 @@ start_service (struct GNUNET_SERVER_Client *client,
442 sl = find_service (servicename); 440 sl = find_service (servicename);
443 if (sl != NULL) 441 if (sl != NULL)
444 { 442 {
445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 443 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Service `%s' already running.\n"),
446 _("Service `%s' already running.\n"), servicename); 444 servicename);
447 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); 445 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP);
448 return GNUNET_SYSERR; 446 return GNUNET_SYSERR;
449 } 447 }
450 if (GNUNET_OK != 448 if (GNUNET_OK !=
451 GNUNET_CONFIGURATION_get_value_string (cfg, 449 GNUNET_CONFIGURATION_get_value_string (cfg, servicename, "BINARY",
452 servicename, "BINARY", &binary)) 450 &binary))
453 { 451 {
454 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 452 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
455 _("Binary implementing service `%s' not known!\n"), 453 _("Binary implementing service `%s' not known!\n"),
@@ -458,9 +456,7 @@ start_service (struct GNUNET_SERVER_Client *client,
458 return GNUNET_SYSERR; 456 return GNUNET_SYSERR;
459 } 457 }
460 if ((GNUNET_OK != 458 if ((GNUNET_OK !=
461 GNUNET_CONFIGURATION_get_value_filename (cfg, 459 GNUNET_CONFIGURATION_get_value_filename (cfg, servicename, "CONFIG",
462 servicename,
463 "CONFIG",
464 &config)) || 460 &config)) ||
465 (0 != STAT (config, &sbuf))) 461 (0 != STAT (config, &sbuf)))
466 { 462 {
@@ -499,8 +495,8 @@ stop_service (struct GNUNET_SERVER_Client *client, const char *servicename)
499{ 495{
500 struct ServiceList *pos; 496 struct ServiceList *pos;
501 497
502 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 498 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Preparing to stop `%s'\n"),
503 _("Preparing to stop `%s'\n"), servicename); 499 servicename);
504 pos = find_service (servicename); 500 pos = find_service (servicename);
505 if (pos == NULL) 501 if (pos == NULL)
506 { 502 {
@@ -515,8 +511,8 @@ stop_service (struct GNUNET_SERVER_Client *client, const char *servicename)
515 { 511 {
516 /* killing already in progress */ 512 /* killing already in progress */
517#if DEBUG_ARM 513#if DEBUG_ARM
518 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' is already down\n",
519 "Service `%s' is already down\n", servicename); 515 servicename);
520#endif 516#endif
521 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); 517 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
522 GNUNET_SERVER_receive_done (client, GNUNET_OK); 518 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -564,8 +560,7 @@ stop_service (struct GNUNET_SERVER_Client *client, const char *servicename)
564 * GNUNET_SYSERR to close it (signal serious error) 560 * GNUNET_SYSERR to close it (signal serious error)
565 */ 561 */
566static void 562static void
567handle_start (void *cls, 563handle_start (void *cls, struct GNUNET_SERVER_Client *client,
568 struct GNUNET_SERVER_Client *client,
569 const struct GNUNET_MessageHeader *message) 564 const struct GNUNET_MessageHeader *message)
570{ 565{
571 const char *servicename; 566 const char *servicename;
@@ -595,8 +590,7 @@ handle_start (void *cls,
595 * GNUNET_SYSERR to close it (signal serious error) 590 * GNUNET_SYSERR to close it (signal serious error)
596 */ 591 */
597static void 592static void
598handle_stop (void *cls, 593handle_stop (void *cls, struct GNUNET_SERVER_Client *client,
599 struct GNUNET_SERVER_Client *client,
600 const struct GNUNET_MessageHeader *message) 594 const struct GNUNET_MessageHeader *message)
601{ 595{
602 const char *servicename; 596 const char *servicename;
@@ -720,16 +714,16 @@ delayed_restart_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
720 { 714 {
721 if (GNUNET_TIME_absolute_get_remaining (pos->restartAt).rel_value == 0) 715 if (GNUNET_TIME_absolute_get_remaining (pos->restartAt).rel_value == 0)
722 { 716 {
723 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 717 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Restarting service `%s'.\n"),
724 _("Restarting service `%s'.\n"), pos->name); 718 pos->name);
725 start_process (pos, NULL); 719 start_process (pos, NULL);
726 } 720 }
727 else 721 else
728 { 722 {
729 lowestRestartDelay 723 lowestRestartDelay =
730 = GNUNET_TIME_relative_min (lowestRestartDelay, 724 GNUNET_TIME_relative_min (lowestRestartDelay,
731 GNUNET_TIME_absolute_get_remaining 725 GNUNET_TIME_absolute_get_remaining (pos->
732 (pos->restartAt)); 726 restartAt));
733 } 727 }
734 } 728 }
735 pos = pos->next; 729 pos = pos->next;
@@ -737,13 +731,12 @@ delayed_restart_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
737 if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) 731 if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
738 { 732 {
739#if DEBUG_ARM 733#if DEBUG_ARM
740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will restart process in %llums\n",
741 "Will restart process in %llums\n",
742 (unsigned long long) lowestRestartDelay.rel_value); 735 (unsigned long long) lowestRestartDelay.rel_value);
743#endif 736#endif
744 child_restart_task 737 child_restart_task =
745 = GNUNET_SCHEDULER_add_delayed (lowestRestartDelay, 738 GNUNET_SCHEDULER_add_delayed (lowestRestartDelay, &delayed_restart_task,
746 &delayed_restart_task, NULL); 739 NULL);
747 } 740 }
748} 741}
749 742
@@ -786,12 +779,10 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
786 next = pos->next; 779 next = pos->next;
787 if (pos->proc == NULL) 780 if (pos->proc == NULL)
788 continue; 781 continue;
789 if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc, 782 if ((GNUNET_SYSERR ==
790 &statusType, 783 (ret = GNUNET_OS_process_status (pos->proc, &statusType, &statusCode)))
791 &statusCode))) || 784 || ((ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) ||
792 ((ret == GNUNET_NO) || 785 (statusType == GNUNET_OS_PROCESS_RUNNING)))
793 (statusType == GNUNET_OS_PROCESS_STOPPED) ||
794 (statusType == GNUNET_OS_PROCESS_RUNNING)))
795 continue; 786 continue;
796 787
797 if (statusType == GNUNET_OS_PROCESS_EXITED) 788 if (statusType == GNUNET_OS_PROCESS_EXITED)
@@ -813,10 +804,10 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
813 pos->proc = NULL; 804 pos->proc = NULL;
814 if (NULL != pos->killing_client) 805 if (NULL != pos->killing_client)
815 { 806 {
816 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 807 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Service `%s' stopped\n"),
817 _("Service `%s' stopped\n"), pos->name); 808 pos->name);
818 signal_result (pos->killing_client, 809 signal_result (pos->killing_client, pos->name,
819 pos->name, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); 810 GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
820 GNUNET_SERVER_receive_done (pos->killing_client, GNUNET_OK); 811 GNUNET_SERVER_receive_done (pos->killing_client, GNUNET_OK);
821 GNUNET_SERVER_client_drop (pos->killing_client); 812 GNUNET_SERVER_client_drop (pos->killing_client);
822 free_service (pos); 813 free_service (pos);
@@ -835,15 +826,15 @@ maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
835 pos->backoff = GNUNET_TIME_relative_multiply (pos->backoff, 2); 826 pos->backoff = GNUNET_TIME_relative_multiply (pos->backoff, 2);
836 if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) 827 if (GNUNET_SCHEDULER_NO_TASK != child_restart_task)
837 GNUNET_SCHEDULER_cancel (child_restart_task); 828 GNUNET_SCHEDULER_cancel (child_restart_task);
838 child_restart_task 829 child_restart_task =
839 = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, 830 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
840 &delayed_restart_task, NULL); 831 &delayed_restart_task, NULL);
841 } 832 }
842#if DEBUG_ARM 833#if DEBUG_ARM
843 else 834 else
844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
845 "Service `%s' terminated with status %s/%d\n", 836 "Service `%s' terminated with status %s/%d\n", pos->name,
846 pos->name, statstr, statcode); 837 statstr, statcode);
847#endif 838#endif
848 } 839 }
849 child_death_task = 840 child_death_task =
@@ -893,8 +884,7 @@ transmit_shutdown_ack (void *cls, size_t size, void *buf)
893 * @param message the actual message 884 * @param message the actual message
894 */ 885 */
895static void 886static void
896handle_shutdown (void *cls, 887handle_shutdown (void *cls, struct GNUNET_SERVER_Client *client,
897 struct GNUNET_SERVER_Client *client,
898 const struct GNUNET_MessageHeader *message) 888 const struct GNUNET_MessageHeader *message)
899{ 889{
900 GNUNET_SERVER_client_keep (client); 890 GNUNET_SERVER_client_keep (client);
@@ -935,8 +925,7 @@ sighandler_child_death ()
935 * @param c configuration to use 925 * @param c configuration to use
936 */ 926 */
937static void 927static void
938run (void *cls, 928run (void *cls, struct GNUNET_SERVER_Handle *serv,
939 struct GNUNET_SERVER_Handle *serv,
940 const struct GNUNET_CONFIGURATION_Handle *c) 929 const struct GNUNET_CONFIGURATION_Handle *c)
941{ 930{
942 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 931 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
@@ -955,32 +944,28 @@ run (void *cls,
955 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); 944 pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
956 GNUNET_assert (pr != NULL); 945 GNUNET_assert (pr != NULL);
957 GNUNET_SERVER_ignore_shutdown (serv, GNUNET_YES); 946 GNUNET_SERVER_ignore_shutdown (serv, GNUNET_YES);
958 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 947 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
959 &shutdown_task, NULL); 948 NULL);
960 child_death_task = 949 child_death_task =
961 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr, 950 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, pr,
962 &maint_child_death, NULL); 951 &maint_child_death, NULL);
963 952
964 if (GNUNET_OK != 953 if (GNUNET_OK !=
965 GNUNET_CONFIGURATION_get_value_string (cfg, 954 GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "GLOBAL_PREFIX",
966 "ARM", 955 &prefix_command))
967 "GLOBAL_PREFIX", &prefix_command))
968 prefix_command = GNUNET_strdup (""); 956 prefix_command = GNUNET_strdup ("");
969 if (GNUNET_OK != 957 if (GNUNET_OK !=
970 GNUNET_CONFIGURATION_get_value_string (cfg, 958 GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "GLOBAL_POSTFIX",
971 "ARM", 959 &final_option))
972 "GLOBAL_POSTFIX", &final_option))
973 final_option = GNUNET_strdup (""); 960 final_option = GNUNET_strdup ("");
974 /* start default services... */ 961 /* start default services... */
975 if (GNUNET_OK == 962 if (GNUNET_OK ==
976 GNUNET_CONFIGURATION_get_value_string (cfg, 963 GNUNET_CONFIGURATION_get_value_string (cfg, "ARM", "DEFAULTSERVICES",
977 "ARM",
978 "DEFAULTSERVICES",
979 &defaultservices)) 964 &defaultservices))
980 { 965 {
981#if DEBUG_ARM 966#if DEBUG_ARM
982 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting default services `%s'\n",
983 "Starting default services `%s'\n", defaultservices); 968 defaultservices);
984#endif 969#endif
985 if (0 < strlen (defaultservices)) 970 if (0 < strlen (defaultservices))
986 { 971 {