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

[Xen-changelog] Let dev_changed detect devices when a watch fires with a longer node name.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID b0893b876c8c4c4eb507d48fc1c4af4268ddecde
# Parent  b2f2c08e1222dce282b9483546e49fdff08b59c9
Let dev_changed detect devices when a watch fires with a longer node name.
Also improve device cleanup when the dir for a while frontend domain
is removed.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r b2f2c08e1222 -r b0893b876c8c 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Aug 18 
19:08:09 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Aug 18 
19:15:22 2005
@@ -257,6 +257,34 @@
        return info.dev;
 }
 
+static int cleanup_dev(struct device *dev, void *data)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+       struct xb_find_info *info = data;
+       int len = strlen(info->nodename);
+
+       if (!strncmp(xendev->nodename, info->nodename, len)) {
+               info->dev = xendev;
+               get_device(dev);
+               return 1;
+       }
+       return 0;
+}
+
+static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
+{
+       struct xb_find_info info = { .nodename = path };
+
+       do {
+               info.dev = NULL;
+               bus_for_each_dev(bus, NULL, &info, cleanup_dev);
+               if (info.dev) {
+                       device_unregister(&info.dev->dev);
+                       put_device(&info.dev->dev);
+               }
+       } while (info.dev);
+}
+
 static void xenbus_release_device(struct device *dev)
 {
        if (dev) {
@@ -443,33 +471,54 @@
        return ret;
 }
 
+static int strsep_len(const char *str, char c, unsigned int len)
+{
+       unsigned int i;
+
+       for (i = 0; str[i]; i++)
+               if (str[i] == c) {
+                       if (len == 0)
+                               return i;
+                       len--;
+               }
+       return (len == 0) ? i : -ERANGE;
+}
+
 static void dev_changed(const char *node, struct xen_bus_type *bus)
 {
-       int exists;
+       int exists, rootlen;
        struct xenbus_device *dev;
        char type[BUS_ID_SIZE];
-       const char *p;
-
-       /* FIXME: wouldn't need this if we could limit watch depth. */
-       if (char_count(node, '/') != bus->levels)
+       const char *p, *root;
+
+       if (char_count(node, '/') < 2)
+               return;
+
+       exists = xenbus_exists(node, "");
+       if (!exists) {
+               xenbus_cleanup_devices(node, &bus->bus);
                return;
+       }
 
        /* backend/<type>/... or device/<type>/... */
        p = strchr(node, '/') + 1;
        snprintf(type, BUS_ID_SIZE, "%.*s", strcspn(p, "/"), p);
        type[BUS_ID_SIZE-1] = '\0';
 
-       /* Created or deleted? */
-       exists = xenbus_exists(node, "");
-       dev = xenbus_device_find(node, &bus->bus);
-
-       if (dev && !exists) {
-               device_unregister(&dev->dev);
-       } else if (!dev && exists) {
-               xenbus_probe_node(bus, type, node);
-       }
-       if (dev)
+       rootlen = strsep_len(node, '/', bus->levels);
+       if (rootlen < 0)
+               return;
+       root = kasprintf("%.*s", rootlen, node);
+       if (!root)
+               return;
+
+       dev = xenbus_device_find(root, &bus->bus);
+       if (!dev)
+               xenbus_probe_node(bus, type, root);
+       else
                put_device(&dev->dev);
+
+       kfree(root);
 }
 
 static void frontend_changed(struct xenbus_watch *watch, const char *node)
@@ -484,7 +533,6 @@
 
 /* We watch for devices appearing and vanishing. */
 static struct xenbus_watch fe_watch = {
-       /* FIXME: Ideally we'd only watch for changes 2 levels deep... */
        .node = "device",
        .callback = frontend_changed,
 };

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


 


Rackspace

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