uint32_t id;
shutdown_task_id = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_SCHEDULER_shutdown ();
LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n");
(void) GNUNET_CONTAINER_multihashmap_iterate (ss_map, &ss_map_free_iterator,
NULL);
*/
struct GNUNET_TESTBED_HelperHandle *helper;
-};
-
-
-/**
- * Context to use while starting a controller
- */
-struct ControllerStartContext
-{
/**
- * The error callback
+ * The controller error callback
*/
GNUNET_TESTBED_ControllerErrorCallback cec;
/**
- * Closure for the above callback
+ * The closure for the above callback
*/
void *cec_cls;
/**
- * error message if any
+ * The task id of the task that will be called when controller dies
*/
- char *emsg;
+ GNUNET_SCHEDULER_TaskIdentifier controller_dead_task_id;
};
+/**
+ * The task which is run when a controller dies (its stdout is closed)
+ *
+ * @param cls the ControllerProc struct
+ * @param tc the context
+ */
+static void
+controller_dead_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ 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? */
+}
+
+
/**
* Starts a controller process at the host
*
void *cec_cls)
{
struct GNUNET_TESTBED_ControllerProc *cproc;
- //struct ControllerStartContext *csc;
+ const struct GNUNET_DISK_FileHandle *read_fh;
char *cfg_filename;
if ((NULL == host) || (0 == GNUNET_TESTBED_host_get_id_ (host)))
}
else
{
- GNUNET_break (0);
+ GNUNET_break (0); /* FIXME: start controller remotely */
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;
}
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);
}
#include "gnunet_hello_lib.h"
#include "gnunet_container_lib.h"
+#include "testbed_api_hosts.h"
+
/**
* Generic logging shorthand
*/
}
-/**
- * Wrapper around GNUNET_HELPER_Handle
- */
-struct GNUNET_TESTBED_HelperHandle
-{
- /**
- * The process 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;
-
- /**
- * The ssh destination string; used for helpers starting ssh
- */
- char *dst;
-};
-
-
/**
* Run a given helper process at the given host. Communication
* with the helper will be via GNUnet messages on stdin/stdout.
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 (NULL == h->cpipe)
+ 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");
{
h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
GNUNET_OS_INHERIT_STD_ALL,
- h->cpipe, NULL,
+ h->cpipe_in, h->cpipe_out,
"gnunet-service-testbed",
binary_argv);
}
GNUNET_assert (argp == argc + 6 + 1);
h->process = GNUNET_OS_start_process_vap (GNUNET_YES,
GNUNET_OS_INHERIT_STD_ALL,
- h->cpipe, NULL,
+ h->cpipe_in, NULL,
"ssh",
remote_args);
}
if (NULL == h->process)
{
- GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe));
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe_in));
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));
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close_end (h->cpipe_in, GNUNET_DISK_PIPE_END_READ));
return h;
}
void
GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle)
{
- GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe));
+ 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);
#include "gnunet_helper_lib.h"
+/**
+ * Wrapper around
+ */
+struct GNUNET_TESTBED_HelperHandle
+{
+ /**
+ * The process handle
+ */
+ struct GNUNET_OS_Process *process;
+
+ /**
+ * Pipe connecting to stdin of the process.
+ */
+ struct GNUNET_DISK_PipeHandle *cpipe_in;
+
+ /**
+ * Pipe from the stdout of the process.
+ */
+ struct GNUNET_DISK_PipeHandle *cpipe_out;
+
+ /**
+ * The port number for ssh; used for helpers starting ssh
+ */
+ char *port;
+
+ /**
+ * The ssh destination string; used for helpers starting ssh
+ */
+ char *dst;
+};
+
+
/**
* Lookup a host by ID.
*