aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorJoe Jin <joe.jin@oracle.com>2011-08-15 00:51:31 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-08-22 11:35:35 -0400
commit6f5986bce558e64fe867bff600a2127a3cb0c006 (patch)
treeb08c7f219d1757f6389258d9879c1ae592232716 /drivers/block
parentea5e116162b7e0cf83a2b8a273440514404604de (diff)
xen-blkback: Don't disconnect backend until state switched to XenbusStateClosed.
When do block-attach/block-detach test with below steps, umount hangs in the guest. Furthermore shutdown ends up being stuck when umounting file-systems. 1. start guest. 2. attach new block device by xm block-attach in Dom0. 3. mount new disk in guest. 4. execute xm block-detach to detach the block device in dom0 until timeout 5. Any request to the disk will hung. Root cause: This issue is caused when setting backend device's state to 'XenbusStateClosing', which sends to the frontend the XenbusStateClosing notification. When frontend receives the notification it tries to release the disk in blkfront_closing(), but at that moment the disk is still in use by guest, so frontend refuses to close. Specifically it sets the disk state to XenbusStateClosing and sends the notification to backend - when backend receives the event, it disconnects the vbd from real device, and sets the vbd device state to XenbusStateClosing. The backend disconnects the real device/file, and any IO requests to the disk in guest will end up in ether, leaving disk DEAD and set to XenbusStateClosing. When the guest wants to disconnect the disk, umount will hang on blkif_release()->xlvbd_release_gendisk() as it is unable to send any IO to the disk, which prevents clean system shutdown. Solution: Don't disconnect backend until frontend state switched to XenbusStateClosed. Signed-off-by: Joe Jin <joe.jin@oracle.com> Cc: Daniel Stodden <daniel.stodden@citrix.com> Cc: Jens Axboe <jaxboe@fusionio.com> Cc: Annie Li <annie.li@oracle.com> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com> [v1: Modified description a bit] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/xen-blkback/xenbus.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 6cc0db1bf522..7be3d0fe8ad3 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -601,11 +601,11 @@ static void frontend_changed(struct xenbus_device *dev,
601 break; 601 break;
602 602
603 case XenbusStateClosing: 603 case XenbusStateClosing:
604 xen_blkif_disconnect(be->blkif);
605 xenbus_switch_state(dev, XenbusStateClosing); 604 xenbus_switch_state(dev, XenbusStateClosing);
606 break; 605 break;
607 606
608 case XenbusStateClosed: 607 case XenbusStateClosed:
608 xen_blkif_disconnect(be->blkif);
609 xenbus_switch_state(dev, XenbusStateClosed); 609 xenbus_switch_state(dev, XenbusStateClosed);
610 if (xenbus_dev_is_online(dev)) 610 if (xenbus_dev_is_online(dev))
611 break; 611 break;