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

[Xen-devel] [patch 3/3] Make frontend drivers shutdown cleanly.


  • To: Xen devel list <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: Gerd Hoffmann <kraxel@xxxxxxx>
  • Date: Thu, 31 Aug 2006 09:42:41 +0200
  • Delivery-date: Thu, 31 Aug 2006 00:43:07 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

  Hi,

This patch makes frontend drivers being shutdown when devices_shutdown()
is called and walks down the device tree.  Most of it is handled by the
xenbus core, which got a new function for the bus->shutdown callback.

please apply,

  Gerd

-- 
Gerd Hoffmann <kraxel@xxxxxxx>
http://www.suse.de/~kraxel/julika-dora.jpeg
Make frontend drivers shutdown cleanly.

This patch makes frontend drivers being shutdown when devices_shutdown()
is called and walks down the device tree.  Most of it is handled by the
xenbus core, which got a new function for the bus->shutdown callback.

Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxx>
---
 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c    |    4 +-
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c    |    7 +--
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c |    7 +++
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c  |   29 ++++++++++++++--
 linux-2.6-xen-sparse/include/xen/xenbus.h               |    3 +
 5 files changed, 42 insertions(+), 8 deletions(-)

Index: 
build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
===================================================================
--- 
build-32-unstable-11286.orig/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
+++ build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
@@ -273,7 +273,7 @@ static void backend_changed(struct xenbu
                        xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
 
                down(&bd->bd_sem);
-               if (info->users > 0)
+               if (info->users > 0 && system_state == SYSTEM_RUNNING)
                        xenbus_dev_error(dev, -EBUSY,
                                         "Device in use; refusing to close");
                else
@@ -360,7 +360,7 @@ static void blkfront_closing(struct xenb
 
        xlvbd_del(info);
 
-       xenbus_switch_state(dev, XenbusStateClosed);
+       xenbus_closing_done(dev);
 }
 
 
Index: 
build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
===================================================================
--- 
build-32-unstable-11286.orig/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
+++ build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
@@ -486,7 +486,7 @@ static void backend_changed(struct xenbu
        struct netfront_info *np = dev->dev.driver_data;
        struct net_device *netdev = np->netdev;
 
-       DPRINTK("\n");
+       DPRINTK("%s\n", xenbus_strstate(backend_state));
 
        switch (backend_state) {
        case XenbusStateInitialising:
@@ -1936,11 +1936,10 @@ static void netfront_closing(struct xenb
 {
        struct netfront_info *info = dev->dev.driver_data;
 
-       DPRINTK("netfront_closing: %s removed\n", dev->nodename);
+       DPRINTK("%s\n", dev->nodename);
 
        close_netdev(info);
-
-       xenbus_switch_state(dev, XenbusStateClosed);
+       xenbus_closing_done(dev);
 }
 
 
Index: 
build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
===================================================================
--- 
build-32-unstable-11286.orig/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
+++ 
build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
@@ -139,6 +139,13 @@ int xenbus_switch_state(struct xenbus_de
 }
 EXPORT_SYMBOL_GPL(xenbus_switch_state);
 
+int xenbus_closing_done(struct xenbus_device *dev)
+{
+       xenbus_switch_state(dev, XenbusStateClosed);
+       complete(&dev->down);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(xenbus_closing_done);
 
 /**
  * Return the path to the error node for the given device, or NULL on failure.
Index: 
build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
===================================================================
--- 
build-32-unstable-11286.orig/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
+++ 
build-32-unstable-11286/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
@@ -73,6 +73,7 @@ static int xenbus_probe_backend(const ch
 
 static int xenbus_dev_probe(struct device *_dev);
 static int xenbus_dev_remove(struct device *_dev);
+static void xenbus_dev_shutdown(struct device *_dev);
 
 /* If something in array of ids matches this device, return it. */
 static const struct xenbus_device_id *
@@ -192,6 +193,7 @@ static struct xen_bus_type xenbus_fronte
                .match    = xenbus_match,
                .probe    = xenbus_dev_probe,
                .remove   = xenbus_dev_remove,
+               .shutdown = xenbus_dev_shutdown,
        },
        .dev = {
                .bus_id = "xen",
@@ -246,6 +248,7 @@ static struct xen_bus_type xenbus_backen
                .match    = xenbus_match,
                .probe    = xenbus_dev_probe,
                .remove   = xenbus_dev_remove,
+//             .shutdown = xenbus_dev_shutdown,
                .uevent   = xenbus_uevent_backend,
        },
        .dev = {
@@ -348,7 +351,7 @@ static int xenbus_dev_probe(struct devic
        const struct xenbus_device_id *id;
        int err;
 
-       DPRINTK("");
+       DPRINTK("%s", dev->nodename);
 
        if (!drv->probe) {
                err = -ENODEV;
@@ -393,7 +396,7 @@ static int xenbus_dev_remove(struct devi
        struct xenbus_device *dev = to_xenbus_device(_dev);
        struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
 
-       DPRINTK("");
+       DPRINTK("%s", dev->nodename);
 
        free_otherend_watch(dev);
        free_otherend_details(dev);
@@ -405,6 +408,27 @@ static int xenbus_dev_remove(struct devi
        return 0;
 }
 
+static void xenbus_dev_shutdown(struct device *_dev)
+{
+       struct xenbus_device *dev = to_xenbus_device(_dev);
+       unsigned long timeout = 5*HZ;
+
+       DPRINTK("%s", dev->nodename);
+
+       get_device(&dev->dev);
+       if (dev->state != XenbusStateConnected) {
+               printk("%s: %s: %s != Connected, skipping\n", __FUNCTION__,
+                      dev->nodename, xenbus_strstate(dev->state));
+               goto out;
+       }
+       xenbus_switch_state(dev, XenbusStateClosing);
+       timeout = wait_for_completion_timeout(&dev->down, timeout);
+       if (!timeout)
+               printk("%s: %s timeout closing device\n", __FUNCTION__, 
dev->nodename);
+ out:
+       put_device(&dev->dev);
+}
+
 static int xenbus_register_driver_common(struct xenbus_driver *drv,
                                         struct xen_bus_type *bus)
 {
@@ -587,6 +611,7 @@ static int xenbus_probe_node(struct xen_
        tmpstring += strlen(tmpstring) + 1;
        strcpy(tmpstring, type);
        xendev->devicetype = tmpstring;
+       init_completion(&xendev->down);
 
        xendev->dev.parent = &bus->dev;
        xendev->dev.bus = &bus->bus;
Index: build-32-unstable-11286/linux-2.6-xen-sparse/include/xen/xenbus.h
===================================================================
--- build-32-unstable-11286.orig/linux-2.6-xen-sparse/include/xen/xenbus.h
+++ build-32-unstable-11286/linux-2.6-xen-sparse/include/xen/xenbus.h
@@ -37,6 +37,7 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/mutex.h>
+#include <linux/completion.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/xenbus.h>
@@ -74,6 +75,7 @@ struct xenbus_device {
        struct xenbus_watch otherend_watch;
        struct device dev;
        enum xenbus_state state;
+       struct completion down;
 };
 
 static inline struct xenbus_device *to_xenbus_device(struct device *dev)
@@ -299,5 +301,6 @@ int __init xenbus_dev_init(void);
 
 char *xenbus_strstate(enum xenbus_state state);
 int xenbus_dev_is_online(struct xenbus_device *dev);
+int xenbus_closing_done(struct xenbus_device *dev);
 
 #endif /* _XEN_XENBUS_H */
_______________________________________________
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®.