diff options
-rw-r--r-- | src/include/gnunet_testbed_service.h | 46 | ||||
-rw-r--r-- | src/testbed/gnunet-testbed-profiler.c | 63 | ||||
-rw-r--r-- | src/testbed/test_testbed_api_3peers_3controllers.c | 30 | ||||
-rw-r--r-- | src/testbed/test_testbed_api_controllerlink.c | 32 | ||||
-rw-r--r-- | src/testbed/testbed_api_hosts.c | 205 | ||||
-rw-r--r-- | src/testbed/testbed_api_testbed.c | 34 |
6 files changed, 332 insertions, 78 deletions
diff --git a/src/include/gnunet_testbed_service.h b/src/include/gnunet_testbed_service.h index 91fb424c4..55e503232 100644 --- a/src/include/gnunet_testbed_service.h +++ b/src/include/gnunet_testbed_service.h | |||
@@ -133,19 +133,53 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host); | |||
133 | 133 | ||
134 | 134 | ||
135 | /** | 135 | /** |
136 | * The handle for whether a host is habitable or not | ||
137 | */ | ||
138 | struct GNUNET_TESTBED_HostHabitableCheckHandle; | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to | ||
143 | * inform whether the given host is habitable or not. The Handle returned by | ||
144 | * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called | ||
145 | * | ||
146 | * @param cls the closure given to GNUNET_TESTBED_is_host_habitable() | ||
147 | * @param status GNUNET_YES if it is habitable; GNUNET_NO if not | ||
148 | */ | ||
149 | typedef void (*GNUNET_TESTBED_HostHabitableCallback) (void *cls, | ||
150 | int status); | ||
151 | |||
152 | |||
153 | /** | ||
136 | * Checks whether a host can be used to start testbed service | 154 | * Checks whether a host can be used to start testbed service |
137 | * | 155 | * |
138 | * @param host the host to check | 156 | * @param host the host to check |
139 | * @param config the configuration handle to lookup the path of the testbed helper | 157 | * @param config the configuration handle to lookup the path of the testbed |
140 | * @return GNUNET_YES if testbed service can be started on the given host | 158 | * helper |
141 | * remotely; GNUNET_NO if not | 159 | * @param cb the callback to call to inform about habitability of the given host |
142 | */ | 160 | * @param cb_cls the closure for the callback |
143 | int | 161 | * @return NULL upon any error or a handle which can be passed to |
162 | * GNUNET_TESTBED_is_host_habitable_cancel() | ||
163 | */ | ||
164 | struct GNUNET_TESTBED_HostHabitableCheckHandle * | ||
144 | GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, | 165 | GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, |
145 | const struct GNUNET_CONFIGURATION_Handle *config); | 166 | const struct GNUNET_CONFIGURATION_Handle |
167 | *config, | ||
168 | GNUNET_TESTBED_HostHabitableCallback cb, | ||
169 | void *cb_cls); | ||
146 | 170 | ||
147 | 171 | ||
148 | /** | 172 | /** |
173 | * Function to cancel a request started using GNUNET_TESTBED_is_host_habitable() | ||
174 | * | ||
175 | * @param struct handle the habitability check handle | ||
176 | */ | ||
177 | void | ||
178 | GNUNET_TESTBED_is_host_habitable_cancel (struct | ||
179 | GNUNET_TESTBED_HostHabitableCheckHandle | ||
180 | *handle); | ||
181 | |||
182 | /** | ||
149 | * Obtain the host's hostname. | 183 | * Obtain the host's hostname. |
150 | * | 184 | * |
151 | * @param host handle to the host, NULL means 'localhost' | 185 | * @param host handle to the host, NULL means 'localhost' |
diff --git a/src/testbed/gnunet-testbed-profiler.c b/src/testbed/gnunet-testbed-profiler.c index 083926cbf..9eaf702a3 100644 --- a/src/testbed/gnunet-testbed-profiler.c +++ b/src/testbed/gnunet-testbed-profiler.c | |||
@@ -153,6 +153,11 @@ struct DLLOperation *dll_op_tail; | |||
153 | struct GNUNET_TESTBED_Operation *topology_op; | 153 | struct GNUNET_TESTBED_Operation *topology_op; |
154 | 154 | ||
155 | /** | 155 | /** |
156 | * The handle for whether a host is habitable or not | ||
157 | */ | ||
158 | struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handles; | ||
159 | |||
160 | /** | ||
156 | * Abort task identifier | 161 | * Abort task identifier |
157 | */ | 162 | */ |
158 | static GNUNET_SCHEDULER_TaskIdentifier abort_task; | 163 | static GNUNET_SCHEDULER_TaskIdentifier abort_task; |
@@ -253,6 +258,14 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
253 | shutdown_task = GNUNET_SCHEDULER_NO_TASK; | 258 | shutdown_task = GNUNET_SCHEDULER_NO_TASK; |
254 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | 259 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) |
255 | GNUNET_SCHEDULER_cancel (abort_task); | 260 | GNUNET_SCHEDULER_cancel (abort_task); |
261 | if (NULL != hc_handles) | ||
262 | { | ||
263 | for (nhost = 0; nhost < num_hosts; nhost++) | ||
264 | if (NULL != hc_handles[num_hosts]) | ||
265 | GNUNET_TESTBED_is_host_habitable_cancel (hc_handles[num_hosts]); | ||
266 | GNUNET_free (hc_handles); | ||
267 | hc_handles = NULL; | ||
268 | } | ||
256 | if (GNUNET_SCHEDULER_NO_TASK != register_hosts_task) | 269 | if (GNUNET_SCHEDULER_NO_TASK != register_hosts_task) |
257 | GNUNET_SCHEDULER_cancel (register_hosts_task); | 270 | GNUNET_SCHEDULER_cancel (register_hosts_task); |
258 | if (NULL != reg_handle) | 271 | if (NULL != reg_handle) |
@@ -688,6 +701,35 @@ status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, int stat | |||
688 | 701 | ||
689 | 702 | ||
690 | /** | 703 | /** |
704 | * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to | ||
705 | * inform whether the given host is habitable or not. The Handle returned by | ||
706 | * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called | ||
707 | * | ||
708 | * @param cls NULL | ||
709 | * @param status GNUNET_YES if it is habitable; GNUNET_NO if not | ||
710 | */ | ||
711 | static void | ||
712 | host_habitable_cb (void *cls, int status) | ||
713 | { | ||
714 | struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handle = cls; | ||
715 | static unsigned int hosts_checked; | ||
716 | |||
717 | *hc_handle = NULL; | ||
718 | if (++hosts_checked < num_hosts) | ||
719 | return; | ||
720 | GNUNET_free (hc_handles); | ||
721 | hc_handles = NULL; | ||
722 | mc_proc = | ||
723 | GNUNET_TESTBED_controller_start (GNUNET_TESTBED_host_get_hostname_ | ||
724 | (hosts[0]), | ||
725 | hosts[0], | ||
726 | cfg, | ||
727 | status_cb, | ||
728 | NULL); | ||
729 | } | ||
730 | |||
731 | |||
732 | /** | ||
691 | * Main function that will be run by the scheduler. | 733 | * Main function that will be run by the scheduler. |
692 | * | 734 | * |
693 | * @param cls closure | 735 | * @param cls closure |
@@ -717,12 +759,22 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
717 | fprintf (stderr, _("No hosts loaded. Need at least one host\n")); | 759 | fprintf (stderr, _("No hosts loaded. Need at least one host\n")); |
718 | return; | 760 | return; |
719 | } | 761 | } |
762 | hc_handles = GNUNET_malloc (sizeof (struct | ||
763 | GNUNET_TESTBED_HostHabitableCheckHandle *) | ||
764 | * num_hosts); | ||
720 | for (nhost = 0; nhost < num_hosts; nhost++) | 765 | for (nhost = 0; nhost < num_hosts; nhost++) |
721 | { | 766 | { |
722 | if (GNUNET_YES != GNUNET_TESTBED_is_host_habitable (hosts[nhost], config)) | 767 | if (NULL == (hc_handles[nhost] = GNUNET_TESTBED_is_host_habitable (hosts[nhost], config, |
768 | &host_habitable_cb, | ||
769 | &hc_handles[nhost]))) | ||
723 | { | 770 | { |
724 | fprintf (stderr, _("Host %s cannot start testbed\n"), | 771 | fprintf (stderr, _("Host %s cannot start testbed\n"), |
725 | GNUNET_TESTBED_host_get_hostname_ (hosts[nhost])); | 772 | GNUNET_TESTBED_host_get_hostname_ (hosts[nhost])); |
773 | for (nhost = 0; nhost < num_hosts; nhost++) | ||
774 | if (NULL != hc_handles[num_hosts]) | ||
775 | GNUNET_TESTBED_is_host_habitable_cancel (hc_handles[num_hosts]); | ||
776 | GNUNET_free (hc_handles); | ||
777 | hc_handles = NULL; | ||
726 | break; | 778 | break; |
727 | } | 779 | } |
728 | } | 780 | } |
@@ -733,13 +785,6 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
733 | return; | 785 | return; |
734 | } | 786 | } |
735 | cfg = GNUNET_CONFIGURATION_dup (config); | 787 | cfg = GNUNET_CONFIGURATION_dup (config); |
736 | mc_proc = | ||
737 | GNUNET_TESTBED_controller_start (GNUNET_TESTBED_host_get_hostname_ | ||
738 | (hosts[0]), | ||
739 | hosts[0], | ||
740 | cfg, | ||
741 | status_cb, | ||
742 | NULL); | ||
743 | abort_task = | 788 | abort_task = |
744 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 789 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
745 | (GNUNET_TIME_UNIT_SECONDS, 5), &do_abort, | 790 | (GNUNET_TIME_UNIT_SECONDS, 5), &do_abort, |
diff --git a/src/testbed/test_testbed_api_3peers_3controllers.c b/src/testbed/test_testbed_api_3peers_3controllers.c index 3e75469ff..0bdcb6147 100644 --- a/src/testbed/test_testbed_api_3peers_3controllers.c +++ b/src/testbed/test_testbed_api_3peers_3controllers.c | |||
@@ -144,6 +144,11 @@ static struct GNUNET_CONFIGURATION_Handle *cfg2; | |||
144 | static struct GNUNET_TESTBED_Operation *common_operation; | 144 | static struct GNUNET_TESTBED_Operation *common_operation; |
145 | 145 | ||
146 | /** | 146 | /** |
147 | * The handle for whether a host is habitable or not | ||
148 | */ | ||
149 | struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle; | ||
150 | |||
151 | /** | ||
147 | * Abort task identifier | 152 | * Abort task identifier |
148 | */ | 153 | */ |
149 | static GNUNET_SCHEDULER_TaskIdentifier abort_task; | 154 | static GNUNET_SCHEDULER_TaskIdentifier abort_task; |
@@ -256,6 +261,8 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
256 | { | 261 | { |
257 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | 262 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) |
258 | GNUNET_SCHEDULER_cancel (abort_task); | 263 | GNUNET_SCHEDULER_cancel (abort_task); |
264 | if (NULL != hc_handle) | ||
265 | GNUNET_TESTBED_is_host_habitable_cancel (hc_handle); | ||
259 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == delayed_connect_task); | 266 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == delayed_connect_task); |
260 | if (NULL != reg_handle) | 267 | if (NULL != reg_handle) |
261 | GNUNET_TESTBED_cancel_registration (reg_handle); | 268 | GNUNET_TESTBED_cancel_registration (reg_handle); |
@@ -854,6 +861,23 @@ status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, int stat | |||
854 | 861 | ||
855 | 862 | ||
856 | /** | 863 | /** |
864 | * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to | ||
865 | * inform whether the given host is habitable or not. The Handle returned by | ||
866 | * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called | ||
867 | * | ||
868 | * @param cls NULL | ||
869 | * @param status GNUNET_YES if it is habitable; GNUNET_NO if not | ||
870 | */ | ||
871 | static void | ||
872 | host_habitable_cb (void *cls, int status) | ||
873 | { | ||
874 | hc_handle = NULL; | ||
875 | cp1 = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, | ||
876 | NULL); | ||
877 | } | ||
878 | |||
879 | |||
880 | /** | ||
857 | * Main run function. | 881 | * Main run function. |
858 | * | 882 | * |
859 | * @param cls NULL | 883 | * @param cls NULL |
@@ -872,7 +896,9 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
872 | abort_test(); | 896 | abort_test(); |
873 | return; | 897 | return; |
874 | } | 898 | } |
875 | if (GNUNET_YES != GNUNET_TESTBED_is_host_habitable (host, config)) | 899 | if (NULL == (hc_handle = GNUNET_TESTBED_is_host_habitable (host, config, |
900 | &host_habitable_cb, | ||
901 | NULL))) | ||
876 | { | 902 | { |
877 | GNUNET_TESTBED_host_destroy (host); | 903 | GNUNET_TESTBED_host_destroy (host); |
878 | host = NULL; | 904 | host = NULL; |
@@ -884,8 +910,6 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
884 | return; | 910 | return; |
885 | } | 911 | } |
886 | cfg = GNUNET_CONFIGURATION_dup (config); | 912 | cfg = GNUNET_CONFIGURATION_dup (config); |
887 | cp1 = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, | ||
888 | NULL); | ||
889 | abort_task = | 913 | abort_task = |
890 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 914 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
891 | (GNUNET_TIME_UNIT_MINUTES, 3), &do_abort, | 915 | (GNUNET_TIME_UNIT_MINUTES, 3), &do_abort, |
diff --git a/src/testbed/test_testbed_api_controllerlink.c b/src/testbed/test_testbed_api_controllerlink.c index da9fd000b..3867df27b 100644 --- a/src/testbed/test_testbed_api_controllerlink.c +++ b/src/testbed/test_testbed_api_controllerlink.c | |||
@@ -243,6 +243,11 @@ static struct GNUNET_TESTBED_Peer *slave2_peer; | |||
243 | static struct GNUNET_TESTBED_Peer *master_peer; | 243 | static struct GNUNET_TESTBED_Peer *master_peer; |
244 | 244 | ||
245 | /** | 245 | /** |
246 | * The handle for whether a host is habitable or not | ||
247 | */ | ||
248 | struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle; | ||
249 | |||
250 | /** | ||
246 | * Event mask | 251 | * Event mask |
247 | */ | 252 | */ |
248 | uint64_t event_mask; | 253 | uint64_t event_mask; |
@@ -264,6 +269,8 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
264 | { | 269 | { |
265 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | 270 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) |
266 | GNUNET_SCHEDULER_cancel (abort_task); | 271 | GNUNET_SCHEDULER_cancel (abort_task); |
272 | if (NULL != hc_handle) | ||
273 | GNUNET_TESTBED_is_host_habitable_cancel (hc_handle); | ||
267 | if (NULL != slave3) | 274 | if (NULL != slave3) |
268 | GNUNET_TESTBED_host_destroy (slave3); | 275 | GNUNET_TESTBED_host_destroy (slave3); |
269 | if (NULL != slave2) | 276 | if (NULL != slave2) |
@@ -632,6 +639,23 @@ status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, | |||
632 | 639 | ||
633 | 640 | ||
634 | /** | 641 | /** |
642 | * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to | ||
643 | * inform whether the given host is habitable or not. The Handle returned by | ||
644 | * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called | ||
645 | * | ||
646 | * @param cls NULL | ||
647 | * @param status GNUNET_YES if it is habitable; GNUNET_NO if not | ||
648 | */ | ||
649 | static void | ||
650 | host_habitable_cb (void *cls, int status) | ||
651 | { | ||
652 | hc_handle = NULL; | ||
653 | cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, | ||
654 | NULL); | ||
655 | } | ||
656 | |||
657 | |||
658 | /** | ||
635 | * Main run function. | 659 | * Main run function. |
636 | * | 660 | * |
637 | * @param cls NULL | 661 | * @param cls NULL |
@@ -645,7 +669,9 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
645 | { | 669 | { |
646 | host = GNUNET_TESTBED_host_create (NULL, NULL, 0); | 670 | host = GNUNET_TESTBED_host_create (NULL, NULL, 0); |
647 | GNUNET_assert (NULL != host); | 671 | GNUNET_assert (NULL != host); |
648 | if (GNUNET_YES != GNUNET_TESTBED_is_host_habitable (host, config)) | 672 | if (NULL == (hc_handle = GNUNET_TESTBED_is_host_habitable (host, config, |
673 | &host_habitable_cb, | ||
674 | NULL))) | ||
649 | { | 675 | { |
650 | GNUNET_TESTBED_host_destroy (host); | 676 | GNUNET_TESTBED_host_destroy (host); |
651 | host = NULL; | 677 | host = NULL; |
@@ -656,9 +682,7 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
656 | result = SUCCESS; | 682 | result = SUCCESS; |
657 | return; | 683 | return; |
658 | } | 684 | } |
659 | cfg = GNUNET_CONFIGURATION_dup (config); | 685 | cfg = GNUNET_CONFIGURATION_dup (config); |
660 | cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, | ||
661 | NULL); | ||
662 | abort_task = | 686 | abort_task = |
663 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 687 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply |
664 | (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, | 688 | (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, |
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c index 42b8e3864..e0455d316 100644 --- a/src/testbed/testbed_api_hosts.c +++ b/src/testbed/testbed_api_hosts.c | |||
@@ -482,74 +482,201 @@ GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host, | |||
482 | 482 | ||
483 | 483 | ||
484 | /** | 484 | /** |
485 | * The handle for whether a host is habitable or not | ||
486 | */ | ||
487 | struct GNUNET_TESTBED_HostHabitableCheckHandle | ||
488 | { | ||
489 | /* /\** */ | ||
490 | /* * The host to check */ | ||
491 | /* *\/ */ | ||
492 | /* const struct GNUNET_TESTBED_Host *host; */ | ||
493 | |||
494 | /* /\** */ | ||
495 | /* * the configuration handle to lookup the path of the testbed helper */ | ||
496 | /* *\/ */ | ||
497 | /* const struct GNUNET_CONFIGURATION_Handle *cfg; */ | ||
498 | |||
499 | /** | ||
500 | * The callback to call once we have the status | ||
501 | */ | ||
502 | GNUNET_TESTBED_HostHabitableCallback cb; | ||
503 | |||
504 | /** | ||
505 | * The callback closure | ||
506 | */ | ||
507 | void *cb_cls; | ||
508 | |||
509 | /** | ||
510 | * The process handle for the SSH process | ||
511 | */ | ||
512 | struct GNUNET_OS_Process *auxp; | ||
513 | |||
514 | /** | ||
515 | * The SSH destination address string | ||
516 | */ | ||
517 | char *ssh_addr; | ||
518 | |||
519 | /** | ||
520 | * The destination port string | ||
521 | */ | ||
522 | char *portstr; | ||
523 | |||
524 | /** | ||
525 | * The path for hte testbed helper binary | ||
526 | */ | ||
527 | char *helper_binary_path; | ||
528 | |||
529 | /** | ||
530 | * Task id for the habitability check task | ||
531 | */ | ||
532 | GNUNET_SCHEDULER_TaskIdentifier habitability_check_task; | ||
533 | |||
534 | /** | ||
535 | * How long we wait before checking the process status. Should grow | ||
536 | * exponentially | ||
537 | */ | ||
538 | struct GNUNET_TIME_Relative wait_time; | ||
539 | |||
540 | }; | ||
541 | |||
542 | |||
543 | /** | ||
544 | * Task for checking whether a host is habitable or not | ||
545 | * | ||
546 | * @param cls GNUNET_TESTBED_HostHabitableCheckHandle | ||
547 | * @param tc the scheduler task context | ||
548 | */ | ||
549 | static void | ||
550 | habitability_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
551 | { | ||
552 | struct GNUNET_TESTBED_HostHabitableCheckHandle *h = cls; | ||
553 | void *cb_cls; | ||
554 | GNUNET_TESTBED_HostHabitableCallback cb; | ||
555 | unsigned long code; | ||
556 | enum GNUNET_OS_ProcessStatusType type; | ||
557 | int ret; | ||
558 | |||
559 | h->habitability_check_task = GNUNET_SCHEDULER_NO_TASK; | ||
560 | ret = GNUNET_OS_process_status (h->auxp, &type, &code); | ||
561 | if (GNUNET_SYSERR == ret) | ||
562 | { | ||
563 | GNUNET_break (0); | ||
564 | ret = GNUNET_NO; | ||
565 | goto call_cb; | ||
566 | } | ||
567 | if (GNUNET_NO == ret) | ||
568 | { | ||
569 | h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time); | ||
570 | h->habitability_check_task = | ||
571 | GNUNET_SCHEDULER_add_delayed (h->wait_time, | ||
572 | &habitability_check, h); | ||
573 | return; | ||
574 | } | ||
575 | GNUNET_OS_process_destroy (h->auxp); | ||
576 | h->auxp = NULL; | ||
577 | ret = (0 != code) ? GNUNET_NO : GNUNET_YES; | ||
578 | |||
579 | call_cb: | ||
580 | GNUNET_free (h->ssh_addr); | ||
581 | GNUNET_free (h->portstr); | ||
582 | GNUNET_free (h->helper_binary_path); | ||
583 | if (NULL != h->auxp) | ||
584 | GNUNET_OS_process_destroy (h->auxp); | ||
585 | cb = h->cb; | ||
586 | cb_cls = h->cb_cls; | ||
587 | GNUNET_free (h); | ||
588 | if (NULL != cb) | ||
589 | cb (cb_cls, ret); | ||
590 | } | ||
591 | |||
592 | |||
593 | /** | ||
485 | * Checks whether a host can be used to start testbed service | 594 | * Checks whether a host can be used to start testbed service |
486 | * | 595 | * |
487 | * @param host the host to check | 596 | * @param host the host to check |
488 | * @param config the configuration handle to lookup the path of the testbed helper | 597 | * @param config the configuration handle to lookup the path of the testbed |
489 | * @return GNUNET_YES if testbed service can be started on the given host | 598 | * helper |
490 | * remotely; GNUNET_NO if not | 599 | * @param cb the callback to call to inform about habitability of the given host |
600 | * @param cb_cls the closure for the callback | ||
601 | * @return NULL upon any error or a handle which can be passed to | ||
602 | * GNUNET_TESTBED_is_host_habitable_cancel() | ||
491 | */ | 603 | */ |
492 | int | 604 | struct GNUNET_TESTBED_HostHabitableCheckHandle * |
493 | GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, | 605 | GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, |
494 | const struct GNUNET_CONFIGURATION_Handle *config) | 606 | const struct GNUNET_CONFIGURATION_Handle |
607 | *config, | ||
608 | GNUNET_TESTBED_HostHabitableCallback cb, | ||
609 | void *cb_cls) | ||
495 | { | 610 | { |
611 | struct GNUNET_TESTBED_HostHabitableCheckHandle *h; | ||
496 | char *remote_args[11]; | 612 | char *remote_args[11]; |
497 | char *helper_binary_path; | ||
498 | char *portstr; | ||
499 | char *ssh_addr; | ||
500 | const char *hostname; | 613 | const char *hostname; |
501 | struct GNUNET_OS_Process *auxp; | ||
502 | unsigned long code; | ||
503 | enum GNUNET_OS_ProcessStatusType type; | ||
504 | int ret; | ||
505 | unsigned int argp; | 614 | unsigned int argp; |
506 | 615 | ||
507 | portstr = NULL; | 616 | h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HostHabitableCheckHandle)); |
508 | ssh_addr = NULL; | 617 | h->cb = cb; |
618 | h->cb_cls = cb_cls; | ||
509 | hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname; | 619 | hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname; |
510 | if (NULL == host->username) | 620 | if (NULL == host->username) |
511 | ssh_addr = GNUNET_strdup (hostname); | 621 | h->ssh_addr = GNUNET_strdup (hostname); |
512 | else | 622 | else |
513 | GNUNET_asprintf (&ssh_addr, "%s@%s", host->username, hostname); | 623 | GNUNET_asprintf (&h->ssh_addr, "%s@%s", host->username, hostname); |
514 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (config, "testbed", | 624 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (config, "testbed", |
515 | "HELPER_BINARY_PATH", | 625 | "HELPER_BINARY_PATH", |
516 | &helper_binary_path)) | 626 | &h->helper_binary_path)) |
517 | helper_binary_path = GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY); | 627 | h->helper_binary_path = |
628 | GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY); | ||
518 | argp = 0; | 629 | argp = 0; |
519 | remote_args[argp++] = "ssh"; | 630 | remote_args[argp++] = "ssh"; |
520 | GNUNET_asprintf (&portstr, "%u", host->port); | 631 | GNUNET_asprintf (&h->portstr, "%u", host->port); |
521 | remote_args[argp++] = "-p"; | 632 | remote_args[argp++] = "-p"; |
522 | remote_args[argp++] = portstr; | 633 | remote_args[argp++] = h->portstr; |
523 | remote_args[argp++] = "-o"; | 634 | remote_args[argp++] = "-o"; |
524 | remote_args[argp++] = "BatchMode=yes"; | 635 | remote_args[argp++] = "BatchMode=yes"; |
525 | remote_args[argp++] = "-o"; | 636 | remote_args[argp++] = "-o"; |
526 | remote_args[argp++] = "NoHostAuthenticationForLocalhost=yes"; | 637 | remote_args[argp++] = "NoHostAuthenticationForLocalhost=yes"; |
527 | remote_args[argp++] = ssh_addr; | 638 | remote_args[argp++] = h->ssh_addr; |
528 | remote_args[argp++] = "stat"; | 639 | remote_args[argp++] = "stat"; |
529 | remote_args[argp++] = helper_binary_path; | 640 | remote_args[argp++] = h->helper_binary_path; |
530 | remote_args[argp++] = NULL; | 641 | remote_args[argp++] = NULL; |
531 | GNUNET_assert (argp == 11); | 642 | GNUNET_assert (argp == 11); |
532 | auxp = | 643 | h->auxp = |
533 | GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, NULL, | 644 | GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, NULL, |
534 | NULL, "ssh", remote_args); | 645 | NULL, "ssh", remote_args); |
535 | if (NULL == auxp) | 646 | if (NULL == h->auxp) |
536 | { | ||
537 | GNUNET_free (ssh_addr); | ||
538 | GNUNET_free (portstr); | ||
539 | return GNUNET_NO; | ||
540 | } | ||
541 | do | ||
542 | { | 647 | { |
543 | ret = GNUNET_OS_process_status (auxp, &type, &code); | 648 | GNUNET_break (0); /* Cannot exec SSH? */ |
544 | GNUNET_assert (GNUNET_SYSERR != ret); | 649 | GNUNET_free (h->ssh_addr); |
545 | (void) usleep (300); | 650 | GNUNET_free (h->portstr); |
651 | GNUNET_free (h->helper_binary_path); | ||
652 | GNUNET_free (h); | ||
653 | return NULL; | ||
546 | } | 654 | } |
547 | while (GNUNET_NO == ret); | 655 | h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time); |
548 | GNUNET_OS_process_destroy (auxp); | 656 | h->habitability_check_task = |
549 | GNUNET_free (ssh_addr); | 657 | GNUNET_SCHEDULER_add_delayed (h->wait_time, |
550 | GNUNET_free (portstr); | 658 | &habitability_check, h); |
551 | GNUNET_free (helper_binary_path); | 659 | return h; |
552 | return (0 != code) ? GNUNET_NO : GNUNET_YES; | ||
553 | } | 660 | } |
554 | 661 | ||
662 | |||
663 | /** | ||
664 | * Function to cancel a request started using GNUNET_TESTBED_is_host_habitable() | ||
665 | * | ||
666 | * @param struct handle the habitability check handle | ||
667 | */ | ||
668 | void | ||
669 | GNUNET_TESTBED_is_host_habitable_cancel (struct | ||
670 | GNUNET_TESTBED_HostHabitableCheckHandle | ||
671 | *handle) | ||
672 | { | ||
673 | GNUNET_SCHEDULER_cancel (handle->habitability_check_task); | ||
674 | (void) GNUNET_OS_process_kill (handle->auxp, SIGTERM); | ||
675 | (void) GNUNET_OS_process_wait (handle->auxp); | ||
676 | GNUNET_OS_process_destroy (handle->auxp); | ||
677 | GNUNET_free (handle->ssh_addr); | ||
678 | GNUNET_free (handle->portstr); | ||
679 | GNUNET_free (handle->helper_binary_path); | ||
680 | GNUNET_free (handle); | ||
681 | } | ||
555 | /* end of testbed_api_hosts.c */ | 682 | /* end of testbed_api_hosts.c */ |
diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index 61dc5e741..05debd98c 100644 --- a/src/testbed/testbed_api_testbed.c +++ b/src/testbed/testbed_api_testbed.c | |||
@@ -969,23 +969,23 @@ GNUNET_TESTBED_create_va (struct GNUNET_TESTBED_Controller *controller, | |||
969 | enum GNUNET_TESTBED_TopologyOption underlay_topology, | 969 | enum GNUNET_TESTBED_TopologyOption underlay_topology, |
970 | va_list va) | 970 | va_list va) |
971 | { | 971 | { |
972 | unsigned int nhost; | 972 | /* unsigned int nhost; */ |
973 | 973 | ||
974 | GNUNET_assert (underlay_topology < GNUNET_TESTBED_TOPOLOGY_NONE); | 974 | /* GNUNET_assert (underlay_topology < GNUNET_TESTBED_TOPOLOGY_NONE); */ |
975 | if (num_hosts != 0) | 975 | /* if (num_hosts != 0) */ |
976 | { | 976 | /* { */ |
977 | for (nhost = 0; nhost < num_hosts; nhost++) | 977 | /* for (nhost = 0; nhost < num_hosts; nhost++) */ |
978 | { | 978 | /* { */ |
979 | if (GNUNET_YES != GNUNET_TESTBED_is_host_habitable (hosts[nhost], cfg)) | 979 | /* if (GNUNET_YES != GNUNET_TESTBED_is_host_habitable (hosts[nhost], cfg)) */ |
980 | { | 980 | /* { */ |
981 | LOG (GNUNET_ERROR_TYPE_ERROR, _("Host %s cannot start testbed\n"), | 981 | /* LOG (GNUNET_ERROR_TYPE_ERROR, _("Host %s cannot start testbed\n"), */ |
982 | GNUNET_TESTBED_host_get_hostname_ (hosts[nhost])); | 982 | /* GNUNET_TESTBED_host_get_hostname_ (hosts[nhost])); */ |
983 | break; | 983 | /* break; */ |
984 | } | 984 | /* } */ |
985 | } | 985 | /* } */ |
986 | if (num_hosts != nhost) | 986 | /* if (num_hosts != nhost) */ |
987 | return NULL; | 987 | /* return NULL; */ |
988 | } | 988 | /* } */ |
989 | /* We need controller callback here to get operation done events while | 989 | /* We need controller callback here to get operation done events while |
990 | linking hosts */ | 990 | linking hosts */ |
991 | GNUNET_break (0); | 991 | GNUNET_break (0); |