aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-07-17 14:59:10 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-07-17 14:59:10 +0000
commiteb3f4006fc74ef71296e53d83b1d4b6990b639d1 (patch)
tree39704da526a6107925ebec9684d6a1e7d65f6e4e /src/testbed
parent90b5375e31986484f5007ec62c57f455bb8178dc (diff)
downloadgnunet-eb3f4006fc74ef71296e53d83b1d4b6990b639d1.tar.gz
gnunet-eb3f4006fc74ef71296e53d83b1d4b6990b639d1.zip
helper integration to GNUNET_TESTBED_host_run_()
todo: add controller start callback with the configuration with which the controller is started
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/Makefile.am5
-rw-r--r--src/testbed/gnunet-service-testbed.c43
-rw-r--r--src/testbed/test_testbed_api.c10
-rw-r--r--src/testbed/test_testbed_api_hosts.c48
-rw-r--r--src/testbed/testbed_api.c86
-rw-r--r--src/testbed/testbed_api_hosts.c117
-rw-r--r--src/testbed/testbed_api_hosts.h48
7 files changed, 202 insertions, 155 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index 5af5b94dc..80e6b9e3d 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -69,9 +69,8 @@ check_PROGRAMS = \
69 69
70if ENABLE_TEST_RUN 70if ENABLE_TEST_RUN
71 TESTS = \ 71 TESTS = \
72 test_testbed_api_hosts \ 72 test_testbed_api_hosts \
73 test_testbed_api \ 73 test_gnunet_testbed_helper
74 test_gnunet_testbed_helper
75endif 74endif
76 75
77test_testbed_api_hosts_SOURCES = \ 76test_testbed_api_hosts_SOURCES = \
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index fabfe1691..3908af14a 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -55,6 +55,16 @@ struct Context
55 * The client handle associated with this context 55 * The client handle associated with this context
56 */ 56 */
57 struct GNUNET_SERVER_Client *client; 57 struct GNUNET_SERVER_Client *client;
58
59 /**
60 * The network address of the master controller
61 */
62 char *master_ip;
63
64 /**
65 * The TESTING system handle for starting peers locally
66 */
67 struct GNUNET_TESTING_System *system;
58 68
59 /** 69 /**
60 * Event mask of event to be responded in this context 70 * Event mask of event to be responded in this context
@@ -381,11 +391,6 @@ static GNUNET_SCHEDULER_TaskIdentifier shutdown_task_id;
381/******************/ 391/******************/
382 392
383/** 393/**
384 * Handle to the local testing system - for starting peers locally
385 */
386static struct GNUNET_TESTING_System *test_system;
387
388/**
389 * Our configuration; we also use this as template for starting other controllers 394 * Our configuration; we also use this as template for starting other controllers
390 */ 395 */
391static struct GNUNET_CONFIGURATION_Handle *config; 396static struct GNUNET_CONFIGURATION_Handle *config;
@@ -733,6 +738,8 @@ handle_init (void *cls,
733{ 738{
734 const struct GNUNET_TESTBED_InitMessage *msg; 739 const struct GNUNET_TESTBED_InitMessage *msg;
735 struct GNUNET_TESTBED_Host *host; 740 struct GNUNET_TESTBED_Host *host;
741 void *addr;
742 size_t addrlen;
736 743
737 if (NULL != master_context) 744 if (NULL != master_context)
738 { 745 {
@@ -744,6 +751,18 @@ handle_init (void *cls,
744 master_context = GNUNET_malloc (sizeof (struct Context)); 751 master_context = GNUNET_malloc (sizeof (struct Context));
745 master_context->client = client; 752 master_context->client = client;
746 master_context->host_id = ntohl (msg->host_id); 753 master_context->host_id = ntohl (msg->host_id);
754 GNUNET_assert (GNUNET_OK ==
755 GNUNET_SERVER_client_get_address (client, &addr, &addrlen));
756 master_context->master_ip = GNUNET_malloc (NI_MAXHOST);
757 if (0 != getnameinfo (addr, addrlen, master_context->master_ip, NI_MAXHOST,
758 NULL, 0, NI_NUMERICHOST))
759 {
760 LOG (GNUNET_ERROR_TYPE_WARNING,
761 "Cannot determine the ip of master controller: %s\n", STRERROR (errno));
762 GNUNET_assert (0);
763 }
764 master_context->system =
765 GNUNET_TESTING_system_create ("testbed", master_context->master_ip);
747 host = GNUNET_TESTBED_host_create_with_id (master_context->host_id, 766 host = GNUNET_TESTBED_host_create_with_id (master_context->host_id,
748 NULL, NULL, 0); 767 NULL, NULL, 0);
749 host_list_add (host); 768 host_list_add (host);
@@ -1037,7 +1056,7 @@ handle_link_controllers (void *cls,
1037 if (1 == msg->is_subordinate) 1056 if (1 == msg->is_subordinate)
1038 { 1057 {
1039 slave->controller_proc = 1058 slave->controller_proc =
1040 GNUNET_TESTBED_controller_start (test_system, 1059 GNUNET_TESTBED_controller_start (master_context->master_ip,
1041 host_list[delegated_host_id], 1060 host_list[delegated_host_id],
1042 cfg, &slave_shutdown_handler, 1061 cfg, &slave_shutdown_handler,
1043 slave); 1062 slave);
@@ -1165,7 +1184,7 @@ handle_peer_create (void *cls,
1165 peer->cfg = cfg; 1184 peer->cfg = cfg;
1166 peer->id = ntohl (msg->peer_id); 1185 peer->id = ntohl (msg->peer_id);
1167 LOG_DEBUG ("Creating peer with id: %u\n", peer->id); 1186 LOG_DEBUG ("Creating peer with id: %u\n", peer->id);
1168 peer->peer = GNUNET_TESTING_peer_configure (test_system, peer->cfg, 1187 peer->peer = GNUNET_TESTING_peer_configure (master_context->system, peer->cfg,
1169 peer->id, 1188 peer->id,
1170 NULL /* Peer id */, 1189 NULL /* Peer id */,
1171 &emsg); 1190 &emsg);
@@ -1282,8 +1301,7 @@ shutdown_task (void *cls,
1282 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n"); 1301 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n");
1283 (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator, 1302 (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator,
1284 NULL); 1303 NULL);
1285 GNUNET_CONTAINER_multihashmap_destroy (ss_map); 1304 GNUNET_CONTAINER_multihashmap_destroy (ss_map);
1286 GNUNET_TESTING_system_destroy (test_system, GNUNET_YES);
1287 if (NULL != fh) 1305 if (NULL != fh)
1288 { 1306 {
1289 GNUNET_DISK_file_close (fh); 1307 GNUNET_DISK_file_close (fh);
@@ -1335,6 +1353,9 @@ shutdown_task (void *cls,
1335 if (NULL != slave_list[id]->controller_proc) 1353 if (NULL != slave_list[id]->controller_proc)
1336 GNUNET_TESTBED_controller_stop (slave_list[id]->controller_proc); 1354 GNUNET_TESTBED_controller_stop (slave_list[id]->controller_proc);
1337 } 1355 }
1356 GNUNET_free_non_null (master_context->master_ip);
1357 if (NULL != master_context->system)
1358 GNUNET_TESTING_system_destroy (master_context->system, GNUNET_YES);
1338 GNUNET_free_non_null (master_context); 1359 GNUNET_free_non_null (master_context);
1339} 1360}
1340 1361
@@ -1413,12 +1434,10 @@ testbed_run (void *cls,
1413 &client_disconnect_cb, 1434 &client_disconnect_cb,
1414 NULL); 1435 NULL);
1415 ss_map = GNUNET_CONTAINER_multihashmap_create (5); 1436 ss_map = GNUNET_CONTAINER_multihashmap_create (5);
1416 test_system = GNUNET_TESTING_system_create ("testbed", NULL);
1417
1418 fh = GNUNET_DISK_get_handle_from_native (stdin); 1437 fh = GNUNET_DISK_get_handle_from_native (stdin);
1419 if (NULL == fh) 1438 if (NULL == fh)
1420 shutdown_task_id = 1439 shutdown_task_id =
1421 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 1440 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
1422 &shutdown_task, 1441 &shutdown_task,
1423 NULL); 1442 NULL);
1424 else 1443 else
diff --git a/src/testbed/test_testbed_api.c b/src/testbed/test_testbed_api.c
index 849f5ddd4..9bdae1fb0 100644
--- a/src/testbed/test_testbed_api.c
+++ b/src/testbed/test_testbed_api.c
@@ -43,11 +43,6 @@
43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) 43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
44 44
45/** 45/**
46 * The testing system we work with
47 */
48struct GNUNET_TESTING_System *test_system;
49
50/**
51 * Our localhost 46 * Our localhost
52 */ 47 */
53static struct GNUNET_TESTBED_Host *host; 48static struct GNUNET_TESTBED_Host *host;
@@ -117,7 +112,6 @@ do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
117 GNUNET_TESTBED_controller_stop (cp); 112 GNUNET_TESTBED_controller_stop (cp);
118 GNUNET_TESTBED_host_destroy (neighbour); 113 GNUNET_TESTBED_host_destroy (neighbour);
119 GNUNET_TESTBED_host_destroy (host); 114 GNUNET_TESTBED_host_destroy (host);
120 GNUNET_TESTING_system_destroy (test_system, GNUNET_YES);
121} 115}
122 116
123 117
@@ -190,12 +184,10 @@ run (void *cls, char *const *args, const char *cfgfile,
190{ 184{
191 uint64_t event_mask; 185 uint64_t event_mask;
192 186
193 test_system = GNUNET_TESTING_system_create ("test_testbed",
194 "127.0.0.1");
195 host = GNUNET_TESTBED_host_create (NULL, NULL, 0); 187 host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
196 GNUNET_assert (NULL != host); 188 GNUNET_assert (NULL != host);
197 cfg = GNUNET_CONFIGURATION_dup (config); 189 cfg = GNUNET_CONFIGURATION_dup (config);
198 cp = GNUNET_TESTBED_controller_start (test_system, host, cfg, NULL, NULL); 190 cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, NULL, NULL);
199 event_mask = 0; 191 event_mask = 0;
200 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START); 192 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
201 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP); 193 event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
diff --git a/src/testbed/test_testbed_api_hosts.c b/src/testbed/test_testbed_api_hosts.c
index 340e2491a..add3a1e02 100644
--- a/src/testbed/test_testbed_api_hosts.c
+++ b/src/testbed/test_testbed_api_hosts.c
@@ -43,6 +43,15 @@ static struct GNUNET_TESTBED_Host *host;
43 */ 43 */
44static struct GNUNET_TESTBED_HelperHandle *helper_handle; 44static struct GNUNET_TESTBED_HelperHandle *helper_handle;
45 45
46/**
47 * Global test status
48 */
49static int status;
50
51/**
52 * Shutdown task identifier
53 */
54GNUNET_SCHEDULER_TaskIdentifier shutdown_id;
46 55
47/** 56/**
48 * The shutdown task 57 * The shutdown task
@@ -59,6 +68,24 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
59 68
60 69
61/** 70/**
71 * Callback that will be called when the helper process dies. This is not called
72 * when the helper process is stoped using GNUNET_HELPER_stop()
73 *
74 * @param cls the closure from GNUNET_HELPER_start()
75 * @param h the handle representing the helper process. This handle is invalid
76 * in this callback. It is only presented for reference. No operations
77 * can be performed using it.
78 */
79static void
80exp_cb (void *cls, const struct GNUNET_HELPER_Handle *h)
81{
82 status = GNUNET_SYSERR;
83 GNUNET_SCHEDULER_cancel (shutdown_id);
84 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
85}
86
87
88/**
62 * Main run function. 89 * Main run function.
63 * 90 *
64 * @param cls NULL 91 * @param cls NULL
@@ -70,9 +97,6 @@ static void
70run (void *cls, char *const *args, const char *cfgfile, 97run (void *cls, char *const *args, const char *cfgfile,
71 const struct GNUNET_CONFIGURATION_Handle *cfg) 98 const struct GNUNET_CONFIGURATION_Handle *cfg)
72{ 99{
73 char *const binary_args[] = {"gnunet-service-testbed",
74 NULL};
75
76 host = GNUNET_TESTBED_host_create ("localhost", NULL, 0); 100 host = GNUNET_TESTBED_host_create ("localhost", NULL, 0);
77 GNUNET_assert (NULL != host); 101 GNUNET_assert (NULL != host);
78 GNUNET_assert (0 != GNUNET_TESTBED_host_get_id_ (host)); 102 GNUNET_assert (0 != GNUNET_TESTBED_host_get_id_ (host));
@@ -81,16 +105,15 @@ run (void *cls, char *const *args, const char *cfgfile,
81 GNUNET_assert (NULL != host); 105 GNUNET_assert (NULL != host);
82 GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host)); 106 GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host));
83 GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0)); 107 GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0));
84 helper_handle = GNUNET_TESTBED_host_run_ (host, binary_args); 108 helper_handle = GNUNET_TESTBED_host_run_ ("127.0.0.1", host, cfg, &exp_cb, NULL);
85 GNUNET_assert (NULL != helper_handle); 109 GNUNET_assert (NULL != helper_handle);
86 GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (1), &do_shutdown, NULL); 110 shutdown_id =
111 GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (2), &do_shutdown, NULL);
87} 112}
88 113
89 114
90int main (int argc, char **argv) 115int main (int argc, char **argv)
91{ 116{
92 int ret;
93
94 char *const argv2[] = { "test_testbed_api_hosts", 117 char *const argv2[] = { "test_testbed_api_hosts",
95 "-c", "test_testbed_api.conf", 118 "-c", "test_testbed_api.conf",
96 NULL 119 NULL
@@ -99,8 +122,11 @@ int main (int argc, char **argv)
99 GNUNET_GETOPT_OPTION_END 122 GNUNET_GETOPT_OPTION_END
100 }; 123 };
101 124
102 ret = GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, 125 status = GNUNET_YES;
103 "test_testbed_api_hosts", "nohelp", options, &run, NULL); 126 if (GNUNET_OK !=
104 127 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
105 return GNUNET_OK == ret ? 0 : 1; 128 "test_testbed_api_hosts", "nohelp",
129 options, &run, NULL))
130 return 1;
131 return (GNUNET_OK == status) ? 0 : 1;
106} 132}
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c
index d9aec6197..7c4436003 100644
--- a/src/testbed/testbed_api.c
+++ b/src/testbed/testbed_api.c
@@ -439,26 +439,23 @@ struct GNUNET_TESTBED_ControllerProc
439 * The closure for the above callback 439 * The closure for the above callback
440 */ 440 */
441 void *cec_cls; 441 void *cec_cls;
442
443 /**
444 * The task id of the task that will be called when controller dies
445 */
446 GNUNET_SCHEDULER_TaskIdentifier controller_dead_task_id;
447}; 442};
448 443
449 444
450/** 445/**
451 * The task which is run when a controller dies (its stdout is closed) 446 * Callback that will be called when the helper process dies. This is not called
447 * when the helper process is stoped using GNUNET_HELPER_stop()
452 * 448 *
453 * @param cls the ControllerProc struct 449 * @param cls the closure from GNUNET_HELPER_start()
454 * @param tc the context 450 * @param h the handle representing the helper process. This handle is invalid
451 * in this callback. It is only presented for reference. No operations
452 * can be performed using it.
455 */ 453 */
456static void 454static void
457controller_dead_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 455controller_exp_cb (void *cls, const struct GNUNET_HELPER_Handle *h)
458{ 456{
459 struct GNUNET_TESTBED_ControllerProc *cproc = cls; 457 struct GNUNET_TESTBED_ControllerProc *cproc = cls;
460 458
461 cproc->controller_dead_task_id = GNUNET_SCHEDULER_NO_TASK;
462 if (NULL != cproc->cec) 459 if (NULL != cproc->cec)
463 cproc->cec (cproc->cec_cls, NULL); /* FIXME: How to get the error message? */ 460 cproc->cec (cproc->cec_cls, NULL); /* FIXME: How to get the error message? */
464} 461}
@@ -467,12 +464,13 @@ controller_dead_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
467/** 464/**
468 * Starts a controller process at the host 465 * Starts a controller process at the host
469 * 466 *
470 * @param system used for reserving ports if host is NULL and to determine 467 * @param controller_ip the ip address of the controller. Will be set as TRUSTED
471 * which 'host' to set as TRUSTED ('controller') when starting testbed remotely 468 * host when starting testbed controller at host
472 * @param host the host where the controller has to be started; NULL for localhost 469 * @param host the host where the controller has to be started; NULL for localhost
473 * @param cfg template configuration to use for the remote controller; will 470 * @param cfg template configuration to use for the remote controller; the
474 * be modified to contain the actual host/port/unixpath used for 471 * remote controller will be started with a slightly modified
475 * the testbed service 472 * configuration (port numbers, unix domain sockets and service home
473 * values are changed as per TESTING library on the remote host)
476 * @param cec function called if the contoller dies unexpectedly; will not be 474 * @param cec function called if the contoller dies unexpectedly; will not be
477 * invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called, 475 * invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called,
478 * GNUNET_TESTBED_controller_stop must no longer be called; will 476 * GNUNET_TESTBED_controller_stop must no longer be called; will
@@ -482,59 +480,24 @@ controller_dead_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
482 * @return the controller process handle, NULL on errors 480 * @return the controller process handle, NULL on errors
483 */ 481 */
484struct GNUNET_TESTBED_ControllerProc * 482struct GNUNET_TESTBED_ControllerProc *
485GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system, 483GNUNET_TESTBED_controller_start (const char *controller_ip,
486 struct GNUNET_TESTBED_Host *host, 484 struct GNUNET_TESTBED_Host *host,
487 struct GNUNET_CONFIGURATION_Handle *cfg, 485 const struct GNUNET_CONFIGURATION_Handle *cfg,
488 GNUNET_TESTBED_ControllerErrorCallback cec, 486 GNUNET_TESTBED_ControllerErrorCallback cec,
489 void *cec_cls) 487 void *cec_cls)
490{ 488{
491 struct GNUNET_TESTBED_ControllerProc *cproc; 489 struct GNUNET_TESTBED_ControllerProc *cproc;
492 const struct GNUNET_DISK_FileHandle *read_fh; 490
493 char *cfg_filename; 491 cproc = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
494 492 cproc->helper = GNUNET_TESTBED_host_run_ (controller_ip, host, cfg,
495 if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host))) 493 &controller_exp_cb, cproc);
496 { 494 if (NULL == cproc->helper)
497 if (GNUNET_OK != GNUNET_TESTING_configuration_create (system, cfg))
498 return NULL;
499 GNUNET_assert
500 (GNUNET_OK ==
501 GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "DEFAULTCONFIG",
502 &cfg_filename));
503 if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, cfg_filename))
504 {
505 GNUNET_break (0);
506 return NULL;
507 }
508 char * const binary_argv[] = {
509 "gnunet-service-testbed",
510 "-c", cfg_filename,
511 NULL
512 };
513 cproc = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
514 cproc->helper = GNUNET_TESTBED_host_run_ (host, binary_argv);
515 GNUNET_free (cfg_filename);
516 if (NULL == cproc->helper)
517 {
518 GNUNET_free (cproc);
519 return NULL;
520 }
521 }
522 else
523 { 495 {
524 GNUNET_break (0); /* FIXME: start controller remotely */ 496 GNUNET_free (cproc);
525 return NULL; 497 return NULL;
526 } 498 }
527 read_fh = GNUNET_DISK_pipe_handle (cproc->helper->cpipe_out,
528 GNUNET_DISK_PIPE_END_READ);
529 if (NULL == read_fh)
530 {
531 GNUNET_break (0); // we can't catch the process
532 }
533 cproc->cec = cec; 499 cproc->cec = cec;
534 cproc->cec_cls = cec_cls; 500 cproc->cec_cls = cec_cls;
535 cproc->controller_dead_task_id =
536 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, read_fh,
537 &controller_dead_task, cproc);
538 return cproc; 501 return cproc;
539} 502}
540 503
@@ -549,11 +512,6 @@ GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
549void 512void
550GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc) 513GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc)
551{ 514{
552 if (GNUNET_SCHEDULER_NO_TASK != cproc->controller_dead_task_id)
553 {
554 GNUNET_SCHEDULER_cancel (cproc->controller_dead_task_id);
555 cproc->controller_dead_task_id = GNUNET_SCHEDULER_NO_TASK;
556 }
557 GNUNET_TESTBED_host_stop_ (cproc->helper); 515 GNUNET_TESTBED_host_stop_ (cproc->helper);
558 GNUNET_free (cproc); 516 GNUNET_free (cproc);
559} 517}
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c
index fd129283e..5fe525b9e 100644
--- a/src/testbed/testbed_api_hosts.c
+++ b/src/testbed/testbed_api_hosts.c
@@ -35,6 +35,7 @@
35 35
36#include "testbed_api.h" 36#include "testbed_api.h"
37#include "testbed_api_hosts.h" 37#include "testbed_api_hosts.h"
38#include "testbed_helper.h"
38 39
39/** 40/**
40 * Generic logging shorthand 41 * Generic logging shorthand
@@ -337,46 +338,86 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
337 338
338 339
339/** 340/**
341 * Continuation function from GNUNET_HELPER_send()
342 *
343 * @param cls closure
344 * @param result GNUNET_OK on success,
345 * GNUNET_NO if helper process died
346 * GNUNET_SYSERR during GNUNET_HELPER_stop
347 */
348static void
349clear_msg (void *cls, int result)
350{
351 GNUNET_free (cls);
352}
353
354
355/**
356 * Callback that will be called when the helper process dies. This is not called
357 * when the helper process is stoped using GNUNET_HELPER_stop()
358 *
359 * @param cls the closure from GNUNET_HELPER_start()
360 * @param h the handle representing the helper process. This handle is invalid
361 * in this callback. It is only presented for reference. No operations
362 * can be performed using it.
363 */
364static void
365helper_exp_cb (void *cls, const struct GNUNET_HELPER_Handle *h)
366{
367 struct GNUNET_TESTBED_HelperHandle *handle = cls;
368
369 handle->is_stopped = GNUNET_YES;
370 GNUNET_TESTBED_host_stop_ (handle);
371 handle->exp_cb (handle->exp_cb_cls, h);
372}
373
374
375/**
340 * Run a given helper process at the given host. Communication 376 * Run a given helper process at the given host. Communication
341 * with the helper will be via GNUnet messages on stdin/stdout. 377 * with the helper will be via GNUnet messages on stdin/stdout.
342 * Runs the process via 'ssh' at the specified host, or locally. 378 * Runs the process via 'ssh' at the specified host, or locally.
343 * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API. 379 * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API.
344 * 380 *
381 * @param controller_ip the ip address of the controller. Will be set as TRUSTED
382 * host when starting testbed controller at host
345 * @param host host to use, use "NULL" for localhost 383 * @param host host to use, use "NULL" for localhost
346 * @param binary_argv binary name and command-line arguments to give to the binary 384 * @param binary_argv binary name and command-line arguments to give to the
385 * binary
386 * @param cfg template configuration to use for the remote controller; the
387 * remote controller will be started with a slightly modified
388 * configuration (port numbers, unix domain sockets and service home
389 * values are changed as per TESTING library on the remote host)
390 * @param cb the callback to run when helper process dies; cannot be NULL
391 * @param cb_cls the closure for the above callback
347 * @return handle to terminate the command, NULL on error 392 * @return handle to terminate the command, NULL on error
348 */ 393 */
349struct GNUNET_TESTBED_HelperHandle * 394struct GNUNET_TESTBED_HelperHandle *
350GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host, 395GNUNET_TESTBED_host_run_ (const char *controller_ip,
351 char *const binary_argv[]) 396 const struct GNUNET_TESTBED_Host *host,
397 const struct GNUNET_CONFIGURATION_Handle *cfg,
398 GNUNET_HELPER_ExceptionCallback cb,
399 void *cb_cls)
352{ 400{
353 struct GNUNET_TESTBED_HelperHandle *h; 401 struct GNUNET_TESTBED_HelperHandle *h;
354 unsigned int argc; 402 struct GNUNET_TESTBED_HelperInit *msg;
355 403
356 argc = 0; 404 GNUNET_assert (NULL != cb);
357 while (NULL != binary_argv[argc])
358 argc++;
359 h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle)); 405 h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle));
360 h->cpipe_in = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); 406 h->exp_cb = cb;
361 h->cpipe_out = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_YES); 407 h->exp_cb_cls = cb_cls;
362 if ((NULL == h->cpipe_in) || (NULL == h->cpipe_out)) 408 h->is_stopped = GNUNET_NO;
363 {
364 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
365 "pipe");
366 GNUNET_free (h);
367 return NULL;
368 }
369 if ((NULL == host) || (0 == host->id)) 409 if ((NULL == host) || (0 == host->id))
370 { 410 {
371 h->process = GNUNET_OS_start_process_vap (GNUNET_YES, 411 char * const binary_argv[] = {
372 GNUNET_OS_INHERIT_STD_ALL, 412 "gnunet-testbed-helper", NULL
373 h->cpipe_in, h->cpipe_out, 413 };
374 "gnunet-service-testbed", 414
375 binary_argv); 415 h->helper =
416 GNUNET_HELPER_start ("gnunet-testbed-helper", binary_argv, NULL, &helper_exp_cb, h);
376 } 417 }
377 else 418 else
378 { 419 {
379 char *remote_args[argc + 6 + 1]; 420 char *remote_args[6 + 1];
380 unsigned int argp; 421 unsigned int argp;
381 422
382 GNUNET_asprintf (&h->port, "%d", host->port); 423 GNUNET_asprintf (&h->port, "%d", host->port);
@@ -390,29 +431,22 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
390 remote_args[argp++] = h->port; 431 remote_args[argp++] = h->port;
391 remote_args[argp++] = "-q"; 432 remote_args[argp++] = "-q";
392 remote_args[argp++] = h->dst; 433 remote_args[argp++] = h->dst;
393 remote_args[argp++] = "gnunet-service-testbed"; 434 remote_args[argp++] = "gnunet-testbed-helper";
394 while (NULL != binary_argv[argp-6])
395 {
396 remote_args[argp] = binary_argv[argp - 6];
397 argp++;
398 }
399 remote_args[argp++] = NULL; 435 remote_args[argp++] = NULL;
400 GNUNET_assert (argp == argc + 6 + 1); 436 GNUNET_assert (argp == 6 + 1);
401 h->process = GNUNET_OS_start_process_vap (GNUNET_YES, 437 h->helper = GNUNET_HELPER_start ("ssh", remote_args, NULL, &helper_exp_cb, h);
402 GNUNET_OS_INHERIT_STD_ALL,
403 h->cpipe_in, NULL,
404 "ssh",
405 remote_args);
406 } 438 }
407 if (NULL == h->process) 439 msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_ip, cfg);
440 if ((NULL == h->helper) ||
441 (NULL == (h->helper_shandle = GNUNET_HELPER_send (h->helper, &msg->header, GNUNET_NO,
442 &clear_msg, msg))))
408 { 443 {
409 GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe_in)); 444 GNUNET_free (msg);
410 GNUNET_free_non_null (h->port); 445 GNUNET_free_non_null (h->port);
411 GNUNET_free_non_null (h->dst); 446 GNUNET_free_non_null (h->dst);
412 GNUNET_free (h); 447 GNUNET_free (h);
413 return NULL; 448 return NULL;
414 } 449 }
415 GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close_end (h->cpipe_in, GNUNET_DISK_PIPE_END_READ));
416 return h; 450 return h;
417} 451}
418 452
@@ -425,11 +459,8 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
425void 459void
426GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle) 460GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle)
427{ 461{
428 GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe_in)); 462 if (GNUNET_YES != handle->is_stopped)
429 GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe_out)); 463 GNUNET_HELPER_stop (handle->helper);
430 GNUNET_break (0 == GNUNET_OS_process_kill (handle->process, SIGTERM));
431 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (handle->process));
432 GNUNET_OS_process_destroy (handle->process);
433 GNUNET_free_non_null (handle->port); 464 GNUNET_free_non_null (handle->port);
434 GNUNET_free_non_null (handle->dst); 465 GNUNET_free_non_null (handle->dst);
435 GNUNET_free (handle); 466 GNUNET_free (handle);
diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h
index cc88d78a3..21e9520e2 100644
--- a/src/testbed/testbed_api_hosts.h
+++ b/src/testbed/testbed_api_hosts.h
@@ -39,17 +39,12 @@ struct GNUNET_TESTBED_HelperHandle
39 /** 39 /**
40 * The process handle 40 * The process handle
41 */ 41 */
42 struct GNUNET_OS_Process *process; 42 struct GNUNET_HELPER_Handle *helper;
43 43
44 /** 44 /**
45 * Pipe connecting to stdin of the process. 45 * The send handle for the helper
46 */ 46 */
47 struct GNUNET_DISK_PipeHandle *cpipe_in; 47 struct GNUNET_HELPER_SendHandle *helper_shandle;
48
49 /**
50 * Pipe from the stdout of the process.
51 */
52 struct GNUNET_DISK_PipeHandle *cpipe_out;
53 48
54 /** 49 /**
55 * The port number for ssh; used for helpers starting ssh 50 * The port number for ssh; used for helpers starting ssh
@@ -59,7 +54,22 @@ struct GNUNET_TESTBED_HelperHandle
59 /** 54 /**
60 * The ssh destination string; used for helpers starting ssh 55 * The ssh destination string; used for helpers starting ssh
61 */ 56 */
62 char *dst; 57 char *dst;
58
59 /**
60 * The helper exception callback
61 */
62 GNUNET_HELPER_ExceptionCallback exp_cb;
63
64 /**
65 * The closure for exp_cb
66 */
67 void *exp_cb_cls;
68
69 /**
70 * Is the helper stopped?
71 */
72 int is_stopped;
63}; 73};
64 74
65 75
@@ -140,13 +150,25 @@ struct GNUNET_TESTBED_HelperHandle;
140 * Runs the process via 'ssh' at the specified host, or locally. 150 * Runs the process via 'ssh' at the specified host, or locally.
141 * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API. 151 * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API.
142 * 152 *
153 * @param controller_ip the ip address of the controller. Will be set as TRUSTED
154 * host when starting testbed controller at host
143 * @param host host to use, use "NULL" for localhost 155 * @param host host to use, use "NULL" for localhost
144 * @param binary_argv binary name and command-line arguments to give to the binary 156 * @param binary_argv binary name and command-line arguments to give to the
157 * binary
158 * @param cfg template configuration to use for the remote controller; the
159 * remote controller will be started with a slightly modified
160 * configuration (port numbers, unix domain sockets and service home
161 * values are changed as per TESTING library on the remote host)
162 * @param cb the callback to run when helper process dies; cannot be NULL
163 * @param cb_cls the closure for the above callback
145 * @return handle to terminate the command, NULL on error 164 * @return handle to terminate the command, NULL on error
146 */ 165 */
147struct GNUNET_TESTBED_HelperHandle * 166struct GNUNET_TESTBED_HelperHandle *
148GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host, 167GNUNET_TESTBED_host_run_ (const char *controller_ip,
149 char *const binary_argv[]); 168 const struct GNUNET_TESTBED_Host *host,
169 const struct GNUNET_CONFIGURATION_Handle *cfg,
170 GNUNET_HELPER_ExceptionCallback cb,
171 void *cb_cls);
150 172
151 173
152/** 174/**
@@ -193,7 +215,7 @@ GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host,
193 */ 215 */
194struct GNUNET_TESTBED_HelperInit * 216struct GNUNET_TESTBED_HelperInit *
195GNUNET_TESTBED_create_helper_init_msg_ (const char *cname, 217GNUNET_TESTBED_create_helper_init_msg_ (const char *cname,
196 const struct GNUNET_CONFIGURATION_Handle *cfg); 218 const struct GNUNET_CONFIGURATION_Handle *cfg);
197 219
198 220
199 221