gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated: - started to implement several cmds to s


From: gnunet
Subject: [gnunet] branch master updated: - started to implement several cmds to start peers^Ctestcase plugin will be started directly from helper, functionality to communicate between master cmd loop and local cmd loop, code compiles, test is not working atm.
Date: Fri, 16 Jul 2021 21:11:34 +0200

This is an automated email from the git hooks/post-receive script.

t3sserakt pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 33830e71f - started to implement several cmds to start peers^Ctestcase 
plugin will be started directly from helper, functionality to communicate 
between master cmd loop and local cmd loop, code compiles, test is not working 
atm.
33830e71f is described below

commit 33830e71f8e80334e0c8cf5527b1f2b20804485e
Author: t3sserakt <t3ss@posteo.de>
AuthorDate: Fri Jul 16 21:05:11 2021 +0200

    - started to implement several cmds to start peers^Ctestcase plugin will be 
started directly from helper, functionality to communicate between master cmd 
loop and local cmd loop, code compiles, test is not working atm.
---
 src/include/gnunet_protocols.h                     |  20 +
 src/include/gnunet_testbed_ng_service.h            |   9 +
 src/include/gnunet_testing_ng_lib.h                |   1 +
 src/include/gnunet_testing_plugin.h                |  12 +-
 src/testbed/Makefile.am                            |  11 +-
 src/testbed/gnunet-cmd.c                           |  54 ++-
 .../{gnunet-helper-cmds.c => gnunet-cmds-helper.c} | 480 +++++++++++++--------
 src/testbed/netjail_exec.sh                        |   2 +-
 src/testbed/plugin_testcmd.c                       |  19 +-
 src/testbed/testbed_api.h                          |   3 +-
 ...testbed_api_cmd_block_until_all_peers_started.c | 102 +++++
 src/testbed/testbed_api_cmd_netjail_start.c        |   6 +
 .../testbed_api_cmd_netjail_start_testbed.c        | 162 +++++--
 src/testbed/testbed_api_cmd_send_peer_ready.c      | 102 +++++
 src/testbed/testbed_helper.h                       |  46 ++
 src/testing/testing_api_cmd_start_peer.c           | 296 +++++++++++++
 src/testing/testing_api_cmd_system_create.c        | 110 +++++
 src/testing/testing_api_loop.c                     |   3 +
 src/transport/transport-testing.c                  |   4 +-
 src/transport/transport-testing2.c                 |   4 +-
 src/util/child_management.c                        |  19 +-
 21 files changed, 1239 insertions(+), 226 deletions(-)

diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 8e6e8b1be..1d33d986d 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3549,6 +3549,26 @@ extern "C" {
 
 
/*********************************************************************************/
 
+/*********************************************************************************/
+/**********************************  Cmd Testing  
**********************************/
+/*********************************************************************************/
+
+/**
+ * The initialization message towards gnunet-cmds-helper
+ */
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT 1700
+
+/**
+ * The reply message from gnunet-cmds-helper
+ */
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY 1701
+
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED 1702
+
+#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED 1703
+
+/*********************************************************************************/
+
 /**
  * Type used to match 'all' message types.
  */
diff --git a/src/include/gnunet_testbed_ng_service.h 
b/src/include/gnunet_testbed_ng_service.h
index 9845b3be6..2ea5e616c 100644
--- a/src/include/gnunet_testbed_ng_service.h
+++ b/src/include/gnunet_testbed_ng_service.h
@@ -265,4 +265,13 @@ int
 GNUNET_TESTBED_get_trait_hosts (const struct
                                 GNUNET_TESTING_Command *cmd,
                                 struct GNUNET_TESTBED_Host ***hosts);
+
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
+                                                  unsigned int *
+                                                  all_peers_started);
+
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_send_peer_ready (const char *label,
+                                    TESTBED_CMD_HELPER_write_cb write_message);
 #endif
diff --git a/src/include/gnunet_testing_ng_lib.h 
b/src/include/gnunet_testing_ng_lib.h
index a794562a9..8927fd4f1 100644
--- a/src/include/gnunet_testing_ng_lib.h
+++ b/src/include/gnunet_testing_ng_lib.h
@@ -28,6 +28,7 @@
 #define GNUNET_TESTING_NG_LIB_H
 
 #include "gnunet_util_lib.h"
+#include "gnunet_testing_plugin.h"
 
 
 /* ********************* Helper functions ********************* */
diff --git a/src/include/gnunet_testing_plugin.h 
b/src/include/gnunet_testing_plugin.h
index 527f509ad..6a54cacd2 100644
--- a/src/include/gnunet_testing_plugin.h
+++ b/src/include/gnunet_testing_plugin.h
@@ -36,9 +36,17 @@ extern "C"
 #endif
 #endif
 
+typedef void
+(*TESTBED_CMD_HELPER_write_cb) (struct GNUNET_MessageHeader *message, size_t
+                                msg_length);
+
+typedef void
+(*GNUNET_TESTING_PLUGIN_StartTestCase) (TESTBED_CMD_HELPER_write_cb
+                                        write_message, char *router_ip,
+                                        char *node_ip);
 
 typedef void
-(*GNUNET_TESTING_PLUGIN_StartTestCase) ();
+(*GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED) ();
 
 struct GNUNET_TESTING_PluginFunctions
 {
@@ -48,6 +56,8 @@ struct GNUNET_TESTING_PluginFunctions
   void *cls;
 
   GNUNET_TESTING_PLUGIN_StartTestCase start_testcase;
+
+  GNUNET_TESTING_PLUGIN_ALL_PEERS_STARTED all_peers_started;
 };
 
 #if 0                           /* keep Emacsens' auto-indent happy */
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am
index 8c4a6342b..dc24eaf26 100644
--- a/src/testbed/Makefile.am
+++ b/src/testbed/Makefile.am
@@ -24,7 +24,7 @@ endif
 
 libexec_PROGRAMS = \
   gnunet-cmd \
-  gnunet-helper-cmds \
+  gnunet-cmds-helper \
   gnunet-service-testbed \
   gnunet-helper-testbed \
   gnunet-daemon-testbed-blacklist \
@@ -45,6 +45,7 @@ libgnunet_plugin_testcmd_la_SOURCES = \
 libgnunet_plugin_testcmd_la_LIBADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
   $(top_builddir)/src/testing/libgnunettesting.la \
+  $(top_builddir)/src/testbed/libgnunettestbed.la
   $(LTLIBINTL)
 libgnunet_plugin_testcmd_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
@@ -94,9 +95,9 @@ gnunet_cmd_LDADD = $(XLIB) \
  libgnunettestbed.la \
  $(LTLIBINTL) $(Z_LIBS)
 
-gnunet_helper_cmds_SOURCES = \
-  gnunet-helper-cmds.c
-gnunet_helper_cmds_LDADD = $(XLIB) \
+gnunet_cmds_helper_SOURCES = \
+  gnunet-cmds-helper.c
+gnunet_cmds_helper_LDADD = $(XLIB) \
  $(top_builddir)/src/util/libgnunetutil.la \
  $(top_builddir)/src/testing/libgnunettesting.la \
  libgnunettestbed.la \
@@ -124,6 +125,8 @@ lib_LTLIBRARIES = \
   libgnunettestbed.la
 
 libgnunettestbed_la_SOURCES = \
+  testbed_api_cmd_send_peer_ready.c \
+  testbed_api_cmd_block_until_all_peers_started.c \
   testbed_api_cmd_netjail_start.c \
   testbed_api_cmd_netjail_start_testbed.c \
   testbed_api_cmd_netjail_stop_testbed.c \
diff --git a/src/testbed/gnunet-cmd.c b/src/testbed/gnunet-cmd.c
index 477c3c454..7889750ba 100644
--- a/src/testbed/gnunet-cmd.c
+++ b/src/testbed/gnunet-cmd.c
@@ -36,6 +36,9 @@
  */
 #define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
 
+#define NODE_BASE_IP "192.168.15."
+
+#define ROUTER_BASE_IP "92.68.150."
 
 /**
  * Handle for a plugin.
@@ -51,29 +54,44 @@ struct Plugin
    * Plugin API.
    */
   struct GNUNET_TESTING_PluginFunctions *api;
+
+  char *node_ip;
+
+  char *plugin_name;
+
+  char *global_n;
+
+  char *local_m;
+
+  char *n;
+
+  char *m;
 };
 
 
 /**
  * Main function to run the test cases.
  *
- * @param cls not used.
+ * @param cls plugin to use.
  *
  */
 static void
 run (void *cls)
 {
-  struct Plugin *plugin;
+  struct Plugin *plugin = cls;
+  char *router_ip;
+  char *node_ip;
+
+  router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m) + 1);
+  strcpy (router_ip, ROUTER_BASE_IP);
+  strcat (router_ip, plugin->m);
+
+  node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
+  strcat (node_ip, NODE_BASE_IP);
+  strcat (node_ip, plugin->n);
+
+  plugin->api->start_testcase (NULL, router_ip, node_ip);
 
-  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "gnunet-cmd",
-                   "running plugin.\n");
-  LOG (GNUNET_ERROR_TYPE_ERROR,
-       "running plugin.\n");
-  plugin = GNUNET_new (struct Plugin);
-  plugin->api = GNUNET_PLUGIN_load ("libgnunet_plugin_testcmd",
-                                    NULL);
-  plugin->library_name = GNUNET_strdup ("libgnunet_plugin_testcmd");
-  plugin->api->start_testcase ();
 }
 
 
@@ -81,13 +99,25 @@ int
 main (int argc, char *const *argv)
 {
   int rv = 0;
+  struct Plugin *plugin;
 
   GNUNET_log_setup ("gnunet-cmd",
                     "DEBUG",
                     NULL);
 
+  plugin = GNUNET_new (struct Plugin);
+  plugin->api = GNUNET_PLUGIN_load (argv[0],
+                                    NULL);
+  plugin->library_name = GNUNET_strdup (argv[0]);
+
+  plugin->global_n = argv[1];
+  plugin->local_m = argv[2];
+  plugin->n = argv[3];
+  plugin->m = argv[4];
+
   GNUNET_SCHEDULER_run (&run,
-                        NULL);
+                        plugin);
 
+  GNUNET_free (plugin);
   return rv;
 }
diff --git a/src/testbed/gnunet-helper-cmds.c b/src/testbed/gnunet-cmds-helper.c
similarity index 58%
rename from src/testbed/gnunet-helper-cmds.c
rename to src/testbed/gnunet-cmds-helper.c
index 3073ebdfb..693892a9c 100644
--- a/src/testbed/gnunet-helper-cmds.c
+++ b/src/testbed/gnunet-cmds-helper.c
@@ -19,7 +19,7 @@
  */
 
 /**
- * @file testbed/gnunet-helper-cmds.c
+ * @file testbed/gnunet-cmds-helper.c
  * @brief Helper binary that is started from a remote interpreter loop to start
  *        a local interpreter loop.
  *
@@ -42,7 +42,9 @@
 #include "gnunet_testbed_service.h"
 #include "testbed_helper.h"
 #include "testbed_api.h"
+#include "gnunet_testing_plugin.h"
 #include <zlib.h>
+#include "execinfo.h"
 
 /**
  * Generic logging shortcut
@@ -54,6 +56,50 @@
  */
 #define LOG_DEBUG(...) LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
 
+#define NODE_BASE_IP "192.168.15."
+
+#define ROUTER_BASE_IP "92.68.150."
+
+#define MAX_TRACE_DEPTH 50
+
+/**
+ * Handle for a plugin.
+ */
+struct Plugin
+{
+  /**
+   * Name of the shared library.
+   */
+  char *library_name;
+
+  /**
+   * Plugin API.
+   */
+  struct GNUNET_TESTING_PluginFunctions *api;
+
+  char *node_ip;
+
+  char *plugin_name;
+
+  char *global_n;
+
+  char *local_m;
+
+  char *n;
+
+  char *m;
+};
+
+struct NodeIdentifier
+{
+  char *n;
+
+  char *m;
+
+  char *global_n;
+
+  char *local_m;
+};
 
 /**
  * Context for a single write on a chunk of memory
@@ -76,6 +122,8 @@ struct WriteContext
   size_t pos;
 };
 
+struct Plugin *plugin;
+
 /**
  * The process handle to the testbed service
  */
@@ -132,6 +180,61 @@ static int done_reading;
 static int status;
 
 
+struct BacktraceInfo
+{
+  /**
+   * Array of strings which make up a backtrace from the point when this
+   * task was scheduled (essentially, who scheduled the task?)
+   */
+  char **backtrace_strings;
+
+  /**
+   * Size of the backtrace_strings array
+   */
+  int num_backtrace_strings;
+};
+
+/**
+ * Output stack trace of task @a t.
+ *
+ * @param t task to dump stack trace of
+ */
+static void
+dump_backtrace (struct BacktraceInfo *t)
+{
+
+  for (unsigned int i = 0; i < t->num_backtrace_strings; i++)
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Task %p trace %u: %s\n",
+         t,
+         i,
+         t->backtrace_strings[i]);
+
+}
+
+
+/**
+ * Initialize backtrace data for task @a t
+ *
+ * @param t task to initialize
+ */
+static void
+init_backtrace ()
+{
+  struct BacktraceInfo *t;
+  void *backtrace_array[MAX_TRACE_DEPTH];
+
+  t = GNUNET_new (struct BacktraceInfo);
+  t->num_backtrace_strings
+    = backtrace (backtrace_array, MAX_TRACE_DEPTH);
+  t->backtrace_strings =
+    backtrace_symbols (backtrace_array,
+                       t->num_backtrace_strings);
+  dump_backtrace (t);
+
+}
+
+
 /**
  * Task to shut down cleanly
  *
@@ -140,7 +243,11 @@ static int status;
 static void
 shutdown_task (void *cls)
 {
-  LOG_DEBUG ("Shutting down\n");
+
+  init_backtrace ();
+  LOG_DEBUG ("Shutting down.\n");
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "Shutting down tokenizer!\n");
 
   if (NULL != read_task_id)
   {
@@ -176,6 +283,8 @@ shutdown_task (void *cls)
 }
 
 
+
+
 /**
  * Task to write to the standard out
  *
@@ -187,6 +296,9 @@ write_task (void *cls)
   struct WriteContext *wc = cls;
   ssize_t bytes_wrote;
 
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "Writing data!\n");
+
   GNUNET_assert (NULL != wc);
   write_task_id = NULL;
   bytes_wrote = GNUNET_DISK_file_write (stdout_fd,
@@ -194,7 +306,8 @@ write_task (void *cls)
                                         wc->length - wc->pos);
   if (GNUNET_SYSERR == bytes_wrote)
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Cannot reply back configuration\n");
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Cannot reply back successful initialization\n");
     GNUNET_free (wc->data);
     GNUNET_free (wc);
     return;
@@ -204,8 +317,12 @@ write_task (void *cls)
   {
     GNUNET_free (wc->data);
     GNUNET_free (wc);
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Written successfully!\n");
     return;
   }
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "Written data!\n");
   write_task_id = GNUNET_SCHEDULER_add_write_file 
(GNUNET_TIME_UNIT_FOREVER_REL,
                                                    stdout_fd,
                                                    &write_task,
@@ -240,6 +357,52 @@ child_death_task (void *cls)
 }
 
 
+static void
+write_message (struct GNUNET_MessageHeader *message, size_t msg_length)
+{
+  struct WriteContext *wc;
+
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "enter write_message!\n");
+  wc = GNUNET_new (struct WriteContext);
+  wc->length = msg_length;
+  wc->data = message;
+  write_task_id = GNUNET_SCHEDULER_add_write_file (
+    GNUNET_TIME_UNIT_FOREVER_REL,
+    stdout_fd,
+    &write_task,
+    wc);
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "leave write_message!\n");
+}
+
+
+/**
+ * Function to run the test cases.
+ *
+ * @param cls plugin to use.
+ *
+ */
+static void
+run_plugin (void *cls)
+{
+  struct Plugin *plugin = cls;
+  char *router_ip;
+  char *node_ip;
+
+  router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m) + 1);
+  strcpy (router_ip, ROUTER_BASE_IP);
+  strcat (router_ip, plugin->m);
+
+  node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
+  strcat (node_ip, NODE_BASE_IP);
+  strcat (node_ip, plugin->n);
+
+  plugin->api->start_testcase (&write_message, router_ip, node_ip);
+
+}
+
+
 /**
  * Functions with this signature are called whenever a
  * complete message is received by the tokenizer.
@@ -255,191 +418,140 @@ child_death_task (void *cls)
 static int
 tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
 {
-  const struct GNUNET_TESTBED_HelperInit *msg;
-  struct GNUNET_TESTBED_HelperReply *reply;
-  struct GNUNET_CONFIGURATION_Handle *cfg;
-  struct WriteContext *wc;
+  struct NodeIdentifier *ni = cls;
+  const struct GNUNET_CMDS_HelperInit *msg;
+  struct GNUNET_CMDS_HelperReply *reply;
   char *binary;
-  char *trusted_ip;
-  char *hostname;
-  char *config;
-  char *xconfig;
-  char *evstr;
-  // char *str;
-  size_t config_size;
-  uLongf ul_config_size;
-  size_t xconfig_size;
-  uint16_t trusted_ip_size;
-  uint16_t hostname_size;
+  char *plugin_name;
+  size_t plugin_name_size;
   uint16_t msize;
+  size_t msg_length;
+  char *router_ip;
+  char *node_ip;
+
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "tokenizer \n");
 
   msize = ntohs (message->size);
-  if ((sizeof(struct GNUNET_TESTBED_HelperInit) >= msize) ||
-      (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT != ntohs (message->type)))
+  if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED == ntohs (
+        message->type))
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- 
exiting\n");
-    goto error;
-  }
-  msg = (const struct GNUNET_TESTBED_HelperInit *) message;
-  trusted_ip_size = ntohs (msg->trusted_ip_size);
-  trusted_ip = (char *) &msg[1];
-  if ('\0' != trusted_ip[trusted_ip_size])
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Trusted IP cannot be empty -- exiting\n");
-    goto error;
-  }
-  hostname_size = ntohs (msg->hostname_size);
-  if ((sizeof(struct GNUNET_TESTBED_HelperInit) + trusted_ip_size + 1
-       + hostname_size) >= msize)
-  {
-    GNUNET_break (0);
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- 
exiting\n");
-    goto error;
+    plugin->api->all_peers_started ();
   }
-  ul_config_size = (uLongf) ntohs (msg->config_size);
-  config = GNUNET_malloc (ul_config_size);
-  xconfig_size = msize - (trusted_ip_size + 1 + hostname_size
-                          + sizeof(struct GNUNET_TESTBED_HelperInit));
-  int ret = uncompress ((Bytef *) config,
-                        &ul_config_size,
-                        (const Bytef *) (trusted_ip + trusted_ip_size + 1
-                                         + hostname_size),
-                        (uLongf) xconfig_size);
-  if (Z_OK != ret)
+  else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT == ntohs (message->type))
   {
-    switch (ret)
+    msg = (const struct GNUNET_CMDS_HelperInit *) message;
+    plugin_name_size = ntohs (msg->plugin_name_size);
+    if ((sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_size) > msize)
     {
-    case Z_MEM_ERROR:
-      LOG (GNUNET_ERROR_TYPE_ERROR, "Not enough memory for decompression\n");
-      break;
+      GNUNET_break (0);
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+           "Received unexpected message -- exiting\n");
+      goto error;
+    }
+    plugin_name = GNUNET_malloc (plugin_name_size + 1);
+    GNUNET_strlcpy (plugin_name,
+                    ((char *) &msg[1]),
+                    plugin_name_size + 1);
 
-    case Z_BUF_ERROR:
-      LOG (GNUNET_ERROR_TYPE_ERROR, "Output buffer too small\n");
-      break;
+    binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
 
-    case Z_DATA_ERROR:
-      LOG (GNUNET_ERROR_TYPE_ERROR, "Data corrupted/incomplete\n");
-      break;
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "plugin_name: %s \n",
+         plugin_name);
+
+    // cmd_binary_process = GNUNET_OS_start_process (
+    /*GNUNET_OS_INHERIT_STD_ERR  verbose? ,
+      NULL,
+      NULL,
+      NULL,
+      binary,
+      plugin_name,
+      ni->global_n,
+      ni->local_m,
+      ni->n,
+      ni->m,
+      NULL);*/
+
+    plugin = GNUNET_new (struct Plugin);
+    plugin->api = GNUNET_PLUGIN_load (plugin_name,
+                                      NULL);
+    plugin->library_name = GNUNET_strdup (plugin_name);
+
+    plugin->global_n = ni->global_n;
+    plugin->local_m = ni->local_m;
+    plugin->n = ni->n;
+    plugin->m = ni->m;
+
+    router_ip = GNUNET_malloc (strlen (ROUTER_BASE_IP) + strlen (plugin->m)
+                               + 1);
+    strcpy (router_ip, ROUTER_BASE_IP);
+    strcat (router_ip, plugin->m);
+
+    node_ip = GNUNET_malloc (strlen (NODE_BASE_IP) + strlen (plugin->n) + 1);
+    strcat (node_ip, NODE_BASE_IP);
+    strcat (node_ip, plugin->n);
+
+    plugin->api->start_testcase (&write_message, router_ip, node_ip);
 
-    default:
-      GNUNET_break (0);
-    }
     LOG (GNUNET_ERROR_TYPE_ERROR,
-         "Error while uncompressing config -- exiting\n");
-    GNUNET_free (config);
-    goto error;
-  }
-  cfg = GNUNET_CONFIGURATION_create ();
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_deserialize (cfg, config, ul_config_size, NULL))
-  {
-    LOG (GNUNET_ERROR_TYPE_ERROR, "Unable to deserialize config -- exiting\n");
-    GNUNET_free (config);
-    goto error;
-  }
-  GNUNET_free (config);
-  hostname = NULL;
-  if (0 != hostname_size)
-  {
-    hostname = GNUNET_malloc (hostname_size + 1);
-    GNUNET_strlcpy (hostname,
-                    ((char *) &msg[1]) + trusted_ip_size + 1,
-                    hostname_size + 1);
-  }
-  /* unset GNUNET_TESTING_PREFIX if present as it is more relevant for testbed 
*/
-  evstr = getenv (GNUNET_TESTING_PREFIX);
-  if (NULL != evstr)
-  {
-    /* unsetting the variable will invalidate the pointer! */
-    evstr = GNUNET_strdup (evstr);
-    GNUNET_break (0 == unsetenv (GNUNET_TESTING_PREFIX));
-  }
-  test_system =
-    GNUNET_TESTING_system_create ("testbed-helper", trusted_ip, hostname, 
NULL);
-  if (NULL != evstr)
-  {
-    char *evar;
+         "We got here!\n");
 
-    GNUNET_asprintf (&evar, GNUNET_TESTING_PREFIX "=%s", evstr);
-    GNUNET_assert (0 == putenv (evar)); /* consumes 'evar',
-                                           see putenv(): becomes part of 
environment! */
-    GNUNET_free (evstr);
-    evstr = NULL;
-  }
-  GNUNET_free (hostname);
-  hostname = NULL;
-  GNUNET_assert (NULL != test_system);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_TESTING_configuration_create (test_system, cfg));
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CONFIGURATION_get_value_filename (cfg,
-                                                          "PATHS",
-                                                          "DEFAULTCONFIG",
-                                                          &config));
-  if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config))
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         "Unable to write config file: %s -- exiting\n",
-         config);
-    GNUNET_CONFIGURATION_destroy (cfg);
-    GNUNET_free (config);
-    goto error;
-  }
-  LOG_DEBUG ("Staring testbed with config: %s\n", config);
-  binary = GNUNET_OS_get_libexec_binary_path ("gnunet-cmd");
-  {
-    char *evar;
+    /*if (NULL == cmd_binary_process)
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           "Starting plugin failed!\n");
+      return GNUNET_SYSERR;
+      }*/
 
-    /* expose testbed configuration through env variable */
-    GNUNET_asprintf (&evar, "%s=%s", ENV_TESTBED_CONFIG, config);
-    GNUNET_assert (0 == putenv (evar));   /* consumes 'evar',
-                                            see putenv(): becomes part of 
environment! */
-    evstr = NULL;
-  }
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "We got here 2!\n");
+
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "global_n: %s local_n: %s n: %s m: %s.\n",
+         ni->global_n,
+         ni->local_m,
+         ni->n,
+         ni->m);
+
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "We got here 3!\n");
 
-  cmd_binary_process = GNUNET_OS_start_process (
-    GNUNET_OS_INHERIT_STD_ERR /*verbose? */,
-    NULL,
-    NULL,
-    NULL,
-    binary);
+    GNUNET_free (binary);
+
+    done_reading = GNUNET_YES;
+
+    msg_length = sizeof(struct GNUNET_CMDS_HelperReply);
+    reply = GNUNET_new (struct GNUNET_CMDS_HelperReply);
+    reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY);
+    reply->header.size = htons ((uint16_t) msg_length);
+
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "We got here 4!\n");
 
-  if (NULL == cmd_binary_process)
+    write_message ((struct GNUNET_MessageHeader *) reply, msg_length);
+
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "We got here 5!\n");
+
+    /*child_death_task_id = GNUNET_SCHEDULER_add_read_file (
+      GNUNET_TIME_UNIT_FOREVER_REL,
+      GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
+      &child_death_task,
+      NULL);*/
+    return GNUNET_OK;
+  }
+  else
   {
-    return GNUNET_SYSERR;
+    LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- 
exiting\n");
+    goto error;
   }
 
-  GNUNET_free (binary);
-  GNUNET_free (config);
-
-  done_reading = GNUNET_YES;
-  config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
-  GNUNET_CONFIGURATION_destroy (cfg);
-  cfg = NULL;
-  xconfig_size =
-    GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
-  GNUNET_free (config);
-  wc = GNUNET_new (struct WriteContext);
-  wc->length = xconfig_size + sizeof(struct GNUNET_TESTBED_HelperReply);
-  reply = GNUNET_realloc (xconfig, wc->length);
-  memmove (&reply[1], reply, xconfig_size);
-  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY);
-  reply->header.size = htons ((uint16_t) wc->length);
-  reply->config_size = htons ((uint16_t) config_size);
-  wc->data = reply;
-  write_task_id = GNUNET_SCHEDULER_add_write_file 
(GNUNET_TIME_UNIT_FOREVER_REL,
-                                                   stdout_fd,
-                                                   &write_task,
-                                                   wc);
-  child_death_task_id = GNUNET_SCHEDULER_add_read_file (
-    GNUNET_TIME_UNIT_FOREVER_REL,
-    GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ),
-    &child_death_task,
-    NULL);
-  return GNUNET_OK;
 
   error:
   status = GNUNET_SYSERR;
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "tokenizer shuting down!\n");
   GNUNET_SCHEDULER_shutdown ();
   return GNUNET_SYSERR;
 }
@@ -461,6 +573,8 @@ read_task (void *cls)
   if ((GNUNET_SYSERR == sread) || (0 == sread))
   {
     LOG_DEBUG ("STDIN closed\n");
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "tokenizer shuting down during reading!\n");
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
@@ -468,6 +582,8 @@ read_task (void *cls)
   {
     /* didn't expect any more data! */
     GNUNET_break_op (0);
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "tokenizer shuting down during reading, didn't expect any more 
data!\n");
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
@@ -478,6 +594,8 @@ read_task (void *cls)
       GNUNET_MST_from_buffer (tokenizer, buf, sread, GNUNET_NO, GNUNET_NO))
   {
     GNUNET_break (0);
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "tokenizer shuting down during reading, writing to buffer failed!\n");
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
@@ -503,8 +621,11 @@ run (void *cls,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
+  struct NodeIdentifier *ni = cls;
+
   LOG_DEBUG ("Starting interpreter loop helper...\n");
-  tokenizer = GNUNET_MST_create (&tokenizer_cb, NULL);
+
+  tokenizer = GNUNET_MST_create (&tokenizer_cb, ni);
   stdin_fd = GNUNET_DISK_get_handle_from_native (stdin);
   stdout_fd = GNUNET_DISK_get_handle_from_native (stdout);
   read_task_id = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -545,14 +666,28 @@ sighandler_child_death ()
 int
 main (int argc, char **argv)
 {
+  struct NodeIdentifier *ni;
   struct GNUNET_SIGNAL_Context *shc_chld;
   struct GNUNET_GETOPT_CommandLineOption options[] =
   { GNUNET_GETOPT_OPTION_END };
   int ret;
 
-  GNUNET_log_setup ("gnunet-helper-cmds",
+  GNUNET_log_setup ("gnunet-cmds-helper",
                     "DEBUG",
                     NULL);
+  ni = GNUNET_new (struct NodeIdentifier);
+  ni->global_n = argv[1];
+  ni->local_m = argv[2];
+  ni->n = argv[3];
+  ni->m = argv[4];
+
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "global_n: %s local_n: %s n: %s m: %s.\n",
+       ni->global_n,
+       ni->local_m,
+       ni->n,
+       ni->m);
+
   status = GNUNET_OK;
   if (NULL ==
       (sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE)))
@@ -564,18 +699,21 @@ main (int argc, char **argv)
     GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death);
   ret = GNUNET_PROGRAM_run (argc,
                             argv,
-                            "gnunet-helper-cmds",
+                            "gnunet-cmds-helper",
                             "Helper for starting a local interpreter loop",
                             options,
                             &run,
-                            NULL);
+                            ni);
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "run finished\n");
   GNUNET_SIGNAL_handler_uninstall (shc_chld);
   shc_chld = NULL;
   GNUNET_DISK_pipe_close (sigpipe);
+  GNUNET_free (ni);
   if (GNUNET_OK != ret)
     return 1;
   return (GNUNET_OK == status) ? 0 : 1;
 }
 
 
-/* end of gnunet-helper-testbed.c */
+/* end of gnunet-cmds-helper.c */
diff --git a/src/testbed/netjail_exec.sh b/src/testbed/netjail_exec.sh
index 3e5d39c1c..532f4711c 100755
--- a/src/testbed/netjail_exec.sh
+++ b/src/testbed/netjail_exec.sh
@@ -13,4 +13,4 @@ NODE=$(netjail_print_name "N" $N $M)
 
 
 
-netjail_node_exec_without_fds $NODE $3
+netjail_node_exec_without_fds $NODE $3 $4 $5 $1 $2
diff --git a/src/testbed/plugin_testcmd.c b/src/testbed/plugin_testcmd.c
index 90e4a90a1..6f28e102d 100644
--- a/src/testbed/plugin_testcmd.c
+++ b/src/testbed/plugin_testcmd.c
@@ -26,21 +26,32 @@
 #include "platform.h"
 #include "gnunet_testing_ng_lib.h"
 #include "gnunet_util_lib.h"
-#include "gnunet_testing_plugin.h"
-
-
+#include "gnunet_testbed_ng_service.h"
 
+unsigned int are_all_peers_started;
 
+static void
+all_peers_started ()
+{
+  are_all_peers_started = GNUNET_YES;
+}
 
 static void
-start_testcase ()
+start_testcase (TESTBED_CMD_HELPER_write_cb write_message, char *router_ip,
+                char *node_ip)
 {
   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
 
+  are_all_peers_started = GNUNET_NO;
+
   struct GNUNET_TESTING_Command commands[] = {
     GNUNET_TESTING_cmd_hello_world_birth ("hello-world-birth-0",
                                           &now),
     GNUNET_TESTING_cmd_hello_world ("hello-world-0","hello-world-birth-0",""),
+    GNUNET_TESTING_cmd_send_peer_ready ("send-peer-ready-1",
+                                        write_message),
+    GNUNET_TESTING_cmd_block_until_all_peers_started ("block-1",
+                                                      &are_all_peers_started),
     GNUNET_TESTING_cmd_end ()
   };
 
diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h
index ea78a14ff..9a54ca36c 100644
--- a/src/testbed/testbed_api.h
+++ b/src/testbed/testbed_api.h
@@ -40,7 +40,7 @@
 /**
  * Cmds Helper binary name
  */
-#define HELPER_CMDS_BINARY "gnunet-helper-cmds"
+#define HELPER_CMDS_BINARY "gnunet-cmds-helper"
 
 
 /**
@@ -185,7 +185,6 @@ struct OperationContext
 typedef void
 (*TESTBED_opcq_empty_cb) (void *cls);
 
-
 /**
  * Handle to interact with a GNUnet testbed controller.  Each
  * controller has at least one master handle which is created when the
diff --git a/src/testbed/testbed_api_cmd_block_until_all_peers_started.c 
b/src/testbed/testbed_api_cmd_block_until_all_peers_started.c
new file mode 100644
index 000000000..fc872311d
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_block_until_all_peers_started.c
@@ -0,0 +1,102 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      GNUnet is free software: you can redistribute it and/or modify it
+      under the terms of the GNU Affero General Public License as published
+      by the Free Software Foundation, either version 3 of the License,
+      or (at your option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Affero General Public License for more details.
+
+      You should have received a copy of the GNU Affero General Public License
+      along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_block_until_all_peers_started.c
+ * @brief cmd to block the interpreter loop until all peers started.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+struct BlockState
+{
+  unsigned int *all_peers_started;
+};
+
+
+static int
+block_until_all_peers_started_traits (void *cls,
+                                      const void **ret,
+                                      const char *trait,
+                                      unsigned int index)
+{
+  return GNUNET_OK;
+}
+
+
+static void
+block_until_all_peers_started_cleanup (void *cls,
+                                       const struct GNUNET_TESTING_Command 
*cmd)
+{
+  struct BlockState *bs = cls;
+
+  GNUNET_free (bs);
+}
+
+
+static void
+block_until_all_peers_started_run (void *cls,
+                                   const struct GNUNET_TESTING_Command *cmd,
+                                   struct GNUNET_TESTING_Interpreter *is)
+{
+}
+
+
+static int
+block_until_all_peers_started_finish (void *cls,
+                                      GNUNET_SCHEDULER_TaskCallback cont,
+                                      void *cont_cls)
+{
+  struct BlockState *bs = cls;
+  unsigned int *ret = bs->all_peers_started;
+
+  return *ret;
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_block_until_all_peers_started (const char *label,
+                                                  unsigned int *
+                                                  all_peers_started)
+{
+  struct BlockState *bs;
+
+  bs = GNUNET_new (struct BlockState);
+  bs->all_peers_started = all_peers_started;
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = bs,
+    .label = label,
+    .run = &block_until_all_peers_started_run,
+    .finish = &block_until_all_peers_started_finish,
+    .cleanup = &block_until_all_peers_started_cleanup,
+    .traits = &block_until_all_peers_started_traits
+  };
+
+  return cmd;
+}
diff --git a/src/testbed/testbed_api_cmd_netjail_start.c 
b/src/testbed/testbed_api_cmd_netjail_start.c
index 320537a61..1e37d5475 100644
--- a/src/testbed/testbed_api_cmd_netjail_start.c
+++ b/src/testbed/testbed_api_cmd_netjail_start.c
@@ -59,6 +59,9 @@ netjail_start_cleanup (void *cls,
 {
   struct NetJailState *ns = cls;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "netjail_start_cleanup!\n");
+
   if (NULL != ns->cwh)
   {
     GNUNET_wait_child_cancel (ns->cwh);
@@ -74,6 +77,7 @@ netjail_start_cleanup (void *cls,
     GNUNET_OS_process_destroy (ns->start_proc);
     ns->start_proc = NULL;
   }
+  GNUNET_free (ns);
 }
 
 
@@ -108,6 +112,8 @@ child_completed_callback (void *cls,
   }
   else
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Child completed with an error!\n");
     ns->finished = GNUNET_SYSERR;
   }
   GNUNET_OS_process_destroy (ns->start_proc);
diff --git a/src/testbed/testbed_api_cmd_netjail_start_testbed.c 
b/src/testbed/testbed_api_cmd_netjail_start_testbed.c
index dc8196e94..585825cbc 100644
--- a/src/testbed/testbed_api_cmd_netjail_start_testbed.c
+++ b/src/testbed/testbed_api_cmd_netjail_start_testbed.c
@@ -28,13 +28,36 @@
 #include "gnunet_testbed_ng_service.h"
 #include "testbed_api.h"
 #include "testbed_api_hosts.h"
+#include "testbed_helper.h"
 
 #define NETJAIL_EXEC_SCRIPT "./netjail_exec.sh"
 
+struct HelperMessage;
+
+struct HelperMessage
+{
+
+  struct HelperMessage *next;
+
+  struct HelperMessage *prev;
+
+  /**
+   * Size of the original message.
+   */
+  uint16_t bytes_msg;
+
+  /* Followed by @e bytes_msg of msg.*/
+};
+
+
 
 struct NetJailState
 {
 
+  struct HelperMessage *hp_messages_head;
+
+  struct HelperMessage *hp_messages_tail;
+
   /**
    * The process handle
    */
@@ -64,6 +87,8 @@ struct NetJailState
 
   unsigned int number_of_testbeds_started;
 
+  unsigned int number_of_peers_started;
+
   /**
    * The host where the controller is running
    */
@@ -112,7 +137,7 @@ netjail_exec_traits (void *cls,
 {
   struct NetJailState *ns = cls;
   struct GNUNET_HELPER_Handle **helper = ns->helper;
-  struct GNUNET_TESTBED_Host **hosts = ns->host;
+  struct HelperMessage *hp_messages_head = ns->hp_messages_head;
 
 
   struct GNUNET_TESTING_Trait traits[] = {
@@ -123,8 +148,8 @@ netjail_exec_traits (void *cls,
     },
     {
       .index = 1,
-      .trait_name = "hosts",
-      .ptr = (const void *) hosts,
+      .trait_name = "hp_msgs_head",
+      .ptr = (const void *) hp_messages_head,
     },
     GNUNET_TESTING_trait_end ()
   };
@@ -162,13 +187,14 @@ GNUNET_TESTBED_get_trait_helper_handles (const struct
  * @return #GNUNET_OK on success.
  */
 int
-GNUNET_TESTBED_get_trait_hosts (const struct
-                                GNUNET_TESTING_Command *cmd,
-                                struct GNUNET_TESTBED_Host ***hosts)
+GNUNET_TESTBED_get_trait_helper_messages (const struct
+                                          GNUNET_TESTING_Command *cmd,
+                                          struct HelperMessage ***
+                                          hp_messages_head)
 {
   return cmd->traits (cmd->cls,
-                      (const void **) hosts,
-                      "hosts",
+                      (const void **) hp_messages_head,
+                      "hp_msgs_head",
                       (unsigned int) 1);
 }
 
@@ -214,15 +240,32 @@ helper_mst (void *cls, const struct GNUNET_MessageHeader 
*message)
 {
   struct TestbedCount *tbc = cls;
   struct NetJailState *ns = tbc->ns;
-  struct GNUNET_TESTBED_Host *host = ns->host[tbc->count - 1];
+  struct HelperMessage *hp_msg;
+
+  if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "helper_mst tbc->count: %d\n",
+                tbc->count);
+    // GNUNET_TESTBED_extract_cfg (host, message);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Received message from helper.\n");
+    ns->number_of_testbeds_started++;
+  }
+  else if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED == ntohs (
+             message->type))
+  {
+    ns->number_of_peers_started++;
+  }
+  else
+  {
+    hp_msg = GNUNET_new (struct HelperMessage);
+    hp_msg->bytes_msg = message->size;
+    memcpy (&hp_msg[1], message, message->size);
+    GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
+                                 hp_msg);
+  }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "helper_mst tbc->count: %d\n",
-              tbc->count);
-  GNUNET_TESTBED_extract_cfg (host, message);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Received message from helper.\n");
-  ns->number_of_testbeds_started++;
   return GNUNET_OK;
 }
 
@@ -235,6 +278,32 @@ exp_cb (void *cls)
 }
 
 
+static struct GNUNET_CMDS_HelperInit *
+create_helper_init_msg_ (char *m_char,
+                         char *n_char,
+                         const char *plugin_name)
+{
+  struct GNUNET_CMDS_HelperInit *msg;
+  uint16_t plugin_name_len;
+  uint16_t msg_size;
+
+  GNUNET_assert (NULL != plugin_name);
+  plugin_name_len = strlen (plugin_name);
+  msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "msg_size: %d \n",
+              msg_size);
+  msg = GNUNET_malloc (msg_size);
+  msg->header.size = htons (msg_size);
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT);
+  msg->plugin_name_size = htons (plugin_name_len);
+  GNUNET_memcpy ((char *) &msg[1],
+                 plugin_name,
+                 plugin_name_len);
+  return msg;
+}
+
+
 static void
 start_testbed (struct NetJailState *ns, struct
                GNUNET_CONFIGURATION_Handle *config,
@@ -242,13 +311,15 @@ start_testbed (struct NetJailState *ns, struct
                char *m_char)
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
-  struct GNUNET_TESTBED_HelperInit *msg;
+  struct GNUNET_CMDS_HelperInit *msg;
   struct TestbedCount *tbc;
   char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
-                               m_char,
                                n_char,
+                               m_char,
                                GNUNET_OS_get_libexec_binary_path (
                                  HELPER_CMDS_BINARY),
+                               ns->global_n,
+                               ns->local_m,
                                NULL};
   unsigned int m = atoi (m_char);
   unsigned int n = atoi (n_char);
@@ -291,7 +362,9 @@ start_testbed (struct NetJailState *ns, struct
 
   struct GNUNET_HELPER_Handle *helper = ns->helper[tbc->count - 1];
 
-  msg = GNUNET_TESTBED_create_helper_init_msg_ ("127.0.0.1", NULL, config);
+  msg = create_helper_init_msg_ (m_char,
+                                 n_char,
+                                 "libgnunet_plugin_testcmd");
   GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
 
   GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
@@ -300,6 +373,10 @@ start_testbed (struct NetJailState *ns, struct
                          GNUNET_NO,
                          &clear_msg,
                          tbc));
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Message send!\n");
+
   if (NULL == ns->shandle[tbc->count - 1])
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -348,14 +425,49 @@ netjail_start_finish (void *cls,
 {
   unsigned int ret = GNUNET_NO;
   struct NetJailState *ns = cls;
+  unsigned int total_number = atoi (ns->local_m) * atoi (ns->global_n);
+  struct GNUNET_CMDS_PEER_STARTED *reply;
+  size_t msg_length;
+  struct GNUNET_HELPER_Handle *helper;
+  struct TestbedCount *tbc;
 
-  if (ns->number_of_testbeds_started == atoi (ns->local_m) * atoi (
-        ns->global_n))
+  if (ns->number_of_testbeds_started == total_number)
   {
-    ret = GNUNET_YES;
-    cont (cont_cls);
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "All helper started!\n");
+    /* ret = GNUNET_YES;
+       cont (cont_cls);*/
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "All helpers started!\n");
+  }
+
+  if (ns->number_of_peers_started == total_number)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "All peers started!\n");
+
+    for (int i = 1; i <= atoi (ns->global_n); i++) {
+      for (int j = 1; j <= atoi (ns->local_m); j++)
+      {
+        tbc = GNUNET_new (struct TestbedCount);
+        tbc->ns = ns;
+        tbc->count = (j - 1) * atoi (ns->local_m) + i + atoi (ns->global_n)
+                     * atoi (ns->local_m);
+        helper = ns->helper[tbc->count - 1];
+        msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
+        reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
+        reply->header.type = htons (
+          GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED);
+        reply->header.size = htons ((uint16_t) msg_length);
+
+        GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
+
+        GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
+                               helper,
+                               &reply->header,
+                               GNUNET_NO,
+                               &clear_msg,
+                               tbc));
+      }
+    }
   }
   return ret;
 }
diff --git a/src/testbed/testbed_api_cmd_send_peer_ready.c 
b/src/testbed/testbed_api_cmd_send_peer_ready.c
new file mode 100644
index 000000000..8a82b23a8
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_send_peer_ready.c
@@ -0,0 +1,102 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      GNUnet is free software: you can redistribute it and/or modify it
+      under the terms of the GNU Affero General Public License as published
+      by the Free Software Foundation, either version 3 of the License,
+      or (at your option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Affero General Public License for more details.
+
+      You should have received a copy of the GNU Affero General Public License
+      along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_send_peer_ready.c
+ * @brief cmd to send a helper message if peer is ready.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+
+struct SendPeerReadyState
+{
+  TESTBED_CMD_HELPER_write_cb write_message;
+
+  struct GNUNET_CMDS_PEER_STARTED *reply;
+};
+
+
+static int
+send_peer_ready_traits (void *cls,
+                        const void **ret,
+                        const char *trait,
+                        unsigned int index)
+{
+  return GNUNET_OK;
+}
+
+
+static void
+send_peer_ready_cleanup (void *cls,
+                         const struct GNUNET_TESTING_Command *cmd)
+{
+  struct SendPeerReadyState *sprs = cls;
+
+  GNUNET_free (sprs->reply);
+  GNUNET_free (sprs);
+}
+
+
+static void
+send_peer_ready_run (void *cls,
+                     const struct GNUNET_TESTING_Command *cmd,
+                     struct GNUNET_TESTING_Interpreter *is)
+{
+  /*struct SendPeerReadyState *sprs = cls;
+  struct GNUNET_CMDS_PEER_STARTED *reply;
+  size_t msg_length;
+
+  msg_length = sizeof(struct GNUNET_CMDS_PEER_STARTED);
+  reply = GNUNET_new (struct GNUNET_CMDS_PEER_STARTED);
+  reply->header.type = htons (GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED);
+  reply->header.size = htons ((uint16_t) msg_length);
+  sprs->reply = reply;
+  sprs->write_message ((struct GNUNET_MessageHeader *) reply, msg_length);*/
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_send_peer_ready (const char *label,
+                                    TESTBED_CMD_HELPER_write_cb write_message)
+{
+  struct SendPeerReadyState *sprs;
+
+  sprs = GNUNET_new (struct SendPeerReadyState);
+  sprs->write_message = write_message;
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = sprs,
+    .label = label,
+    .run = &send_peer_ready_run,
+    .cleanup = &send_peer_ready_cleanup,
+    .traits = &send_peer_ready_traits
+  };
+
+  return cmd;
+}
diff --git a/src/testbed/testbed_helper.h b/src/testbed/testbed_helper.h
index 817ad559d..84059fef2 100644
--- a/src/testbed/testbed_helper.h
+++ b/src/testbed/testbed_helper.h
@@ -84,6 +84,52 @@ struct GNUNET_TESTBED_HelperReply
    * un-compressed */
 };
 
+/**
+ * Initialization message for gnunet-cmds-testbed to start cmd binary.
+ */
+struct GNUNET_CMDS_HelperInit
+{
+  /**
+   * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   *
+   */
+  uint16_t plugin_name_size GNUNET_PACKED;
+
+  /* Followed by plugin name of the plugin running the test case. This is not 
NULL
+   * terminated */
+};
+
+/**
+ * Reply message from cmds helper process
+ */
+struct GNUNET_CMDS_HelperReply
+{
+  /**
+   * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
+   */
+  struct GNUNET_MessageHeader header;
+};
+
+struct GNUNET_CMDS_PEER_STARTED
+{
+  /**
+   * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
+   */
+  struct GNUNET_MessageHeader header;
+};
+
+struct GNUNET_CMDS_ALL_PEERS_STARTED
+{
+  /**
+   * Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
+   */
+  struct GNUNET_MessageHeader header;
+};
+
 GNUNET_NETWORK_STRUCT_END
 #endif
 /* end of testbed_helper.h */
diff --git a/src/testing/testing_api_cmd_start_peer.c 
b/src/testing/testing_api_cmd_start_peer.c
new file mode 100644
index 000000000..0f8c618b8
--- /dev/null
+++ b/src/testing/testing_api_cmd_start_peer.c
@@ -0,0 +1,296 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      GNUnet is free software: you can redistribute it and/or modify it
+      under the terms of the GNU Affero General Public License as published
+      by the Free Software Foundation, either version 3 of the License,
+      or (at your option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Affero General Public License for more details.
+
+      You should have received a copy of the GNU Affero General Public License
+      along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_start_peer.c
+ * @brief cmd to start a peer.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+
+struct StartPeerState
+{
+  /**
+   * Receive callback
+   */
+  struct GNUNET_MQ_MessageHandler *handlers;
+
+  const char *cfgname;
+
+  /**
+   * Peer's configuration
+   */
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  struct GNUNET_TESTING_Peer *peer;
+
+  /**
+   * Peer identity
+   */
+  struct GNUNET_PeerIdentity id;
+
+  /**
+   * Peer's transport service handle
+   */
+  struct GNUNET_TRANSPORT_CoreHandle *th;
+
+  /**
+   * Application handle
+   */
+  struct GNUNET_TRANSPORT_ApplicationHandle *ah;
+
+  /**
+   * Peer's PEERSTORE Handle
+   */
+  struct GNUNET_PEERSTORE_Handle *ph;
+
+  /**
+   * Hello get task
+   */
+  struct GNUNET_SCHEDULER_Task *rh_task;
+
+  /**
+   * Peer's transport get hello handle to retrieve peer's HELLO message
+   */
+  struct GNUNET_PEERSTORE_IterateContext *pic;
+
+  /**
+   * Hello
+   */
+  char *hello;
+
+  /**
+   * Hello size
+   */
+  size_t hello_size;
+
+  char *m;
+
+  char *n;
+
+  unsigned int finished;
+};
+
+
+static void
+retrieve_hello (void *cls);
+
+static void
+hello_iter_cb (void *cb_cls,
+               const struct GNUNET_PEERSTORE_Record *record,
+               const char *emsg)
+{
+  struct StartPeerState *sps = cb_cls;
+  if (NULL == record)
+  {
+    sps->pic = NULL;
+    sps->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
+    return;
+  }
+  // Check record type et al?
+  sps->hello_size = record->value_size;
+  sps->hello = GNUNET_malloc (sps->hello_size);
+  memcpy (sps->hello, record->value, sps->hello_size);
+  p->hello[p->hello_size - 1] = '\0';
+
+  GNUNET_PEERSTORE_iterate_cancel (sps->pic);
+  sps->pic = NULL;
+  sps->finished = GNUNET_YES;
+}
+
+
+static void
+retrieve_hello (void *cls)
+{
+  struct StartPeerState *sps = cls;
+  sps->rh_task = NULL;
+  sps->pic = GNUNET_PEERSTORE_iterate (sps->ph,
+                                       "transport",
+                                       &sps->id,
+                                       GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
+                                       hello_iter_cb,
+                                       sps);
+
+}
+
+static int
+start_peer_finish (void *cls,
+                   GNUNET_SCHEDULER_TaskCallback cont,
+                   void *cont_cls)
+{
+  struct StartPeerState *sps = cls;
+
+  return sps->finished;
+}
+
+
+static void
+start_peer_run (void *cls,
+                const struct GNUNET_TESTING_Command *cmd,
+                struct GNUNET_TESTING_Interpreter *is)
+{
+  struct StartPeerState *sps = cls;
+  char *emsg = NULL;
+  struct GNUNET_PeerIdentity dummy;
+
+  if (GNUNET_NO == GNUNET_DISK_file_test (sps->cfgname))
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "File not found: `%s'\n",
+         cfgname);
+    return NULL;
+  }
+
+  if (NULL != handlers)
+  {
+    for (i = 0; NULL != handlers[i].cb; i++)
+      ;
+    sps->handlers = GNUNET_new_array (i + 1,
+                                      struct GNUNET_MQ_MessageHandler);
+    GNUNET_memcpy (sps->handlers,
+                   handlers,
+                   i * sizeof(struct GNUNET_MQ_MessageHandler));
+  }
+  sps->cfg = GNUNET_CONFIGURATION_create ();
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONFIGURATION_load (sps->cfg, sps->cfgname));
+  if (GNUNET_SYSERR ==
+      GNUNET_TESTING_configuration_create (tl_system,
+                                           sps->cfg))
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Testing library failed to create unique configuration based on 
`%s'\n",
+         sps->cfgname);
+    GNUNET_CONFIGURATION_destroy (sps->cfg);
+    GNUNET_TESTING_interpreter_fail ();
+  }
+
+  sps->peer = GNUNET_TESTING_peer_configure (tth->tl_system,
+                                             p->cfg,
+                                             p->no,
+                                             NULL,
+                                             &emsg);
+  if (NULL == sps->peer)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Testing library failed to create unique configuration based on `%s': 
`%s'\n",
+         cfgname,
+         emsg);
+    GNUNET_free (emsg);
+    GNUNET_TESTING_interpreter_fail ();
+  }
+
+  if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Testing library failed to create unique configuration based on 
`%s'\n",
+         cfgname);
+    GNUNET_free (emsg);
+    GNUNET_TESTING_interpreter_fail ();
+  }
+
+  memset (&dummy,
+          '\0',
+          sizeof(dummy));
+  GNUNET_TESTING_peer_get_identity (sps->peer,
+                                    &sps->id);
+  if (0 == memcmp (&dummy,
+                   &sps->id,
+                   sizeof(struct GNUNET_PeerIdentity)))
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Testing library failed to obtain peer identity for peer %s_%s\n",
+         p->no);
+    GNUNET_free (emsg);
+    GNUNET_TESTING_interpreter_fail ();
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Peer %u configured with identity `%s'\n",
+       p->no,
+       GNUNET_i2s_full (&p->id));
+  sps->th = GNUNET_TRANSPORT_core_connect (p->cfg,
+                                           NULL,
+                                           handlers,
+                                           p,
+                                           &notify_connect,
+                                           &notify_disconnect);
+  if (NULL == sps->th)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Failed to connect to transport service for peer `%s': `%s'\n",
+         cfgname,
+         emsg);
+    GNUNET_free (emsg);
+    GNUNET_TESTING_interpreter_fail ();
+  }
+  sps->ph = GNUNET_PEERSTORE_connect (p->cfg);
+  if (NULL == sps->th)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Failed to connect to peerstore service for peer `%s': `%s'\n",
+         cfgname,
+         emsg);
+    GNUNET_free (emsg);
+    GNUNET_TESTING_interpreter_fail ();
+  }
+  sps->ah = GNUNET_TRANSPORT_application_init (p->cfg);
+  if (NULL == sps->ah)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "Failed to initialize the TRANSPORT application suggestion client 
handle for peer `%s': `%s'\n",
+         cfgname,
+         emsg);
+    GNUNET_free (emsg);
+    GNUNET_TESTING_interpreter_fail ();
+  }
+  p->rh_task = GNUNET_SCHEDULER_add_now (retrieve_hello, p);
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_start_peer (const char *label,
+                               char *m,
+                               char *n)
+{
+  struct StartPeerState *sps;
+
+  sps = GNUNET_new (struct StartPeerState);
+  sps->m = m;
+  sps->n = n;
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = sps,
+    .label = label,
+    .run = &start_peer_run,
+    .cleanup = &start_peer_cleanup,
+    .traits = &start_peer_traits
+  };
+
+  return cmd;
+}
diff --git a/src/testing/testing_api_cmd_system_create.c 
b/src/testing/testing_api_cmd_system_create.c
new file mode 100644
index 000000000..ad0aa4f90
--- /dev/null
+++ b/src/testing/testing_api_cmd_system_create.c
@@ -0,0 +1,110 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      GNUnet is free software: you can redistribute it and/or modify it
+      under the terms of the GNU Affero General Public License as published
+      by the Free Software Foundation, either version 3 of the License,
+      or (at your option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      Affero General Public License for more details.
+
+      You should have received a copy of the GNU Affero General Public License
+      along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testing_api_cmd_system_create.c
+ * @brief cmd to create a testing system handle.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+
+struct TestSystemState
+{
+  struct GNUNET_TESTING_System *test_system;
+};
+
+
+static void
+system_create_run (void *cls,
+                   const struct GNUNET_TESTING_Command *cmd,
+                   struct GNUNET_TESTING_Interpreter *is)
+{
+  struct TestSystemState *tss = cls;
+
+  tss->test_system = GNUNET_TESTING_system_create (tss->testdir,
+                                                   NULL,
+                                                   NULL,
+                                                   NULL);
+}
+
+static int
+system_create_traits (void *cls,
+                      const void **ret,
+                      const char *trait,
+                      unsigned int index)
+{
+  struct TestSystemState *tss = cls;
+  struct GNUNET_TESTING_System *test_system = tss->test_system;
+
+  struct GNUNET_TESTING_Trait traits[] = {
+    {
+      .index = 0,
+      .trait_name = "test_system",
+      .ptr = (const void *) test_system,
+    },
+    GNUNET_TESTING_trait_end ()
+  };
+
+  return GNUNET_TESTING_get_trait (traits,
+                                   ret,
+                                   trait,
+                                   index);
+}
+
+
+int
+GNUNET_TESTING_get_trait_test_system (const struct
+                                      GNUNET_TESTING_Command *cmd,
+                                      struct GNUNET_TESTING_System 
**test_system)
+{
+  return cmd->traits (cmd->cls,
+                      (const void **) test_system,
+                      "test_system",
+                      (unsigned int) 0);
+}
+
+
+/**
+ * Create command.
+ *
+ * @param label name for command.
+ * @return command.
+ */
+struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_system_create (const char *label,
+                                  const char *testdir)
+{
+  struct TestSystemState *tss;
+
+  tss = GNUNET_new (struct TestSystemState);
+  tss->testdir = testdir;
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = tss,
+    .label = label,
+    .run = &system_create_run,
+    .cleanup = &system_create_cleanup,
+    .traits = &system_create_traits
+  };
+
+  return cmd;
+}
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index 49ed48063..7b7dc010a 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -332,6 +332,9 @@ GNUNET_TESTING_interpreter_fail ()
   if (GNUNET_SYSERR == is->result)
     return; /* ignore, we already failed! */
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "interpreter_fail!\n");
+
   if (NULL != cmd)
   {
     while (GNUNET_TESTING_cmd_is_batch (cmd))
diff --git a/src/transport/transport-testing.c 
b/src/transport/transport-testing.c
index a7ee563d7..00c4a08dd 100644
--- a/src/transport/transport-testing.c
+++ b/src/transport/transport-testing.c
@@ -463,7 +463,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
     GNUNET_free (emsg);
     return NULL;
   }
-  GNUNET_free (emsg);
+
   if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -508,6 +508,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
          cfgname,
          emsg);
     GNUNET_TRANSPORT_TESTING_stop_peer (p);
+    GNUNET_free (emsg);
     return NULL;
   }
   p->ats = GNUNET_ATS_connectivity_init (p->cfg);
@@ -518,6 +519,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
          cfgname,
          emsg);
     GNUNET_TRANSPORT_TESTING_stop_peer (p);
+    GNUNET_free (emsg);
     return NULL;
   }
   p->ghh = GNUNET_TRANSPORT_hello_get (p->cfg,
diff --git a/src/transport/transport-testing2.c 
b/src/transport/transport-testing2.c
index 482aaf4d0..6d41ec098 100644
--- a/src/transport/transport-testing2.c
+++ b/src/transport/transport-testing2.c
@@ -478,7 +478,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
     GNUNET_free (emsg);
     return NULL;
   }
-  GNUNET_free (emsg);
+
   if (GNUNET_OK != GNUNET_TESTING_peer_start (p->peer))
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -520,6 +520,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
          cfgname,
          emsg);
     GNUNET_TRANSPORT_TESTING_stop_peer (p);
+    GNUNET_free (emsg);
     return NULL;
   }
   p->ats = GNUNET_ATS_connectivity_init (p->cfg);
@@ -530,6 +531,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct
          cfgname,
          emsg);
     GNUNET_TRANSPORT_TESTING_stop_peer (p);
+    GNUNET_free (emsg);
     return NULL;
   }
   p->ph = GNUNET_PEERSTORE_connect (p->cfg);
diff --git a/src/util/child_management.c b/src/util/child_management.c
index 11fde4a61..3afd682b9 100644
--- a/src/util/child_management.c
+++ b/src/util/child_management.c
@@ -29,6 +29,11 @@
 #include "gnunet_util_lib.h"
 #include "gnunet_child_management_lib.h"
 
+/**
+ * Generic logging shortcut
+ */
+#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
+
 
 /**
  * Struct which defines a Child Wait handle
@@ -87,7 +92,7 @@ maint_child_death (void *cls)
   (void) cls;
   sig_task = NULL;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
               "Received SIGCHLD.\n");
 
   /* drain pipe */
@@ -193,6 +198,9 @@ GNUNET_wait_child (struct GNUNET_OS_Process *proc,
 {
   struct GNUNET_ChildWaitHandle *cwh;
 
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       "Adding child!\n");
+
   child_management_start ();
   cwh = GNUNET_new (struct GNUNET_ChildWaitHandle);
   cwh->proc = proc;
@@ -216,9 +224,12 @@ GNUNET_wait_child (struct GNUNET_OS_Process *proc,
 void
 GNUNET_wait_child_cancel (struct GNUNET_ChildWaitHandle *cwh)
 {
-  GNUNET_CONTAINER_DLL_remove (cwh_head,
-                               cwh_tail,
-                               cwh);
+  if ((NULL != cwh_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (cwh_head,
+                                 cwh_tail,
+                                 cwh);
+  }
   if (NULL == cwh_head)
   {
     child_management_done ();

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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