aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_device.c
diff options
context:
space:
mode:
authorRoger Pau Monne <roger.pau@entel.upc.edu>2011-12-15 18:55:45 +0100
committerRoger Pau Monne <roger.pau@entel.upc.edu>2011-12-15 18:55:45 +0100
commit888fa55351bc751a0cca0150c92e01b449c5c219 (patch)
tree34ee4df3ebff5a4d3a182027feabc57ce63e0478 /tools/libxl/libxl_device.c
parent97ee1f5d722e7504bf878b8200047db3f127ddde (diff)
downloadxen-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.c42
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 {