[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2] libxl: handle the return value of wait_for_dev_destroy select and pass it to caller function



# HG changeset patch
# User Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
# Date 1319033430 -7200
# Node ID 52c8717d2e0841e08e3569ca7bdac0b8309b6cf2
# Parent  a2a3c4d7333ec15b818b3403f148ad61c254ea82
libxl: handle the return value of wait_for_dev_destroy select and pass it to 
caller function.

Handle the return value of the select call inside wait_for_dev_destroy 
properly, and return 0 if a device is removed, or ERROR_* if a timeout or error 
happened. Use the return value of wait_for_dev_destroy inside 
libxl__device_remove to properly return from that function.

This patch should be applied after Ian Campbell's v3 "libxl: rationalise 
libxl_device_* APIs".

Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>

diff -r a2a3c4d7333e -r 52c8717d2e08 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Tue Oct 18 13:36:43 2011 +0100
+++ b/tools/libxl/libxl.h       Wed Oct 19 16:10:30 2011 +0200
@@ -221,6 +221,7 @@ enum {
     ERROR_INVAL = -6,
     ERROR_BADFAIL = -7,
     ERROR_GUEST_TIMEDOUT = -8,
+    ERROR_TIMEDOUT = -9,
 };
 
 #define LIBXL_VERSION 0
diff -r a2a3c4d7333e -r 52c8717d2e08 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Tue Oct 18 13:36:43 2011 +0100
+++ b/tools/libxl/libxl_device.c        Wed Oct 19 16:10:30 2011 +0200
@@ -367,6 +367,10 @@ int libxl__device_disk_dev_number(const 
     return -1;
 }
 
+/*
+ * 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)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -375,22 +379,41 @@ static int wait_for_dev_destroy(libxl__g
     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);
-    if (select(nfds, &rfds, NULL, NULL, tv) > 0) {
-        l1 = xs_read_watch(ctx->xsh, &n);
-        if (l1 != NULL) {
-            char *state = 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;
+    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 *state = 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;
+                } else {
+                    /* State is not "disconnected", continue waiting... */
+                    goto start;
+                }
+                free(l1);
+            } else {
+                rc = ERROR_FAIL;
             }
-            free(l1);
-        }
+            break;
     }
     return rc;
 }
@@ -436,7 +459,9 @@ retry_transaction:
         struct timeval tv;
         tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
         tv.tv_usec = 0;
-        (void)wait_for_dev_destroy(gc, &tv);
+        rc = wait_for_dev_destroy(gc, &tv);
+        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 */
@@ -542,7 +567,8 @@ int libxl__devices_destroy(libxl__gc *gc
         tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
         tv.tv_usec = 0;
         while (n_watches > 0) {
-            if (wait_for_dev_destroy(gc, &tv)) {
+            if (wait_for_dev_destroy(gc, &tv) < 0) {
+                /* function returned ERROR_* */
                 break;
             } else {
                 n_watches--;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.