[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 19 of 29 RFC] libxl: add libxl__device_hotplug_disconnect
# HG changeset patch # User Roger Pau Monne <roger.pau@xxxxxxxxxxxxx> # Date 1328178627 -3600 # Node ID 937bbe68a1942e22c40aa18c8bb66490aec56945 # Parent 94733bc9cc2fbeaa08a660ec90dcd9c5ad924e1b libxl: add libxl__device_hotplug_disconnect Sets the necessary xenstore entries to trigger the unplug of a device, and waits for the device to react (either by setting the device state to disconnected or to error). Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxxxxx> diff -r 94733bc9cc2f -r 937bbe68a194 tools/libxl/libxl_device.c --- a/tools/libxl/libxl_device.c Thu Feb 02 11:27:27 2012 +0100 +++ b/tools/libxl/libxl_device.c Thu Feb 02 11:30:27 2012 +0100 @@ -405,7 +405,7 @@ int libxl__device_disk_dev_number(const * or timeout occurred. */ int libxl__wait_for_device_state(libxl__gc *gc, struct timeval *tv, - XenbusState state, + int state, libxl__device_state_handler handler) { libxl_ctx *ctx = libxl__gc_owner(gc); @@ -413,6 +413,7 @@ int libxl__wait_for_device_state(libxl__ unsigned int n; fd_set rfds; char **l1 = NULL; + char *entry; start: rc = 1; @@ -431,6 +432,10 @@ start: default: l1 = xs_read_watch(ctx->xsh, &n); if (l1 != NULL) { + entry = strrchr(l1[0], '/'); + if (!entry || strcmp(entry, "/state")) + goto start; + char *sstate = libxl__xs_read(gc, XBT_NULL, l1[XS_WATCH_PATH]); if (!sstate || atoi(sstate) == state) { @@ -575,6 +580,71 @@ out: return rc; } +int libxl__device_hotplug_disconnect(libxl__gc *gc, libxl__device *dev, + libxl__hotplug_status disconnect_param) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + xs_transaction_t t; + char *hotplug_path = libxl__device_hotplug_path(gc, dev); + char *state_path = libxl__sprintf(gc, "%s/state", hotplug_path); + char *state; + struct timeval tv; + int rc = 0; + +retry_transaction: + t = xs_transaction_start(ctx->xsh); + state = libxl__xs_read(gc, t, state_path); + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disconnecting device with path %s and " + "state %s", hotplug_path, state); + if (!state) { + xs_transaction_end(ctx->xsh, t, 0); + goto out; + } + if (atoi(state) != HOTPLUG_DEVICE_CONNECTED) { + xs_transaction_end(ctx->xsh, t, 0); + goto out; + } + libxl__xs_write(gc, t, state_path, "%d", disconnect_param); + if (!xs_transaction_end(ctx->xsh, t, 0)) { + if (errno == EAGAIN) + goto retry_transaction; + else { + rc = ERROR_FAIL; + goto out; + } + } + + xs_watch(ctx->xsh, state_path, hotplug_path); + + tv.tv_sec = LIBXL_DESTROY_TIMEOUT; + tv.tv_usec = 0; + rc = libxl__wait_for_device_state(gc, &tv, HOTPLUG_DEVICE_DISCONNECTED, + NULL); + xs_unwatch(ctx->xsh, state_path, hotplug_path); + state = libxl__xs_read(gc, XBT_NULL, state_path); + if (!state) { + goto out; + } + if (atoi(state) == HOTPLUG_DEVICE_ERROR) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "Error while unplug of " + "device with hotplug path %s", hotplug_path); + rc = ERROR_FAIL; + } else if (rc == ERROR_TIMEDOUT) { + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Timeout while waiting for unplug of " + "device with hotplug path %s", hotplug_path); + } else if (rc == ERROR_FAIL) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "failed to destroy device with " + "hotplug path %s", hotplug_path); + } + +out: + libxl__xs_path_cleanup(gc, hotplug_path); + return rc; +} + int libxl__device_destroy(libxl__gc *gc, libxl__device *dev) { char *be_path = libxl__device_backend_path(gc, dev); diff -r 94733bc9cc2f -r 937bbe68a194 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Thu Feb 02 11:27:27 2012 +0100 +++ b/tools/libxl/libxl_internal.h Thu Feb 02 11:30:27 2012 +0100 @@ -334,7 +334,7 @@ typedef int libxl__device_state_handler( * Returns 0 on success, and < 0 on error. */ _hidden int libxl__wait_for_device_state(libxl__gc *gc, struct timeval *tv, - XenbusState state, + int state, libxl__device_state_handler handler); /* @@ -366,6 +366,16 @@ typedef enum { } libxl__hotplug_status; /* + * libxl__device_hotplug_disconnect - disconnect remove device + * disconnect_param: action to use when disconnecting the device, either + * HOTPLUG_DEVICE_DISCONNECT or HOTPLUG_DEVICE_FORCE_DISCONNECT + * + * Returns 0 on success, and < 0 on error. + */ +_hidden int libxl__device_hotplug_disconnect(libxl__gc *gc, libxl__device *dev, + libxl__hotplug_status disconnect_param); + +/* * libxl__device_hotplug - generic function to execute hotplug scripts * gc: allocation pool * dev: reference to the device that executes the hotplug scripts _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |