gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r21990 - in gnunet/src: include testbed


From: gnunet
Subject: [GNUnet-SVN] r21990 - in gnunet/src: include testbed
Date: Thu, 14 Jun 2012 11:25:54 +0200

Author: grothoff
Date: 2012-06-14 11:25:54 +0200 (Thu, 14 Jun 2012)
New Revision: 21990

Modified:
   gnunet/src/include/gnunet_testbed_service.h
   gnunet/src/testbed/gnunet-service-testbed.c
   gnunet/src/testbed/testbed_api.c
   gnunet/src/testbed/testbed_api_hosts.c
   gnunet/src/testbed/testbed_api_hosts.h
Log:
-testbed hackery

Modified: gnunet/src/include/gnunet_testbed_service.h
===================================================================
--- gnunet/src/include/gnunet_testbed_service.h 2012-06-14 08:55:09 UTC (rev 
21989)
+++ gnunet/src/include/gnunet_testbed_service.h 2012-06-14 09:25:54 UTC (rev 
21990)
@@ -88,7 +88,27 @@
                            uint16_t port);
 
 
+
 /**
+ * Create a host to run peers and controllers on.  This function is used
+ * if a peer learns about a host via IPC between controllers (and thus 
+ * some higher-level controller has already determined the unique IDs).
+ * 
+ * @param id global host ID assigned to the host; 0 is
+ *        reserved to always mean 'localhost'
+ * @param hostname name of the host, use "NULL" for localhost
+ * @param username username to use for the login; may be NULL
+ * @param port port number to use for ssh; use 0 to let ssh decide
+ * @return handle to the host, NULL on error
+ */
+struct GNUNET_TESTBED_Host *
+GNUNET_TESTBED_host_create_with_id (uint32_t id,
+                                   const char *hostname,
+                                   const char *username,
+                                   uint16_t port);
+
+
+/**
  * Load a set of hosts from a configuration file.
  *
  * @param filename file with the host specification
@@ -785,7 +805,6 @@
                                           ...);
 
 
-
 /**
  * Ask the testbed controller to write the current overlay topology to
  * a file.  Naturally, the file will only contain a snapshot as the

Modified: gnunet/src/testbed/gnunet-service-testbed.c
===================================================================
--- gnunet/src/testbed/gnunet-service-testbed.c 2012-06-14 08:55:09 UTC (rev 
21989)
+++ gnunet/src/testbed/gnunet-service-testbed.c 2012-06-14 09:25:54 UTC (rev 
21990)
@@ -55,6 +55,11 @@
 
 
 /**
+ * Wrapped stdin.
+ */
+static struct GNUNET_DISK_FileHandle *fh;
+
+/**
  * The master context; generated with the first INIT message
  */
 static struct Context *master_context;
@@ -139,8 +144,13 @@
   host = GNUNET_TESTBED_host_create (hostname, username, ntohs
                                      (msg->ssh_port));
   /* Store host in a hashmap? But the host_id will be different */
+  /* hashmap? maybe array? 4-8 bytes/host and O(1) lookup vs.
+     > 80 bytes for hash map with slightly worse lookup; only
+     if we really get a tiny fraction of the hosts, the hash
+     map would result in any savings... (GNUNET_array_grow) */
 }
 
+
 /**
  * Task to clean up and shutdown nicely
  *
@@ -151,8 +161,16 @@
 shutdown_task (void *cls,
                const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  shutdown_task_id = GNUNET_SCHEDULER_NO_TASK;
+  GNUNET_SCHEDULER_shutdown ();
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n");
+  if (NULL != fh)
+  {
+    GNUNET_DISK_file_close (fh);
+    fh = NULL;
+  }
   GNUNET_free_non_null (master_context);
+  master_context = NULL;
 }
 
 
@@ -171,9 +189,12 @@
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Master client disconnected\n");
     GNUNET_SERVER_client_drop (client);
-    GNUNET_SCHEDULER_cancel (shutdown_task_id);    
-    shutdown_task_id = 
-      GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
+    /* should not be needed as we're terminated by failure to read
+       from stdin, but if stdin fails for some reason, this shouldn't 
+       hurt for now --- might need to revise this later if we ever
+       decide that master connections might be temporarily down 
+       for some reason */
+    GNUNET_SCHEDULER_shutdown ();
   }
 }
 
@@ -202,11 +223,19 @@
                               message_handlers);
   GNUNET_SERVER_disconnect_notify (server,
                                    &client_disconnect_cb,
-                                   NULL);
-  shutdown_task_id = 
-    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
-                                  &shutdown_task,
-                                  NULL);
+                                   NULL);  
+  fh = GNUNET_DISK_get_handle_from_native (stdin);
+  if (NULL == fh)
+    shutdown_task_id = 
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,              
                   
+                                   &shutdown_task,
+                                   NULL);
+  else
+    shutdown_task_id = 
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                     fh,
+                                     &shutdown_task,
+                                     NULL);
 }
 
 

Modified: gnunet/src/testbed/testbed_api.c
===================================================================
--- gnunet/src/testbed/testbed_api.c    2012-06-14 08:55:09 UTC (rev 21989)
+++ gnunet/src/testbed/testbed_api.c    2012-06-14 09:25:54 UTC (rev 21990)
@@ -123,10 +123,38 @@
    * The controller event mask
    */
   uint64_t event_mask;
+
+  /**
+   * Did we start the receive loop yet?
+   */
+  int in_receive;
 };
 
 
+
 /**
+ * Handler for messages from controller (testbed service)
+ *
+ * @param cls the controller handler
+ * @param msg message received, NULL on timeout or fatal error
+ */
+static void 
+message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
+{
+  struct GNUNET_TESTBED_Controller *c = cls;
+
+  /* FIXME: Add checks for message integrity */
+  switch (ntohs (msg->type))
+  {
+  default:
+    GNUNET_break (0);
+  }
+  GNUNET_CLIENT_receive (c->client, &message_handler, c,
+                         GNUNET_TIME_UNIT_FOREVER_REL);
+}
+
+
+/**
  * Function called to notify a client about the connection begin ready to queue
  * more data.  "buf" will be NULL and "size" zero if the connection was closed
  * for writing in the meantime.
@@ -159,6 +187,13 @@
                                            GNUNET_TIME_UNIT_FOREVER_REL,
                                            GNUNET_NO, &transmit_ready_notify,
                                            c);
+  if ( (GNUNET_NO == c->in_receive) &&
+       (size > 0) )
+  {
+    c->in_receive = GNUNET_YES;
+    GNUNET_CLIENT_receive (c->client, &message_handler, c,
+                          GNUNET_TIME_UNIT_FOREVER_REL);
+  }
   return size;
 }
 
@@ -198,61 +233,6 @@
 
 
 /**
- * Handler for messages from controller (testbed service)
- *
- * @param cls the controller handler
- * @param msg message received, NULL on timeout or fatal error
- */
-static void 
-message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
-{
-  struct GNUNET_TESTBED_Controller *c = cls;
-
-  /* FIXME: Add checks for message integrity */
-  switch (ntohs (msg->type))
-  {
-  default:
-    GNUNET_break (0);
-  }
-  GNUNET_CLIENT_receive (c->client, &message_handler, c,
-                         GNUNET_TIME_UNIT_FOREVER_REL);
-}
-
-
-/**
- * ?Callback for messages recevied from server? 
- *
- * Do not call GNUNET_SERVER_mst_destroy in callback
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- *
- * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
- */
-static int 
-server_mst_cb (void *cls, void *client,
-               const struct GNUNET_MessageHeader *message)
-{
-  struct GNUNET_TESTBED_Controller *c = cls;
-  struct GNUNET_TESTBED_InitMessage *msg;
-  
-  c->client = GNUNET_CLIENT_connect ("testbed", c->cfg);
-  if (NULL == c->client)
-    return GNUNET_SYSERR;       /* FIXME: Call controller startup_cb ? */
-  GNUNET_CLIENT_receive (c->client, &message_handler, c,
-                         GNUNET_TIME_UNIT_FOREVER_REL);
-  msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_InitMessage));
-  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_INIT);
-  msg->header.size = htons (sizeof (struct GNUNET_TESTBED_InitMessage));
-  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (c->host));
-  msg->event_mask = GNUNET_htonll (c->event_mask);
-  queue_message (c, (struct GNUNET_MessageHeader *) msg);
-  return GNUNET_OK;
-}
-
-
-/**
  * Start a controller process using the given configuration at the
  * given host.
  *
@@ -279,9 +259,10 @@
     "gnunet-service-testbed",
     NULL
   };
+  struct GNUNET_TESTBED_InitMessage *msg;
+
   controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller));
-  controller->helper = GNUNET_TESTBED_host_run_ (host, binary_argv,
-                                                &server_mst_cb, controller);
+  controller->helper = GNUNET_TESTBED_host_run_ (host, binary_argv);
   if (NULL == controller->helper)
   {
     GNUNET_free (controller);
@@ -292,6 +273,18 @@
   controller->cc_cls = cc_cls;
   controller->event_mask = event_mask;
   controller->cfg = GNUNET_CONFIGURATION_dup (cfg);
+  controller->client = GNUNET_CLIENT_connect ("testbed", controller->cfg);
+  if (NULL == controller->client)
+  {
+    GNUNET_TESTBED_controller_stop (controller);
+    return NULL;
+  }  
+  msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_InitMessage));
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_INIT);
+  msg->header.size = htons (sizeof (struct GNUNET_TESTBED_InitMessage));
+  msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (controller->host));
+  msg->event_mask = GNUNET_htonll (controller->event_mask);
+  queue_message (controller, (struct GNUNET_MessageHeader *) msg);
   return controller;
 }
 
@@ -338,7 +331,8 @@
     GNUNET_free (mq_entry->msg);
     GNUNET_free (mq_entry);
   }
-  GNUNET_CLIENT_disconnect (controller->client);
+  if (NULL != controller->client)
+    GNUNET_CLIENT_disconnect (controller->client);
   GNUNET_TESTBED_host_stop_ (controller->helper);
   GNUNET_CONFIGURATION_destroy (controller->cfg);
   GNUNET_free (controller);
@@ -391,6 +385,7 @@
 GNUNET_TESTBED_overlay_write_topology_to_file (struct 
GNUNET_TESTBED_Controller *controller,
                                               const char *filename)
 {
+  GNUNET_break (0);
 }
 
 

Modified: gnunet/src/testbed/testbed_api_hosts.c
===================================================================
--- gnunet/src/testbed/testbed_api_hosts.c      2012-06-14 08:55:09 UTC (rev 
21989)
+++ gnunet/src/testbed/testbed_api_hosts.c      2012-06-14 09:25:54 UTC (rev 
21990)
@@ -132,7 +132,7 @@
 uint32_t
 GNUNET_TESTBED_host_get_id_ (const struct GNUNET_TESTBED_Host *host)
 {
-    return host->unique_id;
+  return host->unique_id;
 }
 
 
@@ -147,10 +147,10 @@
  * @return handle to the host, NULL on error
  */
 struct GNUNET_TESTBED_Host *
-GNUNET_TESTBED_host_create_with_id_ (uint32_t id,
-                                    const char *hostname,
-                                    const char *username,
-                                    uint16_t port)
+GNUNET_TESTBED_host_create_with_id (uint32_t id,
+                                   const char *hostname,
+                                   const char *username,
+                                   uint16_t port)
 {
   struct GNUNET_TESTBED_Host *host;
 
@@ -180,10 +180,10 @@
   static uint32_t uid_generator;
 
   if (NULL == hostname)
-    return GNUNET_TESTBED_host_create_with_id_ (0, hostname, username, port);
-  return GNUNET_TESTBED_host_create_with_id_ (++uid_generator, 
-                                             hostname, username,
-                                             port);
+    return GNUNET_TESTBED_host_create_with_id (0, hostname, username, port);
+  return GNUNET_TESTBED_host_create_with_id (++uid_generator, 
+                                            hostname, username,
+                                            port);
 }
 
 
@@ -198,6 +198,7 @@
 GNUNET_TESTBED_hosts_load_from_file (const char *filename,
                                     struct GNUNET_TESTBED_Host **hosts)
 {
+  // see testing_group.c, GNUNET_TESTING_hosts_load
   GNUNET_break (0);
   return 0;
 }
@@ -223,11 +224,16 @@
 struct GNUNET_TESTBED_HelperHandle
 {
   /**
-   * The helper handle
+   * The process handle
    */
-  struct GNUNET_HELPER_Handle *handle;
+  struct GNUNET_OS_Process *process;
 
   /**
+   * Pipe connecting to stdin of the process.
+   */
+  struct GNUNET_DISK_PipeHandle *cpipe;
+
+  /**
    * The port number for ssh; used for helpers starting ssh
    */
   char *port;
@@ -247,39 +253,62 @@
  * 
  * @param host host to use, use "NULL" for localhost
  * @param binary_argv binary name and command-line arguments to give to the 
binary
- * @param cb function to call for messages received from the binary
- * @param cb_cls closure for cb
  * @return handle to terminate the command, NULL on error
  */
 struct GNUNET_TESTBED_HelperHandle *
-GNUNET_TESTBED_host_run_ (struct GNUNET_TESTBED_Host *host,
-                         char *const binary_argv[],
-                         GNUNET_SERVER_MessageTokenizerCallback cb, void 
*cb_cls)
+GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
+                         char *const binary_argv[])
 {
-  /* FIXME: decide on the SSH command line, prepend it and
-     run GNUNET_HELPER_start with the modified binary_name and binary_argv! */
   struct GNUNET_TESTBED_HelperHandle *h;
-  char *const local_args[] = {NULL};  
+  unsigned int argc;
 
+  argc = 0;
+  while (NULL != binary_argv[argc]) 
+    argc++;
   h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle));
+  h->cpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO);
   if (0 == host->unique_id)
   {
-    h->handle = GNUNET_HELPER_start ("gnunet-service-testbed", local_args,
-                                     cb, cb_cls);
+    h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
+                                             h->cpipe, NULL,
+                                             "gnunet-service-testbed", 
+                                             binary_argv);
   }
   else
   {    
+    char *remote_args[argc + 6 + 1];
+    unsigned int argp;
+
     GNUNET_asprintf (&h->port, "%d", host->port);
     GNUNET_asprintf (&h->dst, "address@hidden", host->hostname, 
host->username);
-    char *remote_args[] = {"ssh", "-p", h->port, "-q", h->dst,
-                           "gnunet-service-testbed", NULL};
-    h->handle = GNUNET_HELPER_start ("ssh", remote_args, cb, cb_cls);
+    argp = 0;
+    remote_args[argp++] = "ssh";
+    remote_args[argp++] = "-p";
+    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++] = NULL;
+    GNUNET_assert (argp == argc + 6 + 1);
+    h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
+                                             h->cpipe, NULL,
+                                             "ssh", 
+                                             remote_args);
   }
-  if (NULL == h->handle)
+  if (NULL == h->process)
   {
+    GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe));
+    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, 
GNUNET_DISK_PIPE_END_READ));
   return h;
 }
 
@@ -292,7 +321,10 @@
 void
 GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle)
 {
-  GNUNET_HELPER_stop (handle->handle);
+  GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe));
+  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);
   GNUNET_free_non_null (handle->port);
   GNUNET_free_non_null (handle->dst);
   GNUNET_free (handle);

Modified: gnunet/src/testbed/testbed_api_hosts.h
===================================================================
--- gnunet/src/testbed/testbed_api_hosts.h      2012-06-14 08:55:09 UTC (rev 
21989)
+++ gnunet/src/testbed/testbed_api_hosts.h      2012-06-14 09:25:54 UTC (rev 
21990)
@@ -55,25 +55,6 @@
 
 
 /**
- * Create a host to run peers and controllers on.  This function is used
- * if a peer learns about a host via IPC between controllers (and thus 
- * some higher-level controller has already determined the unique IDs).
- * 
- * @param id global host ID assigned to the host; 0 is
- *        reserved to always mean 'localhost'
- * @param hostname name of the host, use "NULL" for localhost
- * @param username username to use for the login; may be NULL
- * @param port port number to use for ssh; use 0 to let ssh decide
- * @return handle to the host, NULL on error
- */
-struct GNUNET_TESTBED_Host *
-GNUNET_TESTBED_host_create_with_id_ (uint32_t id,
-                                    const char *hostname,
-                                    const char *username,
-                                    uint16_t port);
-
-
-/**
  * Obtain a host's unique global ID.
  * 
  * @param host handle to the host, NULL means 'localhost'
@@ -98,14 +79,11 @@
  * 
  * @param host host to use, use "NULL" for localhost
  * @param binary_argv binary name and command-line arguments to give to the 
binary
- * @param cb function to call for messages received from the binary
- * @param cb_cls closure for cb
  * @return handle to terminate the command, NULL on error
  */
 struct GNUNET_TESTBED_HelperHandle *
-GNUNET_TESTBED_host_run_ (struct GNUNET_TESTBED_Host *host,
-                         char *const binary_argv[],
-                         GNUNET_SERVER_MessageTokenizerCallback cb, void 
*cb_cls);
+GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host,
+                         char *const binary_argv[]);
 
 
 /**




reply via email to

[Prev in Thread] Current Thread [Next in Thread]