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 1/7] libxenlight meta-resend: refactor libxl destroy

To: Stefano Stabellini <Stefano.Stabellini@xxxxxxxxxxxxx>, Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 1/7] libxenlight meta-resend: refactor libxl destroy code
From: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>
Date: Thu, 03 Dec 2009 12:03:14 -0500
Cc:
Delivery-date: Thu, 03 Dec 2009 09:03:41 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <4B16AA93.5090506@xxxxxxxxxxxxxxxx>
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: <4B16AA93.5090506@xxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 2.0.0.23 (X11/20090817)
Refactor libxl device destroy code. Abstract function
waiting for the watch on the state node to fire.
Create a generic device delete function.

Only a single LIBXL_DESTROY_TIMEOUT elapses when
waiting for destruction of all the devices of a
domain.

Signed-off-by: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>


# HG changeset patch
# User Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>
# Date 1259848362 18000
# Node ID ff941d6ded127d8d0bb6e754654140d9e1dfb0b1
# Parent  eeb2f35cd9a7a5a6c4e38c1ec5995524035375fa
Refactor libxl device destroy code. Abstract function
waiting for the watch on the state node to fire.
Create a generic device delete function.

Only a single LIBXL_DESTROY_TIMEOUT elapses when
waiting for destruction of all the devices of a
domain.

Signed-off-by: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>

diff -r eeb2f35cd9a7 -r ff941d6ded12 libxl_device.c
--- a/libxl_device.c
+++ b/libxl_device.c
@@ -203,14 +203,40 @@ retry_transaction:
         return 0;
 }
 
+int wait_for_dev_destroy(struct libxl_ctx *ctx, struct timeval *tv)
+{
+    int nfds, rc;
+    unsigned int n;
+    fd_set rfds;
+    char **l1 = NULL;
+
+    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(ctx, 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]);
+                XL_LOG(ctx, XL_LOG_DEBUG, "Destroyed device backend at %s", 
l1[XS_WATCH_TOKEN]);
+                rc = 0;
+            }
+            libxl_free(ctx, state);
+            free(l1);
+        }
+    }
+    return rc;
+}
+
 int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force)
 {
     char *path, *be_path, *fe_path;
     unsigned int num1, num2;
     char **l1 = NULL, **l2 = NULL;
-    int i, j, nfds, n = 0, n_watches = 0;
-    fd_set rfds;
-    struct timeval tv;
+    int i, j, n = 0, n_watches = 0;
     flexarray_t *toremove;
     struct libxl_ctx clone;
 
@@ -245,27 +271,20 @@ int libxl_devices_destroy(struct libxl_c
         }
     }
     if (!force) {
-        nfds = xs_fileno(clone.xsh) + 1;
-        /* Linux-ism */
+        /* Linux-ism. Most implementations leave the timeout
+         * untouched after select. Linux, however, will chip
+         * away the elapsed time from it, which is what we 
+         * need to enforce a single time span waiting for
+         * device destruction. */
+        struct timeval tv;
         tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
         tv.tv_usec = 0;
-        while (n_watches > 0 && tv.tv_sec > 0) {
-            FD_ZERO(&rfds);
-            FD_SET(xs_fileno(clone.xsh), &rfds);
-            if (select(nfds, &rfds, NULL, NULL, &tv) > 0) {
-                l1 = xs_read_watch(clone.xsh, &num1);
-                if (l1 != NULL) {
-                    char *state = libxl_xs_read(&clone, XBT_NULL, l1[0]);
-                    if (!state || atoi(state) == 6) {
-                        xs_unwatch(clone.xsh, l1[0], l1[1]);
-                        xs_rm(clone.xsh, XBT_NULL, l1[1]);
-                        XL_LOG(&clone, XL_LOG_DEBUG, "Destroyed device backend 
at %s", l1[1]);
-                        n_watches--;
-                    }
-                    free(l1);
-                }
-            } else
+        while (n_watches > 0) {
+            if (wait_for_dev_destroy(&clone, &tv)) {
                 break;
+            } else {
+                n_watches--;
+            }
         }
     }
     for (i = 0; i < n; i++) {
@@ -277,6 +296,49 @@ int libxl_devices_destroy(struct libxl_c
     return 0;
 }
 
+int libxl_device_del(struct libxl_ctx *ctx, libxl_device *dev, int wait)
+{
+    char *dom_path_backend, *backend_path, *hotplug_path;
+    int rc;
+    struct libxl_ctx clone;
+
+    if (libxl_clone_context_xs(ctx, &clone)) {
+        XL_LOG(ctx, XL_LOG_ERROR, "Out of memory when cloning context");
+        return ERROR_NOMEM;
+    }
+
+    /* Create strings */
+    dom_path_backend    = libxl_xs_get_dompath(&clone, dev->backend_domid);
+    backend_path        = libxl_sprintf(&clone, "%s/backend/%s/%u/%d",
+                                    dom_path_backend, 
+                                    string_of_kinds[dev->backend_kind], 
+                                    dev->domid, dev->devid);
+    hotplug_path        = libxl_sprintf(&clone, "/xapi/%d/hotplug/%s/%d",
+                                    dev->domid,
+                                    string_of_kinds[dev->kind], 
+                                    dev->devid);
+    libxl_free(&clone, dom_path_backend);
+
+    rc = libxl_device_destroy(&clone, backend_path, !wait);
+    if (rc == -1) {
+        libxl_discard_cloned_context_xs(&clone);
+        return ERROR_FAIL;
+    }
+
+    if (wait) {
+        struct timeval tv;
+        tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
+        tv.tv_usec = 0;
+        (void)wait_for_dev_destroy(&clone, &tv);
+    }
+
+    xs_rm(clone.xsh, XBT_NULL, hotplug_path);
+    libxl_free(&clone, hotplug_path);
+    libxl_free(&clone, backend_path);
+    libxl_discard_cloned_context_xs(&clone);
+    return 0;
+}
+
 int libxl_device_pci_flr(struct libxl_ctx *ctx, unsigned int domain, unsigned 
int bus,
                          unsigned int dev, unsigned int func)
 {
diff -r eeb2f35cd9a7 -r ff941d6ded12 libxl_internal.h
--- a/libxl_internal.h
+++ b/libxl_internal.h
@@ -124,6 +124,7 @@ int device_disk_dev_number(char *virtpat
 
 int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device,
                              char **bents, char **fents);
+int libxl_device_del(struct libxl_ctx *ctx, libxl_device *dev, int wait);
 int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force);
 int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force);
 int libxl_wait_for_device_model(struct libxl_ctx *ctx,
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>