aboutsummaryrefslogtreecommitdiff
path: root/src/arm/arm_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/arm_api.c')
-rw-r--r--src/arm/arm_api.c107
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 */
635static enum GNUNET_ARM_Result 654static enum GNUNET_ARM_Result
636start_arm_service (struct GNUNET_ARM_Handle *h, 655start_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 (&notify_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 &notify_starting,
1015 op);
1016 }
1017 else
1018 {
1019 op->async = GNUNET_SCHEDULER_add_now (&notify_starting,
1020 op);
1021 }
1022 GNUNET_DISK_pipe_close (sig);
950 return op; 1023 return op;
951} 1024}
952 1025