[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [XENBUS] Introduce new "online" node for backend drivers.



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.