# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 90d3ca978b4090c3ac3ad7586fa71362352ea8ae
# Parent 98a81d2ccf4c7aa9fc70aeafbe87dd67fa17a746
[XENBUS] 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(-)
diff -r 98a81d2ccf4c -r 90d3ca978b40
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Sep 01
00:33:19 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Sep 01
00:42:14 2006 +0100
@@ -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_frontend_closed(dev);
}
diff -r 98a81d2ccf4c -r 90d3ca978b40
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Sep 01
00:33:19 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Sep 01
00:42:14 2006 +0100
@@ -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_frontend_closed(dev);
}
diff -r 98a81d2ccf4c -r 90d3ca978b40
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Fri Sep 01
00:33:19 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c Fri Sep 01
00:42:14 2006 +0100
@@ -138,6 +138,13 @@ int xenbus_switch_state(struct xenbus_de
}
EXPORT_SYMBOL_GPL(xenbus_switch_state);
+int xenbus_frontend_closed(struct xenbus_device *dev)
+{
+ xenbus_switch_state(dev, XenbusStateClosed);
+ complete(&dev->down);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(xenbus_frontend_closed);
/**
* Return the path to the error node for the given device, or NULL on failure.
diff -r 98a81d2ccf4c -r 90d3ca978b40
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Sep 01
00:33:19 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Sep 01
00:42:14 2006 +0100
@@ -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 = {
@@ -349,7 +352,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;
@@ -394,7 +397,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);
@@ -404,6 +407,27 @@ static int xenbus_dev_remove(struct devi
xenbus_switch_state(dev, XenbusStateClosed);
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,
@@ -588,6 +612,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;
diff -r 98a81d2ccf4c -r 90d3ca978b40 linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Fri Sep 01 00:33:19 2006 +0100
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Fri Sep 01 00:42:14 2006 +0100
@@ -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_frontend_closed(struct xenbus_device *dev);
#endif /* _XEN_XENBUS_H */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|