[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] libxl: synchronize device removal when using driver domains
commit f36df037ba8813207275b7094966436fcbb30060 Author: Roger Pau Monne <roger.pau@xxxxxxxxxx> AuthorDate: Fri Sep 27 11:37:04 2013 +0200 Commit: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CommitDate: Mon Nov 18 17:08:56 2013 +0000 libxl: synchronize device removal when using driver domains Synchronize the clean up of the backend from the toolstack domain when the driver domain has actually finished closing the backend for the device. This is accomplished by waiting for the driver domain to remove the directory containing the backend keys, then the toolstack domain will finish the cleanup by removing the empty folders on the backend path. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> --- tools/libxl/libxl_device.c | 80 ++++++++++++++++++++++++++++++++++++++++- tools/libxl/libxl_internal.h | 2 + 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index d5f23cf..b7168d4 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -432,6 +432,11 @@ void libxl__prepare_ao_device(libxl__ao *ao, libxl__ao_device *aodev) aodev->num_exec = 0; /* Initialize timer for QEMU Bodge and hotplug execution */ libxl__ev_time_init(&aodev->timeout); + /* + * Initialize xs_watch, because it's not used on all possible + * execution paths, but it's unconditionally destroyed when finished. + */ + libxl__ev_xswatch_init(&aodev->xs_watch); aodev->active = 1; /* We init this here because we might call device_hotplug_done * without actually calling any hotplug script */ @@ -709,6 +714,14 @@ static void device_hotplug_child_death_cb(libxl__egc *egc, libxl__ev_child *child, pid_t pid, int status); +static void device_destroy_be_timeout_cb(libxl__egc *egc, libxl__ev_time *ev, + const struct timeval *requested_abs); + +static void device_destroy_be_watch_cb(libxl__egc *egc, + libxl__ev_xswatch *watch, + const char *watch_path, + const char *event_path); + static void device_hotplug_done(libxl__egc *egc, libxl__ao_device *aodev); static void device_hotplug_clean(libxl__gc *gc, libxl__ao_device *aodev); @@ -768,6 +781,7 @@ void libxl__initiate_device_remove(libxl__egc *egc, LOG(ERROR, "unable to get info for domain %d", domid); goto out; } + if (QEMU_BACKEND(aodev->dev) && (info.paused || info.dying || info.shutdown)) { /* @@ -919,8 +933,28 @@ static void device_hotplug(libxl__egc *egc, libxl__ao_device *aodev) */ rc = libxl__get_domid(gc, &domid); if (rc) goto out; - if (aodev->dev->backend_domid != domid) - goto out; + if (aodev->dev->backend_domid != domid) { + if (aodev->action != LIBXL__DEVICE_ACTION_REMOVE) + goto out; + + rc = libxl__ev_time_register_rel(gc, &aodev->timeout, + device_destroy_be_timeout_cb, + LIBXL_DESTROY_TIMEOUT * 1000); + if (rc) { + LOG(ERROR, "setup of xs watch timeout failed"); + goto out; + } + + rc = libxl__ev_xswatch_register(gc, &aodev->xs_watch, + device_destroy_be_watch_cb, + be_path); + if (rc) { + LOG(ERROR, "setup of xs watch for %s failed", be_path); + libxl__ev_time_deregister(gc, &aodev->timeout); + goto out; + } + return; + } /* Check if we have to execute hotplug scripts for this device * and return the necessary args/env vars for execution */ @@ -1038,6 +1072,47 @@ error: device_hotplug_done(egc, aodev); } +static void device_destroy_be_timeout_cb(libxl__egc *egc, libxl__ev_time *ev, + const struct timeval *requested_abs) +{ + libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, timeout); + STATE_AO_GC(aodev->ao); + + LOG(ERROR, "timed out while waiting for %s to be removed", + libxl__device_backend_path(gc, aodev->dev)); + + aodev->rc = ERROR_TIMEDOUT; + + device_hotplug_done(egc, aodev); + return; +} + +static void device_destroy_be_watch_cb(libxl__egc *egc, + libxl__ev_xswatch *watch, + const char *watch_path, + const char *event_path) +{ + libxl__ao_device *aodev = CONTAINER_OF(watch, *aodev, xs_watch); + STATE_AO_GC(aodev->ao); + const char *dir; + int rc; + + rc = libxl__xs_read_checked(gc, XBT_NULL, watch_path, &dir); + if (rc) { + LOG(ERROR, "unable to read backend path: %s", watch_path); + aodev->rc = rc; + goto out; + } + if (dir) { + /* backend path still exists, wait a little longer... */ + return; + } + +out: + /* We are done, backend path no longer exists */ + device_hotplug_done(egc, aodev); +} + static void device_hotplug_done(libxl__egc *egc, libxl__ao_device *aodev) { STATE_AO_GC(aodev->ao); @@ -1060,6 +1135,7 @@ static void device_hotplug_clean(libxl__gc *gc, libxl__ao_device *aodev) { /* Clean events and check reentrancy */ libxl__ev_time_deregister(gc, &aodev->timeout); + libxl__ev_xswatch_deregister(gc, &aodev->xs_watch); assert(!libxl__ev_child_inuse(&aodev->child)); } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 23ff265..e3b9fb4 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1928,6 +1928,8 @@ struct libxl__ao_device { libxl__ev_devstate backend_ds; /* Bodge for Qemu devices, also used for timeout of hotplug execution */ libxl__ev_time timeout; + /* xenstore watch for backend path of driver domains */ + libxl__ev_xswatch xs_watch; /* device hotplug execution */ const char *what; int num_exec; -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |