[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v1 06/12] 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 Jackson <Ian.Jackson@xxxxxxxxxxxxx> Cc: Ian Campbell <ian.campbell@xxxxxxxxxx> --- Changes since RFC: * This patch has been reworked to synchronize the toolstack and the driver domain, by making the driver domain only remove the first directory of the backend path, and the toolstack domain remove the rest. --- tools/libxl/libxl_device.c | 82 ++++++++++++++++++++++++++++++++++++++++- tools/libxl/libxl_internal.h | 2 + 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index d726f0b..fbab0d5 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -722,6 +722,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); @@ -932,8 +940,32 @@ 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; + + /* Wait for the driver domain to remove the backend path */ + libxl__ev_time_init(&aodev->timeout); + libxl__ev_xswatch_init(&aodev->xs_watch); + + 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 */ @@ -1051,6 +1083,52 @@ 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); + + libxl__ev_time_deregister(gc, &aodev->timeout); + libxl__ev_xswatch_deregister(gc, &aodev->xs_watch); + + 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 */ + libxl__ev_time_deregister(gc, &aodev->timeout); + libxl__ev_xswatch_deregister(gc, &aodev->xs_watch); + device_hotplug_done(egc, aodev); +} + static void device_hotplug_done(libxl__egc *egc, libxl__ao_device *aodev) { STATE_AO_GC(aodev->ao); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 3b74726..7b86fb4 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1882,6 +1882,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; -- 1.7.7.5 (Apple Git-26) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |