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

[Xen-devel] [PATCH] libxl: add custom disconnect functions for different device types



# HG changeset patch
# User Roger Pau Monne <roger.pau@xxxxxxxxxxxxx>
# Date 1316778937 -7200
# Node ID 1d42b1b355c231e794a56dfadf3ee450346e3516
# Parent  0ab9f548890e5e58122f73aa1c4164fd6e319b1c
libxl: add custom disconnect functions for different device types.

This patch creates a new struct, called libxl__disconnect that can be used to 
assign different functions that will be called to check if the device is 
disconnected and to add it to the shutdown watch. Added a helper function to 
get the libxl__device_kind from a be_path. The only device that has a different 
shutdown mechanism right now is vbd.

diff -r 0ab9f548890e -r 1d42b1b355c2 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Fri Sep 23 13:31:51 2011 +0200
+++ b/tools/libxl/libxl_device.c        Fri Sep 23 13:55:37 2011 +0200
@@ -38,6 +38,27 @@ static const char *string_of_kinds[] = {
     [DEVICE_CONSOLE] = "console",
 };
 
+static const libxl__disconnect disconnect_vbd = {
+    .watch_for_disconnect = libxl__watch_for_disconnect_vbd,
+    .has_disconnected = libxl__has_disconnected_vbd,
+};
+
+static const libxl__disconnect disconnect_generic = {
+    .watch_for_disconnect = libxl__watch_for_disconnect_generic,
+    .has_disconnected = libxl__has_disconnected_generic,
+};
+
+static const libxl__disconnect *disconnect_ops[] = {
+    [DEVICE_UNKNOWN] = &disconnect_generic,
+    [DEVICE_VIF] = &disconnect_generic,
+    [DEVICE_VBD] = &disconnect_vbd,
+    [DEVICE_QDISK] = &disconnect_generic,
+    [DEVICE_PCI] = &disconnect_generic,
+    [DEVICE_VFB] = &disconnect_generic,
+    [DEVICE_VKBD] = &disconnect_generic,
+    [DEVICE_CONSOLE] = &disconnect_generic,
+};
+
 char *libxl__device_frontend_path(libxl__gc *gc, libxl__device *device)
 {
     char *dom_path = libxl__xs_get_dompath(gc, device->domid);
@@ -59,6 +80,18 @@ char *libxl__device_backend_path(libxl__
                           device->domid, device->devid);
 }
 
+libxl__device_kinds libxl__device_identify(char *be_path)
+{
+    int len = sizeof(string_of_kinds)/sizeof(char *);
+
+    for (int j = 1; j < len; j++) {
+        if (strstr(be_path, string_of_kinds[j]))
+            return j;
+    }
+
+    return DEVICE_UNKNOWN;
+}
+
 int libxl__device_generic_add(libxl__gc *gc, libxl__device *device,
                              char **bents, char **fents)
 {
@@ -371,15 +404,11 @@ int libxl__device_destroy(libxl__gc *gc,
     libxl_ctx *ctx = libxl__gc_owner(gc);
     xs_transaction_t t;
     char *state_path = libxl__sprintf(gc, "%s/state", be_path);
-    char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+    libxl__device_kinds device_type = libxl__device_identify(be_path);
     int rc = 0;
 
-    if (!state)
+    if (disconnect_ops[device_type]->has_disconnected(gc, be_path))
         goto out;
-    if (atoi(state) != 4) {
-        xs_rm(ctx->xsh, XBT_NULL, be_path);
-        goto out;
-    }
 
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
@@ -394,7 +423,7 @@ retry_transaction:
         }
     }
     if (!force) {
-        xs_watch(ctx->xsh, state_path, be_path);
+        disconnect_ops[device_type]->watch_for_disconnect(gc, be_path);
         rc = 1;
     } else {
         xs_rm(ctx->xsh, XBT_NULL, be_path);
@@ -410,6 +439,7 @@ static int wait_for_dev_destroy(libxl__g
     unsigned int n;
     fd_set rfds;
     char **l1 = NULL;
+    libxl__device_kinds device_type;
 
     rc = 1;
     nfds = xs_fileno(ctx->xsh) + 1;
@@ -418,11 +448,9 @@ static int wait_for_dev_destroy(libxl__g
     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) {
+            device_type = libxl__device_identify(l1[XS_WATCH_TOKEN]);
+            if (disconnect_ops[device_type]->has_disconnected(gc, 
l1[XS_WATCH_TOKEN])) {
                 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);
@@ -528,6 +556,62 @@ out:
     return rc;
 }
 
+int libxl__watch_for_disconnect_vbd(libxl__gc *gc, char *be_path)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *hotplug_path = libxl__sprintf(gc, "%s/hotplug-status", be_path);
+
+    xs_watch(ctx->xsh, hotplug_path, be_path);
+
+    return 1;
+}
+
+int libxl__has_disconnected_vbd(libxl__gc *gc, char *be_path)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *hotplug_path = libxl__sprintf(gc, "%s/hotplug-status", be_path);
+    char *hotplug = libxl__xs_read(gc, XBT_NULL, hotplug_path);
+    int rc = 0;
+
+    if (!hotplug || !strcmp(hotplug, "disconnected")) {
+        xs_rm(ctx->xsh, XBT_NULL, be_path);
+        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+            "Destroyed device backend at %s",
+            be_path);
+        rc = 1;
+    }
+
+    return rc;
+}
+
+int libxl__watch_for_disconnect_generic(libxl__gc *gc, char *be_path)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *state_path = libxl__sprintf(gc, "%s/state", be_path);
+
+    xs_watch(ctx->xsh, state_path, be_path);
+
+    return 1;
+}
+
+int libxl__has_disconnected_generic(libxl__gc *gc, char *be_path)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *state_path = libxl__sprintf(gc, "%s/state", be_path);
+    char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+    int rc = 0;
+
+    if (!state || atoi(state) != 4) {
+        xs_rm(ctx->xsh, XBT_NULL, be_path);
+        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+            "Destroyed device backend at %s",
+            be_path);
+        rc = 1;
+    }
+
+    return rc;
+}
+
 int libxl__wait_for_device_model(libxl__gc *gc,
                                  uint32_t domid, char *state,
                                  libxl__device_model_starting *starting,
diff -r 0ab9f548890e -r 1d42b1b355c2 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Fri Sep 23 13:31:51 2011 +0200
+++ b/tools/libxl/libxl_internal.h      Fri Sep 23 13:55:37 2011 +0200
@@ -95,7 +95,8 @@ struct libxl__ctx {
 };
 
 typedef enum {
-    DEVICE_VIF = 1,
+    DEVICE_UNKNOWN = 0,
+    DEVICE_VIF,
     DEVICE_VBD,
     DEVICE_QDISK,
     DEVICE_PCI,
@@ -206,6 +207,12 @@ _hidden int libxl__domain_save_device_mo
 _hidden void libxl__userdata_destroyall(libxl__gc *gc, uint32_t domid);
 
 /* from xl_device */
+
+typedef struct {
+    int (*watch_for_disconnect)(libxl__gc *gc, char *be_path);
+    int (*has_disconnected)(libxl__gc *gc, char *be_path);
+} libxl__disconnect;
+
 _hidden char *libxl__device_disk_string_of_backend(libxl_disk_backend backend);
 _hidden char *libxl__device_disk_string_of_format(libxl_disk_format format);
 _hidden int libxl__device_disk_set_backend(libxl__gc*, libxl_device_disk*);
@@ -226,6 +233,11 @@ _hidden int libxl__device_del(libxl__gc 
 _hidden int libxl__device_destroy(libxl__gc *gc, char *be_path, int force);
 _hidden int libxl__devices_destroy(libxl__gc *gc, uint32_t domid, int force);
 _hidden int libxl__wait_for_backend(libxl__gc *gc, char *be_path, char *state);
+_hidden int libxl__watch_for_disconnect_vbd(libxl__gc *gc, char *be_path);
+_hidden int libxl__has_disconnected_vbd(libxl__gc *gc, char *be_path);
+_hidden int libxl__watch_for_disconnect_generic(libxl__gc *gc, char *be_path);
+_hidden int libxl__has_disconnected_generic(libxl__gc *gc, char *be_path);
+_hidden libxl__device_kinds libxl__device_identify(char *be_path);
 
 /* from libxl_pci */
 

_______________________________________________
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®.