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

[Xen-changelog] Add watch for dynamic add/remove of devices.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID bd0ff9b1ea14d4c2b643dc3b094dd1debb049ffd
# Parent  42e8937a93f077f31b7d687308d7789c039dbd77
Add watch for dynamic add/remove of devices.
Signed-off-by: Rusty Russel <rusty@xxxxxxxxxxxxxxx>
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r 42e8937a93f0 -r bd0ff9b1ea14 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jul 26 
17:04:33 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Tue Jul 26 
17:07:05 2005
@@ -121,8 +121,6 @@
        struct xenbus_device *xendev;
        unsigned int stringlen;
 
-       /* FIXME: This could be a rescan. Don't re-register existing devices. */
-
        /* Nodename: /device/<typename>/<name>/ */
        stringlen = strlen(dirpath) + strlen(devicetype) + strlen(name) + 3;
        /* Typename */
@@ -195,6 +193,58 @@
        return err;
 }
 
+/* FIXME: When all tools use transactions, we can ignore events on
+ * subpaths. */
+static void dev_changed(struct xenbus_watch *watch, const char *node)
+{
+       char busid[BUS_ID_SIZE];
+       unsigned int typelen, idlen;
+       int exists;
+       struct device *dev;
+       char *type;
+
+       /* Node is of form device/<type>/<identifier>[/...] */
+       type = strchr(node, '/');
+       if (!type)
+               return;
+       type++;
+
+       typelen = strcspn(type, "/");
+       if (!typelen)
+               return;
+       idlen = strcspn(type + typelen + 1, "/");
+       if (!idlen)
+               return;
+       if (typelen + strlen("-") + idlen + 1 > BUS_ID_SIZE) {
+               printk("Device for node %s is too big!\n", node);
+               return;
+       }
+
+       /* Create it with a / so we can see if it exists. */
+       sprintf(busid, "%.*s/%.*s", typelen, type, idlen, type + typelen + 1);
+       exists = xenbus_exists("device", busid);
+       busid[typelen] = '-';
+
+       dev = device_find(busid, &xenbus_type);
+       if (dev && !exists) {
+               printk("xenbus: Unregistering device %s\n", busid);
+               /* FIXME: free? */
+               device_unregister(dev);
+       }
+       if (!dev && exists) {
+               printk("xenbus: Adding device %s\n", busid);
+               busid[typelen] = '\0';
+               xenbus_probe_device("device", busid, busid+typelen+1);
+       }
+}
+
+/* We watch for devices appearing and vanishing. */
+static struct xenbus_watch dev_watch = {
+       /* FIXME: Ideally we'd only watch for changes 2 levels deep... */
+       .node = "device",
+       .callback = dev_changed,
+};
+
 /* called from a thread in privcmd/privcmd.c */
 int do_xenbus_probe(void *unused)
 {
@@ -211,6 +261,8 @@
 
        /* Enumerate devices in xenstore. */
        xenbus_probe_devices("device");
+
+       register_xenbus_watch(&dev_watch);
        return 0;
 }
 

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