helper integration to GNUNET_TESTBED_host_run_()
authorSree Harsha Totakura <totakura@in.tum.de>
Tue, 17 Jul 2012 14:59:10 +0000 (14:59 +0000)
committerSree Harsha Totakura <totakura@in.tum.de>
Tue, 17 Jul 2012 14:59:10 +0000 (14:59 +0000)
todo: add controller start callback
 with the configuration with which the controller is started

src/include/gnunet_testbed_service.h
src/testbed/Makefile.am
src/testbed/gnunet-service-testbed.c
src/testbed/test_testbed_api.c
src/testbed/test_testbed_api_hosts.c
src/testbed/testbed_api.c
src/testbed/testbed_api_hosts.c
src/testbed/testbed_api_hosts.h

index 736a0c03c5da81b907da4343e227c079f3626f37..a190b67a729b91cff85a6da1be6bf37a7591df28 100644 (file)
@@ -414,14 +414,16 @@ typedef void (*GNUNET_TESTBED_ControllerErrorCallback)(void *cls,
 
 
 /**
- * Starts a controller process at the host
+ * Starts a controller process at the host. FIXME: add controller start callback
+ * with the configuration with which the controller is started
  *
- * @param system used for reserving ports if host is NULL and to determine
- *               which 'host' to set as TRUSTED ('controller') when starting testbed remotely
+ * @param controller_ip the ip address of the controller. Will be set as TRUSTED
+ *          host when starting testbed controller at host
  * @param host the host where the controller has to be started; NULL for localhost
- * @param cfg template configuration to use for the remote controller; will
- *            be modified to contain the actual host/port/unixpath used for
- *            the testbed service
+ * @param cfg template configuration to use for the remote controller; the
+ *          remote controller will be started with a slightly modified
+ *          configuration (port numbers, unix domain sockets and service home
+ *          values are changed as per TESTING library on the remote host)
  * @param cec function called if the contoller dies unexpectedly; will not be 
  *            invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called,
  *            GNUNET_TESTBED_controller_stop must no longer be called; will
@@ -431,9 +433,9 @@ typedef void (*GNUNET_TESTBED_ControllerErrorCallback)(void *cls,
  * @return the controller process handle, NULL on errors
  */
 struct GNUNET_TESTBED_ControllerProc *
-GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
+GNUNET_TESTBED_controller_start (const char *controller_ip,
                                 struct GNUNET_TESTBED_Host *host,
-                                struct GNUNET_CONFIGURATION_Handle *cfg,
+                                const struct GNUNET_CONFIGURATION_Handle *cfg,
                                 GNUNET_TESTBED_ControllerErrorCallback cec,
                                 void *cec_cls);
 
index 5af5b94dc7ab50969ae05d6131cf97e3374fc417..80e6b9e3dc2131ccf3fa82eefff4e205d8382b51 100644 (file)
@@ -69,9 +69,8 @@ check_PROGRAMS = \
 
 if ENABLE_TEST_RUN
  TESTS = \
-   test_testbed_api_hosts \
-   test_testbed_api \
-   test_gnunet_testbed_helper
+  test_testbed_api_hosts \
+  test_gnunet_testbed_helper
 endif
 
 test_testbed_api_hosts_SOURCES = \
index fabfe1691f59fb5bb90f49f667b285a8c914a999..3908af14a03e04d848f11395ec9f16310dea5fea 100644 (file)
@@ -55,6 +55,16 @@ struct Context
    * The client handle associated with this context
    */
   struct GNUNET_SERVER_Client *client;
+
+  /**
+   * The network address of the master controller
+   */
+  char *master_ip;
+
+  /**
+   * The TESTING system handle for starting peers locally
+   */
+  struct GNUNET_TESTING_System *system;
   
   /**
    * Event mask of event to be responded in this context
@@ -380,11 +390,6 @@ static GNUNET_SCHEDULER_TaskIdentifier shutdown_task_id;
 /* Testing System */
 /******************/
 
-/**
- * Handle to the local testing system - for starting peers locally
- */
-static struct GNUNET_TESTING_System *test_system;
-
 /**
  * Our configuration; we also use this as template for starting other controllers
  */
@@ -733,6 +738,8 @@ handle_init (void *cls,
 {
   const struct GNUNET_TESTBED_InitMessage *msg;
   struct GNUNET_TESTBED_Host *host;
+  void *addr;
+  size_t addrlen;
 
   if (NULL != master_context)
   {
@@ -744,6 +751,18 @@ handle_init (void *cls,
   master_context = GNUNET_malloc (sizeof (struct Context));
   master_context->client = client;
   master_context->host_id = ntohl (msg->host_id);
+  GNUNET_assert (GNUNET_OK == 
+                GNUNET_SERVER_client_get_address (client, &addr, &addrlen));
+  master_context->master_ip = GNUNET_malloc (NI_MAXHOST);
+  if (0 != getnameinfo (addr, addrlen, master_context->master_ip, NI_MAXHOST,
+                       NULL, 0, NI_NUMERICHOST))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Cannot determine the ip of master controller: %s\n", STRERROR (errno));
+    GNUNET_assert (0);
+  }
+  master_context->system = 
+    GNUNET_TESTING_system_create ("testbed", master_context->master_ip);
   host = GNUNET_TESTBED_host_create_with_id (master_context->host_id,
                                              NULL, NULL, 0);
   host_list_add (host);
@@ -1037,7 +1056,7 @@ handle_link_controllers (void *cls,
     if (1 == msg->is_subordinate)
     {
       slave->controller_proc =
-        GNUNET_TESTBED_controller_start (test_system,
+        GNUNET_TESTBED_controller_start (master_context->master_ip,
                                         host_list[delegated_host_id],
                                         cfg, &slave_shutdown_handler,
                                         slave);
@@ -1165,7 +1184,7 @@ handle_peer_create (void *cls,
     peer->cfg = cfg;
     peer->id = ntohl (msg->peer_id);
     LOG_DEBUG ("Creating peer with id: %u\n", peer->id);
-    peer->peer = GNUNET_TESTING_peer_configure (test_system, peer->cfg,
+    peer->peer = GNUNET_TESTING_peer_configure (master_context->system, peer->cfg,
                                                 peer->id,
                                                 NULL /* Peer id */,
                                                 &emsg);
@@ -1282,8 +1301,7 @@ shutdown_task (void *cls,
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n");
   (void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator,
                                                 NULL);
-  GNUNET_CONTAINER_multihashmap_destroy (ss_map);
-  GNUNET_TESTING_system_destroy (test_system, GNUNET_YES);
+  GNUNET_CONTAINER_multihashmap_destroy (ss_map);  
   if (NULL != fh)
   {
     GNUNET_DISK_file_close (fh);
@@ -1335,6 +1353,9 @@ shutdown_task (void *cls,
       if (NULL != slave_list[id]->controller_proc)
         GNUNET_TESTBED_controller_stop (slave_list[id]->controller_proc);
     }
+  GNUNET_free_non_null (master_context->master_ip);
+  if (NULL != master_context->system)
+    GNUNET_TESTING_system_destroy (master_context->system, GNUNET_YES);
   GNUNET_free_non_null (master_context);
 }
 
@@ -1413,12 +1434,10 @@ testbed_run (void *cls,
                                    &client_disconnect_cb,
                                    NULL);
   ss_map = GNUNET_CONTAINER_multihashmap_create (5);
-  test_system = GNUNET_TESTING_system_create ("testbed", NULL);
-  
   fh = GNUNET_DISK_get_handle_from_native (stdin);
   if (NULL == fh)
     shutdown_task_id = 
-      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,                                 
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
                                    &shutdown_task,
                                    NULL);
   else
index 849f5ddd435f1beb693389e314c1c631af4d9d1c..9bdae1fb0d5a4182c6529a643077d4d06b687e11 100644 (file)
 #define TIME_REL_SECS(sec) \
   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
 
-/**
- * The testing system we work with
- */
-struct GNUNET_TESTING_System *test_system;
-
 /**
  * Our localhost
  */
@@ -117,7 +112,6 @@ do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
     GNUNET_TESTBED_controller_stop (cp);
   GNUNET_TESTBED_host_destroy (neighbour);
   GNUNET_TESTBED_host_destroy (host);
-  GNUNET_TESTING_system_destroy (test_system, GNUNET_YES);
 }
 
 
@@ -190,12 +184,10 @@ run (void *cls, char *const *args, const char *cfgfile,
 {
   uint64_t event_mask;
 
-  test_system = GNUNET_TESTING_system_create ("test_testbed", 
-                                             "127.0.0.1");
   host = GNUNET_TESTBED_host_create (NULL, NULL, 0);
   GNUNET_assert (NULL != host);
   cfg = GNUNET_CONFIGURATION_dup (config);
-  cp = GNUNET_TESTBED_controller_start (test_system, host, cfg, NULL, NULL);
+  cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, NULL, NULL);
   event_mask = 0;
   event_mask |= (1L << GNUNET_TESTBED_ET_PEER_START);
   event_mask |= (1L << GNUNET_TESTBED_ET_PEER_STOP);
index 340e2491a6f7f7abcf2e6865aace086d83c86102..add3a1e0259e7a0b53fb64d43f14f9127112def0 100644 (file)
@@ -43,6 +43,15 @@ static struct GNUNET_TESTBED_Host *host;
  */
 static struct GNUNET_TESTBED_HelperHandle *helper_handle;
 
+/**
+ * Global test status
+ */
+static int status;
+
+/**
+ * Shutdown task identifier
+ */
+GNUNET_SCHEDULER_TaskIdentifier shutdown_id;
 
 /**
  * The shutdown task
@@ -58,6 +67,24 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 }
 
 
+/**
+ * Callback that will be called when the helper process dies. This is not called
+ * when the helper process is stoped using GNUNET_HELPER_stop()
+ *
+ * @param cls the closure from GNUNET_HELPER_start()
+ * @param h the handle representing the helper process. This handle is invalid
+ *          in this callback. It is only presented for reference. No operations
+ *          can be performed using it.
+ */
+static void 
+exp_cb (void *cls, const struct GNUNET_HELPER_Handle *h)
+{
+  status = GNUNET_SYSERR;
+  GNUNET_SCHEDULER_cancel (shutdown_id);
+  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+}
+
+
 /**
  * Main run function. 
  *
@@ -70,9 +97,6 @@ static void
 run (void *cls, char *const *args, const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  char *const binary_args[] = {"gnunet-service-testbed",
-                              NULL};
-
   host = GNUNET_TESTBED_host_create ("localhost", NULL, 0);
   GNUNET_assert (NULL != host);
   GNUNET_assert (0 != GNUNET_TESTBED_host_get_id_ (host));
@@ -81,16 +105,15 @@ run (void *cls, char *const *args, const char *cfgfile,
   GNUNET_assert (NULL != host);
   GNUNET_assert (0 == GNUNET_TESTBED_host_get_id_ (host));
   GNUNET_assert (host == GNUNET_TESTBED_host_lookup_by_id_ (0));
-  helper_handle = GNUNET_TESTBED_host_run_ (host, binary_args);
+  helper_handle = GNUNET_TESTBED_host_run_ ("127.0.0.1", host, cfg, &exp_cb, NULL);
   GNUNET_assert (NULL != helper_handle);
-  GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (1), &do_shutdown, NULL);
+  shutdown_id = 
+    GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (2), &do_shutdown, NULL);
 }
 
 
 int main (int argc, char **argv)
 {
-  int ret;
-
   char *const argv2[] = { "test_testbed_api_hosts",
                           "-c", "test_testbed_api.conf",
                           NULL
@@ -99,8 +122,11 @@ int main (int argc, char **argv)
     GNUNET_GETOPT_OPTION_END
   };
 
-  ret = GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
-                           "test_testbed_api_hosts", "nohelp", options, &run, NULL);
-
-  return GNUNET_OK == ret ? 0 : 1;
+  status = GNUNET_YES;
+  if (GNUNET_OK != 
+      GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
+                         "test_testbed_api_hosts", "nohelp", 
+                         options, &run, NULL))
+    return 1;
+  return (GNUNET_OK == status) ? 0 : 1;
 }
index d9aec6197f79d7af375763378d310f5a880987bb..7c443600347e6a457f48f7a23c542b197be0cc47 100644 (file)
@@ -439,26 +439,23 @@ struct GNUNET_TESTBED_ControllerProc
    * The closure for the above callback
    */
   void *cec_cls;
-
-  /**
-   * The task id of the task that will be called when controller dies
-   */
-  GNUNET_SCHEDULER_TaskIdentifier controller_dead_task_id;
 };
 
 
 /**
- * The task which is run when a controller dies (its stdout is closed)
+ * Callback that will be called when the helper process dies. This is not called
+ * when the helper process is stoped using GNUNET_HELPER_stop()
  *
- * @param cls the ControllerProc struct
- * @param tc the context
+ * @param cls the closure from GNUNET_HELPER_start()
+ * @param h the handle representing the helper process. This handle is invalid
+ *          in this callback. It is only presented for reference. No operations
+ *          can be performed using it.
  */
-static void
-controller_dead_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+static void 
+controller_exp_cb (void *cls, const struct GNUNET_HELPER_Handle *h)
 {
   struct GNUNET_TESTBED_ControllerProc *cproc = cls;
 
-  cproc->controller_dead_task_id = GNUNET_SCHEDULER_NO_TASK;
   if (NULL != cproc->cec)
     cproc->cec (cproc->cec_cls, NULL); /* FIXME: How to get the error message? */
 }
@@ -467,12 +464,13 @@ controller_dead_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 /**
  * Starts a controller process at the host
  *
- * @param system used for reserving ports if host is NULL and to determine
- *               which 'host' to set as TRUSTED ('controller') when starting testbed remotely
+ * @param controller_ip the ip address of the controller. Will be set as TRUSTED
+ *          host when starting testbed controller at host
  * @param host the host where the controller has to be started; NULL for localhost
- * @param cfg template configuration to use for the remote controller; will
- *            be modified to contain the actual host/port/unixpath used for
- *            the testbed service
+ * @param cfg template configuration to use for the remote controller; the
+ *          remote controller will be started with a slightly modified
+ *          configuration (port numbers, unix domain sockets and service home
+ *          values are changed as per TESTING library on the remote host)
  * @param cec function called if the contoller dies unexpectedly; will not be 
  *            invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called,
  *            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)
  * @return the controller process handle, NULL on errors
  */
 struct GNUNET_TESTBED_ControllerProc *
-GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
+GNUNET_TESTBED_controller_start (const char *controller_ip,
                                 struct GNUNET_TESTBED_Host *host,
-                                struct GNUNET_CONFIGURATION_Handle *cfg,
+                                const struct GNUNET_CONFIGURATION_Handle *cfg,
                                 GNUNET_TESTBED_ControllerErrorCallback cec,
                                 void *cec_cls)
 {
   struct GNUNET_TESTBED_ControllerProc *cproc;
-  const struct GNUNET_DISK_FileHandle *read_fh;
-  char *cfg_filename;
-
-  if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host)))
-  {
-    if (GNUNET_OK != GNUNET_TESTING_configuration_create (system, cfg))
-      return NULL;
-    GNUNET_assert 
-      (GNUNET_OK == 
-       GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "DEFAULTCONFIG",
-                                             &cfg_filename));
-    if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, cfg_filename))
-    {
-      GNUNET_break (0);
-      return NULL;
-    }
-    char * const binary_argv[] = {
-      "gnunet-service-testbed",
-      "-c", cfg_filename,
-      NULL
-    };
-    cproc = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
-    cproc->helper = GNUNET_TESTBED_host_run_ (host, binary_argv);
-    GNUNET_free (cfg_filename);
-    if (NULL == cproc->helper)
-    {
-      GNUNET_free (cproc);
-      return NULL;
-    }
-  }
-  else
+  
+  cproc = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_ControllerProc));
+  cproc->helper = GNUNET_TESTBED_host_run_ (controller_ip, host, cfg,
+                                           &controller_exp_cb, cproc);
+  if (NULL == cproc->helper)
   {
-    GNUNET_break (0); /* FIXME: start controller remotely */
+    GNUNET_free (cproc);
     return NULL;
   }
-  read_fh = GNUNET_DISK_pipe_handle (cproc->helper->cpipe_out,
-                                    GNUNET_DISK_PIPE_END_READ);
-  if (NULL == read_fh)
-  {
-    GNUNET_break (0); // we can't catch the process 
-  }
   cproc->cec = cec;
   cproc->cec_cls = cec_cls;
-  cproc->controller_dead_task_id =
-    GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, read_fh,
-                                   &controller_dead_task, cproc);
   return cproc;
 }
 
@@ -549,11 +512,6 @@ GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
 void
 GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc)
 {
-  if (GNUNET_SCHEDULER_NO_TASK != cproc->controller_dead_task_id)
-  {
-    GNUNET_SCHEDULER_cancel (cproc->controller_dead_task_id);
-    cproc->controller_dead_task_id = GNUNET_SCHEDULER_NO_TASK;
-  }
   GNUNET_TESTBED_host_stop_ (cproc->helper);
   GNUNET_free (cproc);
 }
index fd129283e4d47192d0b4502d0d9d128234a28b87..5fe525b9e8db73b4a0048e4191697c32eabedf1b 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "testbed_api.h"
 #include "testbed_api_hosts.h"
+#include "testbed_helper.h"
 
 /**
  * Generic logging shorthand
@@ -336,47 +337,87 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host)
 }
 
 
+/**
+ * Continuation function from GNUNET_HELPER_send()
+ * 
+ * @param cls closure
+ * @param result GNUNET_OK on success,
+ *               GNUNET_NO if helper process died
+ *               GNUNET_SYSERR during GNUNET_HELPER_stop
+ */
+static void 
+clear_msg (void *cls, int result)
+{
+  GNUNET_free (cls);
+}
+
+
+/**
+ * Callback that will be called when the helper process dies. This is not called
+ * when the helper process is stoped using GNUNET_HELPER_stop()
+ *
+ * @param cls the closure from GNUNET_HELPER_start()
+ * @param h the handle representing the helper process. This handle is invalid
+ *          in this callback. It is only presented for reference. No operations
+ *          can be performed using it.
+ */
+static void 
+helper_exp_cb (void *cls, const struct GNUNET_HELPER_Handle *h)
+{
+  struct GNUNET_TESTBED_HelperHandle *handle = cls;
+
+  handle->is_stopped = GNUNET_YES;
+  GNUNET_TESTBED_host_stop_ (handle);
+  handle->exp_cb (handle->exp_cb_cls, h);
+}
+
+
 /**
  * Run a given helper process at the given host.  Communication
  * with the helper will be via GNUnet messages on stdin/stdout.
  * Runs the process via 'ssh' at the specified host, or locally.
  * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API.
  * 
+ * @param controller_ip the ip address of the controller. Will be set as TRUSTED
+ *          host when starting testbed controller at host
  * @param host host to use, use "NULL" for localhost
- * @param binary_argv binary name and command-line arguments to give to the binary
+ * @param binary_argv binary name and command-line arguments to give to the
+ *          binary
+ * @param cfg template configuration to use for the remote controller; the
+ *          remote controller will be started with a slightly modified
+ *          configuration (port numbers, unix domain sockets and service home
+ *          values are changed as per TESTING library on the remote host)
+ * @param cb the callback to run when helper process dies; cannot be NULL
+ * @param cb_cls the closure for the above callback
  * @return handle to terminate the command, NULL on error
  */
 struct GNUNET_TESTBED_HelperHandle *
-GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
-                         char *const binary_argv[])
+GNUNET_TESTBED_host_run_ (const char *controller_ip,
+                         const struct GNUNET_TESTBED_Host *host,
+                         const struct GNUNET_CONFIGURATION_Handle *cfg,
+                         GNUNET_HELPER_ExceptionCallback cb,
+                         void *cb_cls)
 {
-  struct GNUNET_TESTBED_HelperHandle *h;
-  unsigned int argc;
+  struct GNUNET_TESTBED_HelperHandle *h;  
+  struct GNUNET_TESTBED_HelperInit *msg;
 
-  argc = 0;
-  while (NULL != binary_argv[argc]) 
-    argc++;
+  GNUNET_assert (NULL != cb);
   h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle));
-  h->cpipe_in = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
-  h->cpipe_out = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_YES);
-  if ((NULL == h->cpipe_in) || (NULL == h->cpipe_out))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                        "pipe");
-    GNUNET_free (h);
-    return NULL;
-  }
+  h->exp_cb = cb;
+  h->exp_cb_cls = cb_cls;
+  h->is_stopped = GNUNET_NO;
   if ((NULL == host) || (0 == host->id))
   {
-    h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
-                                              GNUNET_OS_INHERIT_STD_ALL,
-                                             h->cpipe_in, h->cpipe_out,
-                                             "gnunet-service-testbed", 
-                                             binary_argv);
+    char * const binary_argv[] = {
+      "gnunet-testbed-helper", NULL
+    };
+
+    h->helper =
+      GNUNET_HELPER_start ("gnunet-testbed-helper", binary_argv, NULL, &helper_exp_cb, h);
   }
   else
   {
-    char *remote_args[argc + 6 + 1];
+    char *remote_args[6 + 1];
     unsigned int argp;
 
     GNUNET_asprintf (&h->port, "%d", host->port);
@@ -390,29 +431,22 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
     remote_args[argp++] = h->port;
     remote_args[argp++] = "-q";
     remote_args[argp++] = h->dst;
-    remote_args[argp++] = "gnunet-service-testbed";
-    while (NULL != binary_argv[argp-6])
-    {
-      remote_args[argp] = binary_argv[argp - 6];
-      argp++;
-    } 
+    remote_args[argp++] = "gnunet-testbed-helper";
     remote_args[argp++] = NULL;
-    GNUNET_assert (argp == argc + 6 + 1);
-    h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
-                                              GNUNET_OS_INHERIT_STD_ALL,
-                                             h->cpipe_in, NULL,
-                                             "ssh", 
-                                             remote_args);
+    GNUNET_assert (argp == 6 + 1);
+    h->helper = GNUNET_HELPER_start ("ssh", remote_args, NULL, &helper_exp_cb, h);
   }
-  if (NULL == h->process)
+  msg = GNUNET_TESTBED_create_helper_init_msg_ (controller_ip, cfg);
+  if ((NULL == h->helper) ||
+      (NULL == (h->helper_shandle = GNUNET_HELPER_send (h->helper, &msg->header, GNUNET_NO, 
+                                                       &clear_msg, msg))))
   {
-    GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe_in));
+    GNUNET_free (msg);
     GNUNET_free_non_null (h->port);
     GNUNET_free_non_null (h->dst);
     GNUNET_free (h);
     return NULL;
   } 
-  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close_end (h->cpipe_in, GNUNET_DISK_PIPE_END_READ));
   return h;
 }
 
@@ -425,11 +459,8 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
 void
 GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle)
 {
-  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe_in));
-  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe_out));
-  GNUNET_break (0 == GNUNET_OS_process_kill (handle->process, SIGTERM));
-  GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (handle->process));
-  GNUNET_OS_process_destroy (handle->process);
+  if (GNUNET_YES != handle->is_stopped)
+    GNUNET_HELPER_stop (handle->helper);
   GNUNET_free_non_null (handle->port);
   GNUNET_free_non_null (handle->dst);
   GNUNET_free (handle);
index cc88d78a317cbc9e4d36c9a8f19da1e2435dc8b2..21e9520e20aed3d4da5fd4a8d2e0de0d674e4fc0 100644 (file)
@@ -39,17 +39,12 @@ struct GNUNET_TESTBED_HelperHandle
   /**
    * The process handle
    */
-  struct GNUNET_OS_Process *process;
+  struct GNUNET_HELPER_Handle *helper;
 
   /**
-   * Pipe connecting to stdin of the process.
+   * The send handle for the helper
    */
-  struct GNUNET_DISK_PipeHandle *cpipe_in;
-
-  /**
-   * Pipe from the stdout of the process.
-   */
-  struct GNUNET_DISK_PipeHandle *cpipe_out;
+  struct GNUNET_HELPER_SendHandle *helper_shandle;
 
   /**
    * The port number for ssh; used for helpers starting ssh
@@ -59,7 +54,22 @@ struct GNUNET_TESTBED_HelperHandle
   /**
    * The ssh destination string; used for helpers starting ssh
    */
-  char *dst; 
+  char *dst;
+
+  /**
+   * The helper exception callback
+   */
+  GNUNET_HELPER_ExceptionCallback exp_cb;
+
+  /**
+   * The closure for exp_cb
+   */
+  void *exp_cb_cls;
+
+  /**
+   * Is the helper stopped?
+   */
+  int is_stopped;
 };
 
 
@@ -140,13 +150,25 @@ struct GNUNET_TESTBED_HelperHandle;
  * Runs the process via 'ssh' at the specified host, or locally.
  * Essentially an SSH-wrapper around the 'gnunet_helper_lib.h' API.
  * 
+ * @param controller_ip the ip address of the controller. Will be set as TRUSTED
+ *          host when starting testbed controller at host
  * @param host host to use, use "NULL" for localhost
- * @param binary_argv binary name and command-line arguments to give to the binary
+ * @param binary_argv binary name and command-line arguments to give to the
+ *          binary
+ * @param cfg template configuration to use for the remote controller; the
+ *          remote controller will be started with a slightly modified
+ *          configuration (port numbers, unix domain sockets and service home
+ *          values are changed as per TESTING library on the remote host)
+ * @param cb the callback to run when helper process dies; cannot be NULL
+ * @param cb_cls the closure for the above callback
  * @return handle to terminate the command, NULL on error
  */
 struct GNUNET_TESTBED_HelperHandle *
-GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
-                         char *const binary_argv[]);
+GNUNET_TESTBED_host_run_ (const char *controller_ip,
+                         const struct GNUNET_TESTBED_Host *host,
+                         const struct GNUNET_CONFIGURATION_Handle *cfg,
+                         GNUNET_HELPER_ExceptionCallback cb,
+                         void *cb_cls);
 
 
 /**
@@ -193,7 +215,7 @@ GNUNET_TESTBED_is_host_registered_ (const struct GNUNET_TESTBED_Host *host,
  */
 struct GNUNET_TESTBED_HelperInit *
 GNUNET_TESTBED_create_helper_init_msg_ (const char *cname,
-                                        const struct GNUNET_CONFIGURATION_Handle *cfg);
+                                       const struct GNUNET_CONFIGURATION_Handle *cfg);