Skip to contentSkip to conversation

Make frontend drivers shutdown cleanly.

PATCH In review Gerd Hoffmann 1 participant 1 message Aug 31, 2006

lore
Share & tools
lore
#0 lore raw

PATCH 3/3 Make frontend drivers shutdown cleanly.

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

Signature · 2 lines
Gerd Hoffmann <[email protected]>
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.

---
 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(-)
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +2 -2
Index: 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);
 }
 
 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +3 -4
Index: 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);
 }
 
 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c +7 -0
Index: 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.
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +27 -2
Index: 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;
linux-2.6-xen-sparse/include/xen/xenbus.h +3 -0
Index: 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
[email protected]
http://lists.xensource.com/xen-devel