ia64/xen-unstable

changeset 11407:90d3ca978b40

[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@suse.de>
author kaf24@firebug.cl.cam.ac.uk
date Fri Sep 01 00:42:14 2006 +0100 (2006-09-01)
parents 98a81d2ccf4c
children 37a42856e8d9
files linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/include/xen/xenbus.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Sep 01 00:33:19 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Sep 01 00:42:14 2006 +0100
     1.3 @@ -273,7 +273,7 @@ static void backend_changed(struct xenbu
     1.4  			xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
     1.5  
     1.6  		down(&bd->bd_sem);
     1.7 -		if (info->users > 0)
     1.8 +		if (info->users > 0 && system_state == SYSTEM_RUNNING)
     1.9  			xenbus_dev_error(dev, -EBUSY,
    1.10  					 "Device in use; refusing to close");
    1.11  		else
    1.12 @@ -360,7 +360,7 @@ static void blkfront_closing(struct xenb
    1.13  
    1.14  	xlvbd_del(info);
    1.15  
    1.16 -	xenbus_switch_state(dev, XenbusStateClosed);
    1.17 +	xenbus_frontend_closed(dev);
    1.18  }
    1.19  
    1.20  
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Sep 01 00:33:19 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Sep 01 00:42:14 2006 +0100
     2.3 @@ -486,7 +486,7 @@ static void backend_changed(struct xenbu
     2.4  	struct netfront_info *np = dev->dev.driver_data;
     2.5  	struct net_device *netdev = np->netdev;
     2.6  
     2.7 -	DPRINTK("\n");
     2.8 +	DPRINTK("%s\n", xenbus_strstate(backend_state));
     2.9  
    2.10  	switch (backend_state) {
    2.11  	case XenbusStateInitialising:
    2.12 @@ -1936,11 +1936,10 @@ static void netfront_closing(struct xenb
    2.13  {
    2.14  	struct netfront_info *info = dev->dev.driver_data;
    2.15  
    2.16 -	DPRINTK("netfront_closing: %s removed\n", dev->nodename);
    2.17 +	DPRINTK("%s\n", dev->nodename);
    2.18  
    2.19  	close_netdev(info);
    2.20 -
    2.21 -	xenbus_switch_state(dev, XenbusStateClosed);
    2.22 +	xenbus_frontend_closed(dev);
    2.23  }
    2.24  
    2.25  
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Fri Sep 01 00:33:19 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Fri Sep 01 00:42:14 2006 +0100
     3.3 @@ -138,6 +138,13 @@ int xenbus_switch_state(struct xenbus_de
     3.4  }
     3.5  EXPORT_SYMBOL_GPL(xenbus_switch_state);
     3.6  
     3.7 +int xenbus_frontend_closed(struct xenbus_device *dev)
     3.8 +{
     3.9 +	xenbus_switch_state(dev, XenbusStateClosed);
    3.10 +	complete(&dev->down);
    3.11 +	return 0;
    3.12 +}
    3.13 +EXPORT_SYMBOL_GPL(xenbus_frontend_closed);
    3.14  
    3.15  /**
    3.16   * Return the path to the error node for the given device, or NULL on failure.
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Sep 01 00:33:19 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Sep 01 00:42:14 2006 +0100
     4.3 @@ -73,6 +73,7 @@ static int xenbus_probe_backend(const ch
     4.4  
     4.5  static int xenbus_dev_probe(struct device *_dev);
     4.6  static int xenbus_dev_remove(struct device *_dev);
     4.7 +static void xenbus_dev_shutdown(struct device *_dev);
     4.8  
     4.9  /* If something in array of ids matches this device, return it. */
    4.10  static const struct xenbus_device_id *
    4.11 @@ -192,6 +193,7 @@ static struct xen_bus_type xenbus_fronte
    4.12  		.match    = xenbus_match,
    4.13  		.probe    = xenbus_dev_probe,
    4.14  		.remove   = xenbus_dev_remove,
    4.15 +		.shutdown = xenbus_dev_shutdown,
    4.16  	},
    4.17  	.dev = {
    4.18  		.bus_id = "xen",
    4.19 @@ -246,6 +248,7 @@ static struct xen_bus_type xenbus_backen
    4.20  		.match    = xenbus_match,
    4.21  		.probe    = xenbus_dev_probe,
    4.22  		.remove   = xenbus_dev_remove,
    4.23 +//		.shutdown = xenbus_dev_shutdown,
    4.24  		.uevent   = xenbus_uevent_backend,
    4.25  	},
    4.26  	.dev = {
    4.27 @@ -349,7 +352,7 @@ static int xenbus_dev_probe(struct devic
    4.28  	const struct xenbus_device_id *id;
    4.29  	int err;
    4.30  
    4.31 -	DPRINTK("");
    4.32 +	DPRINTK("%s", dev->nodename);
    4.33  
    4.34  	if (!drv->probe) {
    4.35  		err = -ENODEV;
    4.36 @@ -394,7 +397,7 @@ static int xenbus_dev_remove(struct devi
    4.37  	struct xenbus_device *dev = to_xenbus_device(_dev);
    4.38  	struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
    4.39  
    4.40 -	DPRINTK("");
    4.41 +	DPRINTK("%s", dev->nodename);
    4.42  
    4.43  	free_otherend_watch(dev);
    4.44  	free_otherend_details(dev);
    4.45 @@ -406,6 +409,27 @@ static int xenbus_dev_remove(struct devi
    4.46  	return 0;
    4.47  }
    4.48  
    4.49 +static void xenbus_dev_shutdown(struct device *_dev)
    4.50 +{
    4.51 +	struct xenbus_device *dev = to_xenbus_device(_dev);
    4.52 +	unsigned long timeout = 5*HZ;
    4.53 +
    4.54 +	DPRINTK("%s", dev->nodename);
    4.55 +
    4.56 +	get_device(&dev->dev);
    4.57 +	if (dev->state != XenbusStateConnected) {
    4.58 +		printk("%s: %s: %s != Connected, skipping\n", __FUNCTION__,
    4.59 +		       dev->nodename, xenbus_strstate(dev->state));
    4.60 +		goto out;
    4.61 +	}
    4.62 +	xenbus_switch_state(dev, XenbusStateClosing);
    4.63 +	timeout = wait_for_completion_timeout(&dev->down, timeout);
    4.64 +	if (!timeout)
    4.65 +		printk("%s: %s timeout closing device\n", __FUNCTION__, dev->nodename);
    4.66 + out:
    4.67 +	put_device(&dev->dev);
    4.68 +}
    4.69 +
    4.70  static int xenbus_register_driver_common(struct xenbus_driver *drv,
    4.71  					 struct xen_bus_type *bus)
    4.72  {
    4.73 @@ -588,6 +612,7 @@ static int xenbus_probe_node(struct xen_
    4.74  	tmpstring += strlen(tmpstring) + 1;
    4.75  	strcpy(tmpstring, type);
    4.76  	xendev->devicetype = tmpstring;
    4.77 +	init_completion(&xendev->down);
    4.78  
    4.79  	xendev->dev.parent = &bus->dev;
    4.80  	xendev->dev.bus = &bus->bus;
     5.1 --- a/linux-2.6-xen-sparse/include/xen/xenbus.h	Fri Sep 01 00:33:19 2006 +0100
     5.2 +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h	Fri Sep 01 00:42:14 2006 +0100
     5.3 @@ -37,6 +37,7 @@
     5.4  #include <linux/device.h>
     5.5  #include <linux/notifier.h>
     5.6  #include <linux/mutex.h>
     5.7 +#include <linux/completion.h>
     5.8  #include <xen/interface/xen.h>
     5.9  #include <xen/interface/grant_table.h>
    5.10  #include <xen/interface/io/xenbus.h>
    5.11 @@ -74,6 +75,7 @@ struct xenbus_device {
    5.12  	struct xenbus_watch otherend_watch;
    5.13  	struct device dev;
    5.14  	enum xenbus_state state;
    5.15 +	struct completion down;
    5.16  };
    5.17  
    5.18  static inline struct xenbus_device *to_xenbus_device(struct device *dev)
    5.19 @@ -299,5 +301,6 @@ int __init xenbus_dev_init(void);
    5.20  
    5.21  char *xenbus_strstate(enum xenbus_state state);
    5.22  int xenbus_dev_is_online(struct xenbus_device *dev);
    5.23 +int xenbus_frontend_closed(struct xenbus_device *dev);
    5.24  
    5.25  #endif /* _XEN_XENBUS_H */