diff options
Diffstat (limited to 'src/arm/arm_api.c')
-rw-r--r-- | src/arm/arm_api.c | 107 |
1 files changed, 90 insertions, 17 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c index dc5c9c25b..da7268f67 100644 --- a/src/arm/arm_api.c +++ b/src/arm/arm_api.c | |||
@@ -85,6 +85,11 @@ struct GNUNET_ARM_Operation | |||
85 | enum GNUNET_ARM_Result starting_ret; | 85 | enum GNUNET_ARM_Result starting_ret; |
86 | 86 | ||
87 | /** | 87 | /** |
88 | * File descriptor to close on operation stop, if not NULL. | ||
89 | */ | ||
90 | struct GNUNET_DISK_FileHandle *rfd; | ||
91 | |||
92 | /** | ||
88 | * Is this an operation to stop the ARM service? | 93 | * Is this an operation to stop the ARM service? |
89 | */ | 94 | */ |
90 | int is_arm_stop; | 95 | int is_arm_stop; |
@@ -203,19 +208,27 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h) | |||
203 | h->currently_up = GNUNET_NO; | 208 | h->currently_up = GNUNET_NO; |
204 | GNUNET_assert (NULL == h->reconnect_task); | 209 | GNUNET_assert (NULL == h->reconnect_task); |
205 | h->reconnect_task = | 210 | h->reconnect_task = |
206 | GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_task, h); | 211 | GNUNET_SCHEDULER_add_delayed (h->retry_backoff, |
212 | &reconnect_arm_task, | ||
213 | h); | ||
207 | while (NULL != (op = h->operation_pending_head)) | 214 | while (NULL != (op = h->operation_pending_head)) |
208 | { | 215 | { |
209 | if (NULL != op->result_cont) | 216 | if (NULL != op->result_cont) |
210 | op->result_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0); | 217 | op->result_cont (op->cont_cls, |
218 | GNUNET_ARM_REQUEST_DISCONNECTED, | ||
219 | 0); | ||
211 | if (NULL != op->list_cont) | 220 | if (NULL != op->list_cont) |
212 | op->list_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0, NULL); | 221 | op->list_cont (op->cont_cls, |
222 | GNUNET_ARM_REQUEST_DISCONNECTED, | ||
223 | 0, | ||
224 | NULL); | ||
213 | GNUNET_ARM_operation_cancel (op); | 225 | GNUNET_ARM_operation_cancel (op); |
214 | } | 226 | } |
215 | GNUNET_assert (NULL == h->operation_pending_head); | 227 | GNUNET_assert (NULL == h->operation_pending_head); |
216 | h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); | 228 | h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); |
217 | if (NULL != h->conn_status) | 229 | if (NULL != h->conn_status) |
218 | h->conn_status (h->conn_status_cls, GNUNET_NO); | 230 | h->conn_status (h->conn_status_cls, |
231 | GNUNET_NO); | ||
219 | } | 232 | } |
220 | 233 | ||
221 | 234 | ||
@@ -257,7 +270,8 @@ handle_arm_result (void *cls, | |||
257 | void *result_cont_cls; | 270 | void *result_cont_cls; |
258 | 271 | ||
259 | id = GNUNET_ntohll (res->arm_msg.request_id); | 272 | id = GNUNET_ntohll (res->arm_msg.request_id); |
260 | op = find_op_by_id (h, id); | 273 | op = find_op_by_id (h, |
274 | id); | ||
261 | if (NULL == op) | 275 | if (NULL == op) |
262 | { | 276 | { |
263 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 277 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -356,7 +370,9 @@ check_arm_list_result (void *cls, | |||
356 | { | 370 | { |
357 | uint16_t name_index = ntohs (ssm->name_index); | 371 | uint16_t name_index = ntohs (ssm->name_index); |
358 | uint16_t binary_index = ntohs (ssm->binary_index); | 372 | uint16_t binary_index = ntohs (ssm->binary_index); |
359 | if (NULL == pool_get (pool_start, pool_size, name_index)) | 373 | if (NULL == pool_get (pool_start, |
374 | pool_size, | ||
375 | name_index)) | ||
360 | { | 376 | { |
361 | GNUNET_break_op (0); | 377 | GNUNET_break_op (0); |
362 | return GNUNET_NO; | 378 | return GNUNET_NO; |
@@ -418,9 +434,11 @@ handle_arm_list_result (void *cls, | |||
418 | const char *name; | 434 | const char *name; |
419 | const char *binary; | 435 | const char *binary; |
420 | 436 | ||
421 | GNUNET_assert (NULL != (name = pool_get (pool_start, pool_size, | 437 | GNUNET_assert (NULL != (name = pool_get (pool_start, |
438 | pool_size, | ||
422 | name_index))); | 439 | name_index))); |
423 | GNUNET_assert (NULL != (binary = pool_get (pool_start, pool_size, | 440 | GNUNET_assert (NULL != (binary = pool_get (pool_start, |
441 | pool_size, | ||
424 | binary_index))); | 442 | binary_index))); |
425 | list[i] = (struct GNUNET_ARM_ServiceInfo) { | 443 | list[i] = (struct GNUNET_ARM_ServiceInfo) { |
426 | .name = name, | 444 | .name = name, |
@@ -630,11 +648,13 @@ GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h) | |||
630 | * | 648 | * |
631 | * @param h the handle with configuration details | 649 | * @param h the handle with configuration details |
632 | * @param std_inheritance inheritance of std streams | 650 | * @param std_inheritance inheritance of std streams |
651 | * @param sigfd socket to pass to ARM for signalling | ||
633 | * @return operation status code | 652 | * @return operation status code |
634 | */ | 653 | */ |
635 | static enum GNUNET_ARM_Result | 654 | static enum GNUNET_ARM_Result |
636 | start_arm_service (struct GNUNET_ARM_Handle *h, | 655 | start_arm_service (struct GNUNET_ARM_Handle *h, |
637 | enum GNUNET_OS_InheritStdioFlags std_inheritance) | 656 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
657 | struct GNUNET_DISK_FileHandle *sigfd) | ||
638 | { | 658 | { |
639 | struct GNUNET_OS_Process *proc; | 659 | struct GNUNET_OS_Process *proc; |
640 | char *cbinary; | 660 | char *cbinary; |
@@ -643,7 +663,19 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
643 | char *config; | 663 | char *config; |
644 | char *loprefix; | 664 | char *loprefix; |
645 | char *lopostfix; | 665 | char *lopostfix; |
666 | SOCKTYPE ld[2]; | ||
667 | SOCKTYPE *lsocks; | ||
646 | 668 | ||
669 | if (NULL == sigfd) | ||
670 | { | ||
671 | lsocks = NULL; | ||
672 | } | ||
673 | else | ||
674 | { | ||
675 | ld[0] = sigfd->fd; | ||
676 | ld[1] = -1; | ||
677 | lsocks = ld; | ||
678 | } | ||
647 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg, | 679 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg, |
648 | "arm", | 680 | "arm", |
649 | "PREFIX", | 681 | "PREFIX", |
@@ -700,7 +732,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
700 | if (NULL == config) | 732 | if (NULL == config) |
701 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 733 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
702 | std_inheritance, | 734 | std_inheritance, |
703 | NULL, | 735 | lsocks, |
704 | loprefix, | 736 | loprefix, |
705 | quotedbinary, | 737 | quotedbinary, |
706 | /* no daemonization! */ | 738 | /* no daemonization! */ |
@@ -709,7 +741,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
709 | else | 741 | else |
710 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 742 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
711 | std_inheritance, | 743 | std_inheritance, |
712 | NULL, | 744 | lsocks, |
713 | loprefix, | 745 | loprefix, |
714 | quotedbinary, | 746 | quotedbinary, |
715 | "-c", | 747 | "-c", |
@@ -723,7 +755,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
723 | if (NULL == config) | 755 | if (NULL == config) |
724 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 756 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
725 | std_inheritance, | 757 | std_inheritance, |
726 | NULL, | 758 | lsocks, |
727 | loprefix, | 759 | loprefix, |
728 | quotedbinary, | 760 | quotedbinary, |
729 | "-d", /* do daemonize */ | 761 | "-d", /* do daemonize */ |
@@ -732,7 +764,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
732 | else | 764 | else |
733 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 765 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
734 | std_inheritance, | 766 | std_inheritance, |
735 | NULL, | 767 | lsocks, |
736 | loprefix, | 768 | loprefix, |
737 | quotedbinary, | 769 | quotedbinary, |
738 | "-c", | 770 | "-c", |
@@ -764,6 +796,16 @@ GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op) | |||
764 | { | 796 | { |
765 | struct GNUNET_ARM_Handle *h = op->h; | 797 | struct GNUNET_ARM_Handle *h = op->h; |
766 | 798 | ||
799 | if (NULL != op->async) | ||
800 | { | ||
801 | GNUNET_SCHEDULER_cancel (op->async); | ||
802 | op->async = NULL; | ||
803 | } | ||
804 | if (NULL != op->rfd) | ||
805 | { | ||
806 | GNUNET_DISK_file_close (op->rfd); | ||
807 | op->rfd = NULL; | ||
808 | } | ||
767 | if (h->thm == op) | 809 | if (h->thm == op) |
768 | { | 810 | { |
769 | op->result_cont = NULL; | 811 | op->result_cont = NULL; |
@@ -895,6 +937,8 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | |||
895 | { | 937 | { |
896 | struct GNUNET_ARM_Operation *op; | 938 | struct GNUNET_ARM_Operation *op; |
897 | enum GNUNET_ARM_Result ret; | 939 | enum GNUNET_ARM_Result ret; |
940 | struct GNUNET_DISK_PipeHandle *sig; | ||
941 | struct GNUNET_DISK_FileHandle *wsig; | ||
898 | 942 | ||
899 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 943 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
900 | "Starting service `%s'\n", | 944 | "Starting service `%s'\n", |
@@ -933,8 +977,22 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | |||
933 | are unlikely to hammer 'gnunet-arm -s' on a busy system, | 977 | are unlikely to hammer 'gnunet-arm -s' on a busy system, |
934 | the above check should catch 99.99% of the cases where ARM | 978 | the above check should catch 99.99% of the cases where ARM |
935 | is already running. */ | 979 | is already running. */ |
936 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting ARM service\n"); | 980 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
937 | ret = start_arm_service (h, std_inheritance); | 981 | "Starting ARM service\n"); |
982 | if (NULL == (sig = GNUNET_DISK_pipe (GNUNET_NO, | ||
983 | GNUNET_NO, | ||
984 | GNUNET_NO, | ||
985 | GNUNET_YES))) | ||
986 | { | ||
987 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
988 | "pipe"); | ||
989 | } | ||
990 | wsig = GNUNET_DISK_pipe_detach_end (sig, | ||
991 | GNUNET_DISK_PIPE_END_WRITE); | ||
992 | ret = start_arm_service (h, | ||
993 | std_inheritance, | ||
994 | wsig); | ||
995 | GNUNET_DISK_file_close (wsig); | ||
938 | if (GNUNET_ARM_RESULT_STARTING == ret) | 996 | if (GNUNET_ARM_RESULT_STARTING == ret) |
939 | reconnect_arm (h); | 997 | reconnect_arm (h); |
940 | op = GNUNET_new (struct GNUNET_ARM_Operation); | 998 | op = GNUNET_new (struct GNUNET_ARM_Operation); |
@@ -945,8 +1003,23 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | |||
945 | h->operation_pending_tail, | 1003 | h->operation_pending_tail, |
946 | op); | 1004 | op); |
947 | op->starting_ret = ret; | 1005 | op->starting_ret = ret; |
948 | op->async = GNUNET_SCHEDULER_add_now (¬ify_starting, | 1006 | if (NULL != sig) |
949 | op); | 1007 | { |
1008 | op->rfd = GNUNET_DISK_pipe_detach_end (sig, | ||
1009 | GNUNET_DISK_PIPE_END_READ); | ||
1010 | /* Wait at most a minute for gnunet-service-arm to be up, as beyond | ||
1011 | that something clearly just went wrong */ | ||
1012 | op->async = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_MINUTES, | ||
1013 | op->rfd, | ||
1014 | ¬ify_starting, | ||
1015 | op); | ||
1016 | } | ||
1017 | else | ||
1018 | { | ||
1019 | op->async = GNUNET_SCHEDULER_add_now (¬ify_starting, | ||
1020 | op); | ||
1021 | } | ||
1022 | GNUNET_DISK_pipe_close (sig); | ||
950 | return op; | 1023 | return op; |
951 | } | 1024 | } |
952 | 1025 | ||