[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XENBUS] Make frontend drivers shutdown cleanly.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |