From 73ad75b9f9cd4111d7f99e62fe8dc873ab8ccfcc Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Thu, 12 Jul 2012 11:50:12 +0000 Subject: [PATCH] implemented controller error callback --- src/testbed/gnunet-service-testbed.c | 1 - src/testbed/testbed_api.c | 53 ++++++++++++++++++++-------- src/testbed/testbed_api_hosts.c | 45 ++++++----------------- src/testbed/testbed_api_hosts.h | 32 +++++++++++++++++ 4 files changed, 82 insertions(+), 49 deletions(-) diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 0619a67cb..fabfe1691 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -1279,7 +1279,6 @@ shutdown_task (void *cls, 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); diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index 5070d4f29..d9aec6197 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -430,31 +430,40 @@ struct GNUNET_TESTBED_ControllerProc */ 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 * @@ -480,7 +489,7 @@ GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system, 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))) @@ -512,9 +521,20 @@ GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system, } 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; } @@ -529,6 +549,11 @@ 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); } diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c index 2b86074f7..56df4dede 100644 --- a/src/testbed/testbed_api_hosts.c +++ b/src/testbed/testbed_api_hosts.c @@ -33,6 +33,8 @@ #include "gnunet_hello_lib.h" #include "gnunet_container_lib.h" +#include "testbed_api_hosts.h" + /** * Generic logging shorthand */ @@ -333,33 +335,6 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host) } -/** - * 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. @@ -381,8 +356,9 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host, 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"); @@ -393,7 +369,7 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host, { 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); } @@ -423,19 +399,19 @@ GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host, 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; } @@ -448,7 +424,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)); + 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); diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h index 1eab19363..b9a62698c 100644 --- a/src/testbed/testbed_api_hosts.h +++ b/src/testbed/testbed_api_hosts.h @@ -30,6 +30,38 @@ #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. * -- 2.25.1