[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4/7] netbuffer: use async exec API to exec the netbuffer script
Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> --- tools/libxl/libxl.c | 2 +- tools/libxl/libxl_internal.h | 3 +- tools/libxl/libxl_netbuffer.c | 139 ++++++++++++----------------------------- 3 files changed, 43 insertions(+), 101 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index c4a4751..1596146 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -747,7 +747,7 @@ int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info, /* convenience shorthand */ libxl__remus_state *remus_state = dss->remus_state; remus_state->dss = dss; - libxl__ev_child_init(&remus_state->child); + remus_state->egc = egc; /* TBD: enable disk buffering */ diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index ab82334..bf92975 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2438,14 +2438,15 @@ typedef struct libxl__remus_state { /* Script to setup/teardown network buffers */ const char *netbufscript; libxl__domain_suspend_state *dss; + libxl__egc *egc; /* private */ int saved_rc; int dev_id; /* Opaque context containing network buffer related stuff */ void *netbuf_state; + /* used for checkpoint */ libxl__ev_time timeout; - libxl__ev_child child; } libxl__remus_state; _hidden int libxl__netbuffer_enabled(libxl__gc *gc); diff --git a/tools/libxl/libxl_netbuffer.c b/tools/libxl/libxl_netbuffer.c index c9c1ba7..d996832 100644 --- a/tools/libxl/libxl_netbuffer.c +++ b/tools/libxl/libxl_netbuffer.c @@ -32,7 +32,7 @@ typedef struct libxl__remus_netbuf_state { const char **vif_list; const char **ifb_list; uint32_t num_netbufs; - uint32_t unused; + libxl_async_exec async_exec; } libxl__remus_netbuf_state; int libxl__netbuffer_enabled(libxl__gc *gc) @@ -238,52 +238,20 @@ static int init_qdiscs(libxl__gc *gc, return ERROR_FAIL; } -static void netbuf_setup_timeout_cb(libxl__egc *egc, - libxl__ev_time *ev, - const struct timeval *requested_abs) -{ - libxl__remus_state *remus_state = CONTAINER_OF(ev, *remus_state, timeout); - - /* Convenience aliases */ - const int devid = remus_state->dev_id; - libxl__remus_netbuf_state *const netbuf_state = remus_state->netbuf_state; - const char *const vif = netbuf_state->vif_list[devid]; - - STATE_AO_GC(remus_state->dss->ao); - - libxl__ev_time_deregister(gc, &remus_state->timeout); - assert(libxl__ev_child_inuse(&remus_state->child)); - - LOG(DEBUG, "killing hotplug script %s (on vif %s) because of timeout", - remus_state->netbufscript, vif); - - if (kill(remus_state->child.pid, SIGKILL)) { - LOGEV(ERROR, errno, "unable to kill hotplug script %s [%ld]", - remus_state->netbufscript, - (unsigned long)remus_state->child.pid); - } - - return; -} - /* the script needs the following env & args * $vifname * $XENBUS_PATH (/libxl/<domid>/remus/netbuf/<devid>/) * $IFB (for teardown) * setup/teardown as command line arg. - * In return, the script writes the name of IFB device (during setup) to be - * used for output buffering into XENBUS_PATH/ifb */ -static int exec_netbuf_script(libxl__gc *gc, libxl__remus_state *remus_state, - char *op, libxl__ev_child_callback *death) +static void setup_env(libxl_async_exec *async_exec, char *op, + libxl__remus_state *remus_state) { int arraysize, nr = 0; char **env = NULL, **args = NULL; - pid_t pid; + STATE_AO_GC(remus_state->dss->ao); /* Convenience aliases */ - libxl__ev_child *const child = &remus_state->child; - libxl__ev_time *const timeout = &remus_state->timeout; char *const script = libxl__strdup(gc, remus_state->netbufscript); const uint32_t domid = remus_state->dss->domid; const int devid = remus_state->dev_id; @@ -312,40 +280,17 @@ static int exec_netbuf_script(libxl__gc *gc, libxl__remus_state *remus_state, args[nr++] = NULL; assert(nr == arraysize); - /* Set hotplug timeout */ - if (libxl__ev_time_register_rel(gc, timeout, - netbuf_setup_timeout_cb, - LIBXL_HOTPLUG_TIMEOUT * 1000)) { - LOG(ERROR, "unable to register timeout for " - "netbuf setup script %s on vif %s", script, vif); - return ERROR_FAIL; - } - - LOG(DEBUG, "Calling netbuf script: %s %s on vif %s", - script, op, vif); - - /* Fork and exec netbuf script */ - pid = libxl__ev_child_fork(gc, child, death); - if (pid == -1) { - LOG(ERROR, "unable to fork netbuf script %s", script); - return ERROR_FAIL; - } - - if (!pid) { - /* child: Launch netbuf script */ - libxl__exec(gc, -1, -1, -1, args[0], args, env); - /* notreached */ - abort(); - } - - return 0; + async_exec->env = env; + async_exec->args = args; } -static void netbuf_setup_script_cb(libxl__egc *egc, - libxl__ev_child *child, - pid_t pid, int status) +/* + * In return, the script writes the name of IFB device (during setup) to be + * used for output buffering into XENBUS_PATH/ifb + */ +static void netbuf_setup_script_cb(void *opaque, int status) { - libxl__remus_state *remus_state = CONTAINER_OF(child, *remus_state, child); + libxl__remus_state *remus_state = opaque; const char *out_path_base, *hotplug_error = NULL; int rc = ERROR_FAIL; @@ -358,7 +303,8 @@ static void netbuf_setup_script_cb(libxl__egc *egc, STATE_AO_GC(remus_state->dss->ao); - libxl__ev_time_deregister(gc, &remus_state->timeout); + if (status) + goto out; out_path_base = GCSPRINTF("%s/remus/netbuf/%d", libxl__xs_libxl_path(gc, domid), devid); @@ -377,14 +323,6 @@ static void netbuf_setup_script_cb(libxl__egc *egc, goto out; } - if (status) { - libxl_report_child_exitstatus(CTX, LIBXL__LOG_ERROR, - remus_state->netbufscript, - pid, status); - rc = ERROR_FAIL; - goto out; - } - rc = libxl__xs_read_checked(gc, XBT_NULL, GCSPRINTF("%s/remus/netbuf/%d/ifb", libxl__xs_libxl_path(gc, domid), @@ -403,9 +341,8 @@ static void netbuf_setup_script_cb(libxl__egc *egc, LOG(DEBUG, "%s will buffer packets from vif %s", *ifb, vif); remus_state->dev_id++; if (remus_state->dev_id < netbuf_state->num_netbufs) { - rc = exec_netbuf_script(gc, remus_state, - "setup", netbuf_setup_script_cb); - if (rc) + setup_env(&netbuf_state->async_exec, "setup", remus_state); + if (libxl_async_exec_script(gc, &netbuf_state->async_exec)) goto out; return; @@ -413,7 +350,7 @@ static void netbuf_setup_script_cb(libxl__egc *egc, rc = init_qdiscs(gc, remus_state); out: - libxl__remus_netbuf_setup_done(egc, remus_state->dss, rc); + libxl__remus_netbuf_setup_done(remus_state->egc, remus_state->dss, rc); } /* Scan through the list of vifs belonging to domid and @@ -444,12 +381,19 @@ void libxl__remus_netbuf_setup(libxl__egc *egc, if (num_netbufs < 0) goto out; + libxl__ev_child_init(&netbuf_state->async_exec.child); + GCNEW_ARRAY(netbuf_state->ifb_list, num_netbufs); netbuf_state->num_netbufs = num_netbufs; remus_state->netbuf_state = netbuf_state; remus_state->dev_id = 0; - if (exec_netbuf_script(gc, remus_state, "setup", - netbuf_setup_script_cb)) + + netbuf_state->async_exec.timeout = LIBXL_HOTPLUG_TIMEOUT; + netbuf_state->async_exec.opaque = remus_state; + netbuf_state->async_exec.finish_cb = netbuf_setup_script_cb; + netbuf_state->async_exec.ao = ao; + setup_env(&netbuf_state->async_exec, "setup", remus_state); + if (libxl_async_exec_script(gc, &netbuf_state->async_exec)) goto out; return; @@ -457,35 +401,25 @@ void libxl__remus_netbuf_setup(libxl__egc *egc, libxl__remus_netbuf_setup_done(egc, dss, rc); } -static void netbuf_teardown_script_cb(libxl__egc *egc, - libxl__ev_child *child, - pid_t pid, int status) +static void netbuf_teardown_script_cb(void *opaque, int status) { - libxl__remus_state *remus_state = CONTAINER_OF(child, *remus_state, child); + libxl__remus_state *remus_state = opaque; /* Convenience aliases */ libxl__remus_netbuf_state *const netbuf_state = remus_state->netbuf_state; STATE_AO_GC(remus_state->dss->ao); - libxl__ev_time_deregister(gc, &remus_state->timeout); - - if (status) { - libxl_report_child_exitstatus(CTX, LIBXL__LOG_ERROR, - remus_state->netbufscript, - pid, status); - } - remus_state->dev_id++; if (remus_state->dev_id < netbuf_state->num_netbufs) { - if (exec_netbuf_script(gc, remus_state, - "teardown", netbuf_teardown_script_cb)) + setup_env(&netbuf_state->async_exec, "teardown", remus_state); + if (libxl_async_exec_script(gc, &netbuf_state->async_exec)) goto out; return; } out: - libxl__remus_netbuf_teardown_done(egc, remus_state->dss); + libxl__remus_netbuf_teardown_done(remus_state->egc, remus_state->dss); } /* Note: This function will be called in the same gc context as @@ -501,11 +435,18 @@ void libxl__remus_netbuf_teardown(libxl__egc *egc, STATE_AO_GC(dss->ao); + libxl__ev_child_init(&netbuf_state->async_exec.child); + free_qdiscs(netbuf_state); + netbuf_state->async_exec.timeout = LIBXL_HOTPLUG_TIMEOUT; + netbuf_state->async_exec.opaque = remus_state; + netbuf_state->async_exec.finish_cb = netbuf_teardown_script_cb; + netbuf_state->async_exec.ao = ao; remus_state->dev_id = 0; - if (exec_netbuf_script(gc, remus_state, "teardown", - netbuf_teardown_script_cb)) + setup_env(&netbuf_state->async_exec, "teardown", remus_state); + + if (libxl_async_exec_script(gc, &netbuf_state->async_exec)) libxl__remus_netbuf_teardown_done(egc, dss); } -- 1.7.4.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |