# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 98a81d2ccf4c7aa9fc70aeafbe87dd67fa17a746
# Parent e036feb6a4ff4add8eb7cb7aa7cd457812578da2
[XENBUS] Introduce new "online" node for backend drivers.
Driver changes: Make backend drivers check it when entering Closed
state, only unregister devices when the "online" node is either "0" or
not present. The later maintains backward compatibility.
Tools changes: Update "online" node when creating and hot-unplugging
devices.
Background: When kexec'ing a new kernel, the old kernel's frontend
driver will shutdown, but the backend device should *NOT* disappear
due to that, so the new kernel instance can reconnect.
Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c | 10 +++-
linux-2.6-xen-sparse/drivers/xen/blktap/common.h | 1
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 23
++++++----
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 16 ++++++
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 10 +++-
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c | 12 +++++
linux-2.6-xen-sparse/include/xen/xenbus.h | 1
tools/python/xen/xend/server/DevController.py | 6 ++
8 files changed, 62 insertions(+), 17 deletions(-)
diff -r e036feb6a4ff -r 98a81d2ccf4c
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Sep 01 00:20:42
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Fri Sep 01 00:33:19
2006 +0100
@@ -301,11 +301,11 @@ static void frontend_changed(struct xenb
struct backend_info *be = dev->dev.driver_data;
int err;
- DPRINTK("");
+ DPRINTK("%s", xenbus_strstate(frontend_state));
switch (frontend_state) {
case XenbusStateInitialising:
- if (dev->state == XenbusStateClosing) {
+ if (dev->state == XenbusStateClosed) {
printk("%s: %s: prepare for reconnect\n",
__FUNCTION__, dev->nodename);
xenbus_switch_state(dev, XenbusStateInitWait);
@@ -331,8 +331,12 @@ static void frontend_changed(struct xenb
xenbus_switch_state(dev, XenbusStateClosing);
break;
+ case XenbusStateClosed:
+ xenbus_switch_state(dev, XenbusStateClosed);
+ if (xenbus_dev_is_online(dev))
+ break;
+ /* fall through if not online */
case XenbusStateUnknown:
- case XenbusStateClosed:
device_unregister(&dev->dev);
break;
diff -r e036feb6a4ff -r 98a81d2ccf4c
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Fri Sep 01 00:20:42
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Fri Sep 01 00:33:19
2006 +0100
@@ -91,6 +91,7 @@ void tap_blkif_free(blkif_t *blkif);
void tap_blkif_free(blkif_t *blkif);
int tap_blkif_map(blkif_t *blkif, unsigned long shared_page,
unsigned int evtchn);
+void tap_blkif_unmap(blkif_t *blkif);
#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
#define blkif_put(_b) \
diff -r e036feb6a4ff -r 98a81d2ccf4c
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Fri Sep 01
00:20:42 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Fri Sep 01
00:33:19 2006 +0100
@@ -135,20 +135,25 @@ int tap_blkif_map(blkif_t *blkif, unsign
return 0;
}
+void tap_blkif_unmap(blkif_t *blkif)
+{
+ if (blkif->irq) {
+ unbind_from_irqhandler(blkif->irq, blkif);
+ blkif->irq = 0;
+ }
+ if (blkif->blk_ring.sring) {
+ unmap_frontend_page(blkif);
+ free_vm_area(blkif->blk_ring_area);
+ blkif->blk_ring.sring = NULL;
+ }
+}
+
void tap_blkif_free(blkif_t *blkif)
{
atomic_dec(&blkif->refcnt);
wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
- /* Already disconnected? */
- if (blkif->irq)
- unbind_from_irqhandler(blkif->irq, blkif);
-
- if (blkif->blk_ring.sring) {
- unmap_frontend_page(blkif);
- free_vm_area(blkif->blk_ring_area);
- }
-
+ tap_blkif_unmap(blkif);
kmem_cache_free(blkif_cachep, blkif);
}
diff -r e036feb6a4ff -r 98a81d2ccf4c
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Fri Sep 01 00:20:42
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c Fri Sep 01 00:33:19
2006 +0100
@@ -247,6 +247,11 @@ static void tap_frontend_changed(struct
switch (frontend_state) {
case XenbusStateInitialising:
+ if (dev->state == XenbusStateClosed) {
+ printk("%s: %s: prepare for reconnect\n",
+ __FUNCTION__, dev->nodename);
+ xenbus_switch_state(dev, XenbusStateInitWait);
+ }
break;
case XenbusStateInitialised:
@@ -264,11 +269,20 @@ static void tap_frontend_changed(struct
break;
case XenbusStateClosing:
+ if (be->blkif->xenblkd) {
+ kthread_stop(be->blkif->xenblkd);
+ be->blkif->xenblkd = NULL;
+ }
+ tap_blkif_unmap(be->blkif);
xenbus_switch_state(dev, XenbusStateClosing);
break;
+ case XenbusStateClosed:
+ xenbus_switch_state(dev, XenbusStateClosed);
+ if (xenbus_dev_is_online(dev))
+ break;
+ /* fall through if not online */
case XenbusStateUnknown:
- case XenbusStateClosed:
device_unregister(&dev->dev);
break;
diff -r e036feb6a4ff -r 98a81d2ccf4c
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Sep 01 00:20:42
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Fri Sep 01 00:33:19
2006 +0100
@@ -228,13 +228,13 @@ static void frontend_changed(struct xenb
{
struct backend_info *be = dev->dev.driver_data;
- DPRINTK("");
+ DPRINTK("%s", xenbus_strstate(frontend_state));
be->frontend_state = frontend_state;
switch (frontend_state) {
case XenbusStateInitialising:
- if (dev->state == XenbusStateClosing) {
+ if (dev->state == XenbusStateClosed) {
printk("%s: %s: prepare for reconnect\n",
__FUNCTION__, dev->nodename);
if (be->netif) {
@@ -260,8 +260,12 @@ static void frontend_changed(struct xenb
xenbus_switch_state(dev, XenbusStateClosing);
break;
+ case XenbusStateClosed:
+ xenbus_switch_state(dev, XenbusStateClosed);
+ if (xenbus_dev_is_online(dev))
+ break;
+ /* fall through if not online */
case XenbusStateUnknown:
- case XenbusStateClosed:
if (be->netif != NULL)
kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
device_unregister(&dev->dev);
diff -r e036feb6a4ff -r 98a81d2ccf4c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Fri Sep
01 00:20:42 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c Fri Sep
01 00:33:19 2006 +0100
@@ -132,4 +132,16 @@ int xenbus_unmap_ring(struct xenbus_devi
}
EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
+int xenbus_dev_is_online(struct xenbus_device *dev)
+{
+ int rc, val;
+
+ rc = xenbus_scanf(XBT_NIL, dev->nodename, "online", "%d", &val);
+ if (rc != 1)
+ val = 0; /* no online node present */
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(xenbus_dev_is_online);
+
MODULE_LICENSE("Dual BSD/GPL");
diff -r e036feb6a4ff -r 98a81d2ccf4c linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Fri Sep 01 00:20:42 2006 +0100
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Fri Sep 01 00:33:19 2006 +0100
@@ -298,5 +298,6 @@ int __init xenbus_dev_init(void);
int __init xenbus_dev_init(void);
char *xenbus_strstate(enum xenbus_state state);
+int xenbus_dev_is_online(struct xenbus_device *dev);
#endif /* _XEN_XENBUS_H */
diff -r e036feb6a4ff -r 98a81d2ccf4c
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Fri Sep 01 00:20:42
2006 +0100
+++ b/tools/python/xen/xend/server/DevController.py Fri Sep 01 00:33:19
2006 +0100
@@ -207,6 +207,9 @@ class DevController:
devid = int(devid)
+ # Modify online status /before/ updating state (latter is watched by
+ # drivers, so this ordering avoids a race).
+ self.writeBackend(devid, 'online', "0")
self.writeBackend(devid, 'state', str(xenbusState['Closing']))
@@ -406,7 +409,8 @@ class DevController:
'domain' : self.vm.getName(),
'frontend' : frontpath,
'frontend-id' : "%i" % self.vm.getDomid(),
- 'state' : str(xenbusState['Initialising'])
+ 'state' : str(xenbusState['Initialising']),
+ 'online' : "1"
})
return (backpath, frontpath)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|