[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V9 01/12] introduce an API to async exec scripts
introduce an API to async exec scripts.it will be used for both device and netbuffer. Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> --- tools/libxl/libxl_internal.c | 82 ++++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl_internal.h | 21 ++++++++++++ 2 files changed, 103 insertions(+) diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c index 6c94d3e..e47eb90 100644 --- a/tools/libxl/libxl_internal.c +++ b/tools/libxl/libxl_internal.c @@ -375,6 +375,88 @@ out: return rc; } +static void libxl_async_exec_timeout(libxl__egc *egc, + libxl__ev_time *ev, + const struct timeval *requested_abs) +{ + libxl_async_exec *async_exec = CONTAINER_OF(ev, *async_exec, time); + + STATE_AO_GC(async_exec->ao); + + libxl__ev_time_deregister(gc, &async_exec->time); + assert(libxl__ev_child_inuse(&async_exec->child)); + + LOG(DEBUG, "killing hotplug script %s because of timeout", + async_exec->args[0]); + + if (kill(async_exec->child.pid, SIGKILL)) { + LOGEV(ERROR, errno, "unable to kill hotplug script %s [%ld]", + async_exec->args[0], + (unsigned long)async_exec->child.pid); + } + + return; +} + +static void libxl_async_exec_done(libxl__egc *egc, + libxl__ev_child *child, + pid_t pid, int status) +{ + libxl_async_exec *async_exec = CONTAINER_OF(child, *async_exec, child); + + STATE_AO_GC(async_exec->ao); + + libxl__ev_time_deregister(gc, &async_exec->time); + + if (status && !async_exec->allow_fail) { + libxl_report_child_exitstatus(CTX, LIBXL__LOG_ERROR, + async_exec->args[0], + pid, status); + } + + async_exec->finish_cb(async_exec->opaque, status); +} + +int libxl_async_exec_script(libxl__gc *gc, libxl_async_exec *async_exec) +{ + pid_t pid; + + /* Convenience aliases */ + libxl__ev_child *const child = &async_exec->child; + char * const *args = async_exec->args; + char * const *env = async_exec->env; + const int stdinfd = async_exec->stdinfd; + const int stdoutfd = async_exec->stdoutfd; + const int stderrfd = async_exec->stderrfd; + + /* Set hotplug timeout */ + if (libxl__ev_time_register_rel(gc, &async_exec->time, + libxl_async_exec_timeout, + async_exec->timeout * 1000)) { + LOG(ERROR, "unable to register timeout for " + "script %s", args[0]); + return ERROR_FAIL; + } + + LOG(DEBUG, "Calling script: %s ", args[0]); + + /* Fork and exec netbuf script */ + pid = libxl__ev_child_fork(gc, child, libxl_async_exec_done); + if (pid == -1) { + LOG(ERROR, "unable to fork for script %s", args[0]); + return ERROR_FAIL; + } + + if (!pid) { + /* child: Launch netbuf script */ + libxl__exec(gc, stdinfd, stdoutfd, stderrfd, args[0], args, env); + /* notreached */ + abort(); + } + + return 0; +} + /* * Local variables: * mode: C diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index c2b73c4..eddafaf 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2030,6 +2030,27 @@ _hidden const char *libxl__xen_script_dir_path(void); _hidden const char *libxl__lock_dir_path(void); _hidden const char *libxl__run_dir_path(void); +/*----- asynchronous function -----*/ +typedef struct libxl_async_exec { + char **env; + char **args; + void *opaque; + void (*finish_cb)(void *opaque, int status); + /* unit: second */ + int timeout; + bool allow_fail; + int stdinfd; + int stdoutfd; + int stderrfd; + + libxl__ev_time time; + libxl__ev_child child; + libxl__ao *ao; +} libxl_async_exec; + +_hidden extern int libxl_async_exec_script(libxl__gc *gc, + libxl_async_exec *async_exec); + /*----- device addition/removal -----*/ typedef struct libxl__ao_device libxl__ao_device; -- 1.8.3.2 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |