summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_testbed_service.h46
-rw-r--r--src/testbed/gnunet-testbed-profiler.c63
-rw-r--r--src/testbed/test_testbed_api_3peers_3controllers.c30
-rw-r--r--src/testbed/test_testbed_api_controllerlink.c32
-rw-r--r--src/testbed/testbed_api_hosts.c205
-rw-r--r--src/testbed/testbed_api_testbed.c34
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 */
138struct 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 */
149typedef 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
143int 161 * @return NULL upon any error or a handle which can be passed to
162 * GNUNET_TESTBED_is_host_habitable_cancel()
163 */
164struct GNUNET_TESTBED_HostHabitableCheckHandle *
144GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, 165GNUNET_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 */
177void
178GNUNET_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;
153struct GNUNET_TESTBED_Operation *topology_op; 153struct GNUNET_TESTBED_Operation *topology_op;
154 154
155/** 155/**
156 * The handle for whether a host is habitable or not
157 */
158struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handles;
159
160/**
156 * Abort task identifier 161 * Abort task identifier
157 */ 162 */
158static GNUNET_SCHEDULER_TaskIdentifier abort_task; 163static 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 */
711static void
712host_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;
144static struct GNUNET_TESTBED_Operation *common_operation; 144static struct GNUNET_TESTBED_Operation *common_operation;
145 145
146/** 146/**
147 * The handle for whether a host is habitable or not
148 */
149struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle;
150
151/**
147 * Abort task identifier 152 * Abort task identifier
148 */ 153 */
149static GNUNET_SCHEDULER_TaskIdentifier abort_task; 154static 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 */
871static void
872host_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;
243static struct GNUNET_TESTBED_Peer *master_peer; 243static struct GNUNET_TESTBED_Peer *master_peer;
244 244
245/** 245/**
246 * The handle for whether a host is habitable or not
247 */
248struct GNUNET_TESTBED_HostHabitableCheckHandle *hc_handle;
249
250/**
246 * Event mask 251 * Event mask
247 */ 252 */
248uint64_t event_mask; 253uint64_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 */
649static void
650host_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 */
487struct 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 */
549static void
550habitability_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 */
492int 604struct GNUNET_TESTBED_HostHabitableCheckHandle *
493GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host, 605GNUNET_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 */
668void
669GNUNET_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);