aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_device.c
diff options
context:
space:
mode:
authorIan Jackson <ian.jackson@eu.citrix.com>2012-01-27 17:01:26 +0000
committerIan Jackson <ian.jackson@eu.citrix.com>2012-01-27 17:01:26 +0000
commit43e5afa7c827eb1ccf1c6ebae9b4f5e0c5cc468b (patch)
tree7e87f99a5cd0c5c7c2632b4f2682db3c071f26ac /tools/libxl/libxl_device.c
parenta057e090a1bc8090e347d4918cc516d082b6ed3f (diff)
downloadxen-43e5afa7c827eb1ccf1c6ebae9b4f5e0c5cc468b.tar.gz
xen-43e5afa7c827eb1ccf1c6ebae9b4f5e0c5cc468b.tar.bz2
xen-43e5afa7c827eb1ccf1c6ebae9b4f5e0c5cc468b.zip
libxl: Convert to asynchronous: device removal
Convert libxl_FOO_device_remove, and the function which does the bulk of the work, libxl__device_remove, to the new async ops scheme. Adjust all callers. Also remove libxl__wait_for_device_state which is now obsolete. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> Committed-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxl/libxl_device.c')
-rw-r--r--tools/libxl/libxl_device.c113
1 files changed, 31 insertions, 82 deletions
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 834375c7ea..c2880e080d 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -356,85 +356,36 @@ int libxl__device_disk_dev_number(const char *virtpath, int *pdisk,
return -1;
}
-/*
- * Returns 0 if a device is removed, ERROR_* if an error
- * or timeout occurred.
- */
-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;
- unsigned int n;
- fd_set rfds;
- char **l1 = NULL;
-
-start:
- rc = 1;
- nfds = xs_fileno(ctx->xsh) + 1;
- FD_ZERO(&rfds);
- FD_SET(xs_fileno(ctx->xsh), &rfds);
- switch (select(nfds, &rfds, NULL, NULL, tv)) {
- case -1:
- if (errno == EINTR)
- goto start;
- rc = ERROR_FAIL;
- break;
- case 0:
- rc = ERROR_TIMEDOUT;
- break;
- default:
- l1 = xs_read_watch(ctx->xsh, &n);
- if (l1 != NULL) {
- char *sstate = libxl__xs_read(gc, XBT_NULL,
- l1[XS_WATCH_PATH]);
- if (!sstate || atoi(sstate) == state) {
- /* Call handler function if present */
- if (handler)
- rc = handler(gc, l1, sstate);
- } else {
- /* State is different than expected, continue waiting... */
- goto start;
- }
- free(l1);
- } else {
- rc = ERROR_FAIL;
- }
- break;
- }
- return rc;
-}
-/*
- * 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]);
+typedef struct {
+ libxl__ao *ao;
+ libxl__ev_devstate ds;
+} libxl__ao_device_remove;
+
+static void device_remove_cleanup(libxl__gc *gc,
+ libxl__ao_device_remove *aorm) {
+ if (!aorm) return;
+ libxl__ev_devstate_cancel(gc, &aorm->ds);
+}
- return 0;
+static void device_remove_callback(libxl__egc *egc, libxl__ev_devstate *ds,
+ int rc) {
+ libxl__ao_device_remove *aorm = CONTAINER_OF(ds, *aorm, ds);
+ libxl__gc *gc = &aorm->ao->gc;
+ libxl__ao_complete(egc, aorm->ao, rc);
+ device_remove_cleanup(gc, aorm);
}
-/*
- * Returns 0 (device already destroyed) or 1 (caller must
- * wait_for_dev_destroy) on success, ERROR_* on fail.
- */
-int libxl__device_remove(libxl__gc *gc, libxl__device *dev, int wait)
+int libxl__initiate_device_remove(libxl__ao *ao, libxl__device *dev)
{
+ AO_GC;
libxl_ctx *ctx = libxl__gc_owner(gc);
xs_transaction_t t;
char *be_path = libxl__device_backend_path(gc, dev);
char *state_path = libxl__sprintf(gc, "%s/state", be_path);
char *state = libxl__xs_read(gc, XBT_NULL, state_path);
int rc = 0;
+ libxl__ao_device_remove *aorm = 0;
if (!state)
goto out;
@@ -457,23 +408,21 @@ retry_transaction:
}
}
- xs_watch(ctx->xsh, state_path, be_path);
libxl__device_destroy_tapdisk(gc, be_path);
- if (wait) {
- struct timeval tv;
- tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
- tv.tv_usec = 0;
- 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));
- } else {
- rc = 1; /* Caller must wait_for_dev_destroy */
- }
+ aorm = libxl__zalloc(gc, sizeof(*aorm));
+ aorm->ao = ao;
+ libxl__ev_devstate_init(&aorm->ds);
-out:
+ rc = libxl__ev_devstate_wait(gc, &aorm->ds, device_remove_callback,
+ state_path, XenbusStateClosed,
+ LIBXL_DESTROY_TIMEOUT * 1000);
+ if (rc) goto out;
+
+ return 0;
+
+ out:
+ device_remove_cleanup(gc, aorm);
return rc;
}