WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] libxl: fix device removal handling of wait_for_dev_d

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] libxl: fix device removal handling of wait_for_dev_destroy
From: Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
Date: Tue, 18 Oct 2011 14:55:00 +0200
Cc: ian.campbell@xxxxxxxxxx
Delivery-date: Tue, 18 Oct 2011 06:23:41 -0700
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:content-type:mime-version:content-transfer-encoding:subject :x-mercurial-node:message-id:in-reply-to:references:user-agent:date :from:to:cc; bh=MOpyobnHyWxk21ggtGMWVsLoXYXqg/LBNuk2h0UTwdY=; b=IK/Cjn0TGF3Udqlp6kToufhxqyKoUQGrKoH+/IStuAlaq8e7rISutWs1K5Oh1cYXgG 3qE2d2tfXTgu5Tdj4qyVcvqQSsYgwZI7W3iZD0boW+zY699fUgEFpspp9GkEKyWYeiC6 WlIX1T/7GJf9OmNl/dcsz/s9lf3Rdb7de5/BI=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1318499605@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1318499605@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.9.2
# HG changeset patch
# User Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
# Date 1318942350 -7200
# Node ID 973022eb35ed3c2e58980d8c4482721d4e1d7bab
# Parent  c9c228ec718a4c2d22b58ce306f269868af0d12f
libxl: fix device removal handling of wait_for_dev_destroy

This patch is a fix for Ian Campbell's "libxl: rationalise libxl_device_* APIs" 
and addresses the problem of not handling the return value from destroy 
functions correctly. The return value can represent three different options, 
the device is removed correctly, the device is busy or and error occurred.

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

diff -r c9c228ec718a -r 973022eb35ed tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Thu Oct 13 10:52:46 2011 +0100
+++ b/tools/libxl/libxl_device.c        Tue Oct 18 14:52:30 2011 +0200
@@ -367,6 +367,10 @@ int libxl__device_disk_dev_number(const 
     return -1;
 }
 
+/*
+ * Returns 0 on succesful device removal, 1 if a timeout
+ * happenned and ERROR_* if there was an error
+ */
 static int wait_for_dev_destroy(libxl__gc *gc, struct timeval *tv)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -375,27 +379,47 @@ 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 = 1;
+            break;
+        case 1:
+            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;
+                }
+                free(l1);
+            } else {
+                rc = ERROR_FAIL;
             }
-            free(l1);
-        }
+            break;
     }
     return rc;
 }
 
-/* Returns 0 on success, ERROR_* on fail */
+/* 
+ * Returns 0 on success, ERROR_* on fail and 1 if there's an event
+ * pending (a device has been added to a watch to wait for
+ * disconnection)
+ */
 int libxl__device_remove(libxl__gc *gc, libxl__device *dev, int wait)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -428,16 +452,15 @@ retry_transaction:
 
     xs_watch(ctx->xsh, state_path, be_path);
     libxl__device_destroy_tapdisk(gc, be_path);
+    rc = 1;
 
     if (wait) {
         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);
         xs_rm(ctx->xsh, XBT_NULL, libxl__device_frontend_path(gc, dev));
     }
-
-    rc = 0;
 out:
     return rc;
 }
@@ -496,7 +519,7 @@ int libxl__devices_destroy(libxl__gc *gc
                 if (force) {
                     libxl__device_destroy(gc, &dev);
                 } else {
-                    if (libxl__device_remove(gc, &dev, 0) == 0)
+                    if (libxl__device_remove(gc, &dev, 0) == 1)
                         n_watches++;
                 }
             }
@@ -515,7 +538,7 @@ int libxl__devices_destroy(libxl__gc *gc
         if (force) {
             libxl__device_destroy(gc, &dev);
         } else {
-            if (libxl__device_remove(gc, &dev, 0) == 0)
+            if (libxl__device_remove(gc, &dev, 0) == 1)
                 n_watches++;
         }
     }
@@ -531,7 +554,7 @@ int libxl__devices_destroy(libxl__gc *gc
         tv.tv_usec = 0;
         while (n_watches > 0) {
             if (wait_for_dev_destroy(gc, &tv)) {
-                break;
+                continue;
             } else {
                 n_watches--;
             }

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