Introduce new "online" node for backend drivers.
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
@@ -301,11 +301,11 @@ static void frontend_changed(struct xenbstruct 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 xenbxenbus_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
@@ -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 xenbxenbus_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
@@ -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
@@ -298,5 +298,6 @@ void xenbus_dev_fatal(struct xenbus_deviint __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
@@ -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
@@ -247,6 +247,11 @@ static void tap_frontend_changed(structswitch (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(structbreak ;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
@@ -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
@@ -135,20 +135,25 @@ int tap_blkif_map(blkif_t *blkif, unsignreturn 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