diff options
author | Roger Pau Monne <roger.pau@entel.upc.edu> | 2011-12-15 18:55:45 +0100 |
---|---|---|
committer | Roger Pau Monne <roger.pau@entel.upc.edu> | 2011-12-15 18:55:45 +0100 |
commit | 888fa55351bc751a0cca0150c92e01b449c5c219 (patch) | |
tree | 34ee4df3ebff5a4d3a182027feabc57ce63e0478 /tools/libxl/libxl_device.c | |
parent | 97ee1f5d722e7504bf878b8200047db3f127ddde (diff) | |
download | xen-888fa55351bc751a0cca0150c92e01b449c5c219.tar.gz xen-888fa55351bc751a0cca0150c92e01b449c5c219.tar.bz2 xen-888fa55351bc751a0cca0150c92e01b449c5c219.zip |
libxl: introduce libxl__wait_for_device_state
This is a generic function, that waits for xs watches to reach a
certain state and then executes the passed helper function. Removed
wait_for_dev_destroy and used this new function instead. This
function will also be used by future patches that need to wait for
the initialization of devices before executing hotplug scripts.
Signed-off-by: Roger Pau Monne <roger.pau@entel.upc.edu>
Acked-by: Ian Jackson <ian.jackson.citrix.com>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxl/libxl_device.c')
-rw-r--r-- | tools/libxl/libxl_device.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index 3264c7f93d..1ff812d4cb 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -369,7 +369,9 @@ int libxl__device_disk_dev_number(const char *virtpath, int *pdisk, * Returns 0 if a device is removed, ERROR_* if an error * or timeout occurred. */ -static int wait_for_dev_destroy(libxl__gc *gc, struct timeval *tv) +int libxl__wait_for_device_state(libxl__gc *gc, struct timeval *tv, + XenbusState state, + libxl__device_state_handler handler) { libxl_ctx *ctx = libxl__gc_owner(gc); int nfds, rc; @@ -394,17 +396,14 @@ start: default: l1 = xs_read_watch(ctx->xsh, &n); if (l1 != NULL) { - char *state = libxl__xs_read(gc, XBT_NULL, + char *sstate = libxl__xs_read(gc, XBT_NULL, l1[XS_WATCH_PATH]); - if (!state || atoi(state) == 6) { - xs_unwatch(ctx->xsh, l1[0], l1[1]); - xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]); - LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, - "Destroyed device backend at %s", - l1[XS_WATCH_TOKEN]); - rc = 0; + if (!sstate || atoi(sstate) == state) { + /* Call handler function if present */ + if (handler) + rc = handler(gc, l1, sstate); } else { - /* State is not "disconnected", continue waiting... */ + /* State is different than expected, continue waiting... */ goto start; } free(l1); @@ -417,6 +416,23 @@ start: } /* + * Handler function for device destruction to be passed to + * libxl__wait_for_device_state + */ +static int destroy_device(libxl__gc *gc, char **l1, char *state) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + + xs_unwatch(ctx->xsh, l1[0], l1[1]); + xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]); + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, + "Destroyed device backend at %s", + l1[XS_WATCH_TOKEN]); + + return 0; +} + +/* * Returns 0 (device already destroyed) or 1 (caller must * wait_for_dev_destroy) on success, ERROR_* on fail. */ @@ -457,7 +473,8 @@ retry_transaction: struct timeval tv; tv.tv_sec = LIBXL_DESTROY_TIMEOUT; tv.tv_usec = 0; - rc = wait_for_dev_destroy(gc, &tv); + rc = libxl__wait_for_device_state(gc, &tv, XenbusStateClosed, + destroy_device); if (rc < 0) /* an error or timeout occurred, clear watches */ xs_unwatch(ctx->xsh, state_path, be_path); xs_rm(ctx->xsh, XBT_NULL, libxl__device_frontend_path(gc, dev)); @@ -565,7 +582,8 @@ int libxl__devices_destroy(libxl__gc *gc, uint32_t domid, int force) tv.tv_sec = LIBXL_DESTROY_TIMEOUT; tv.tv_usec = 0; while (n_watches > 0) { - if (wait_for_dev_destroy(gc, &tv) < 0) { + if (libxl__wait_for_device_state(gc, &tv, XenbusStateClosed, + destroy_device) < 0) { /* function returned ERROR_* */ break; } else { |