Skip to contentSkip to conversation

Introduce new "online" node for backend drivers.

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

lore
Share & tools
lore
#0 lore raw

PATCH 2/3 Introduce new "online" node for backend drivers.

Hi,

This patch introduces a 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.

please apply,

Gerd

Signature · 2 lines
Gerd Hoffmann <[email protected]>
http://www.suse.de/~kraxel/julika-dora.jpeg

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.

---
 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             |   19 ++++++----
 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 |   11 +++++
 linux-2.6-xen-sparse/include/xen/xenbus.h                       |    1 
 tools/python/xen/xend/server/DevController.py                   |    6 ++-
 8 files changed, 58 insertions(+), 16 deletions(-)
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +7 -3
Index: build-32-unstable-11288/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
===================================================================
@@ -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 XenbusStateUnknown:
 	case XenbusStateClosed:
+		xenbus_switch_state(dev, XenbusStateClosed);
+		if (xenbus_dev_is_online(dev))
+			break;
+		/* fall through if not online */
+	case XenbusStateUnknown:
 		device_unregister(&dev->dev);
 		break;
 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c +7 -3
Index: build-32-unstable-11288/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
===================================================================
@@ -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 XenbusStateUnknown:
 	case XenbusStateClosed:
+		xenbus_switch_state(dev, XenbusStateClosed);
+		if (xenbus_dev_is_online(dev))
+			break;
+		/* fall through if not online */
+	case XenbusStateUnknown:
 		if (be->netif != NULL)
 			kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE);
 		device_unregister(&dev->dev);
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c +11 -0
Index: build-32-unstable-11288/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_backend_client.c
===================================================================
@@ -132,4 +132,15 @@ 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 (1 != rc)
+		val = 0; /* no online node present */
+	return val;
+}
+EXPORT_SYMBOL_GPL(xenbus_dev_is_online);
+
 MODULE_LICENSE("Dual BSD/GPL");
linux-2.6-xen-sparse/include/xen/xenbus.h +1 -0
Index: build-32-unstable-11288/linux-2.6-xen-sparse/include/xen/xenbus.h
===================================================================
@@ -298,5 +298,6 @@ void xenbus_dev_fatal(struct xenbus_devi
 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 */
tools/python/xen/xend/server/DevController.py +4 -2
Index: build-32-unstable-11288/tools/python/xen/xend/server/DevController.py
===================================================================
@@ -207,7 +207,8 @@ class DevController:
 
         devid = int(devid)
 
-        self.writeBackend(devid, 'state', str(xenbusState['Closing']))
+        self.writeBackend(devid, 'state',  str(xenbusState['Closing']))
+        self.writeBackend(devid, 'online', "0")
 
 
     def configurations(self):
@@ -406,7 +407,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)
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c +15 -1
Index: build-32-unstable-11288/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c
===================================================================
@@ -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 XenbusStateUnknown:
 	case XenbusStateClosed:
+		xenbus_switch_state(dev, XenbusStateClosed);
+		if (xenbus_dev_is_online(dev))
+			break;
+		/* fall through if not online */
+	case XenbusStateUnknown:
 		device_unregister(&dev->dev);
 		break;
 
linux-2.6-xen-sparse/drivers/xen/blktap/common.h +1 -0
Index: build-32-unstable-11288/linux-2.6-xen-sparse/drivers/xen/blktap/common.h
===================================================================
@@ -91,6 +91,7 @@ blkif_t *tap_alloc_blkif(domid_t domid);
 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)					\
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c +12 -7
Index: build-32-unstable-11288/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
===================================================================
@@ -135,20 +135,25 @@ int tap_blkif_map(blkif_t *blkif, unsign
 	return 0;
 }
 
-void tap_blkif_free(blkif_t *blkif)
+void tap_blkif_unmap(blkif_t *blkif)
 {
-	atomic_dec(&blkif->refcnt);
-	wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
-
-	/* Already disconnected? */
-	if (blkif->irq)
+	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);
+
+	tap_blkif_unmap(blkif);
 	kmem_cache_free(blkif_cachep, blkif);
 }
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel