Fix for qemu-nbd hang
NBD device once used seem to run into intermittent trouble when used with mount repeatedly. Adding code to explicitly flush the device buffers using 'blockdev --flushbufs'. Closes-Bug: #973413 Partial-Bug: #1254890 Change-Id: I2b7053b9a069d6e82f6f6baf9ad480efa4388d91
This commit is contained in:
parent
beca18af16
commit
dd3f96e915
|
@ -27,6 +27,9 @@ umount: CommandFilter, umount, root
|
||||||
# nova/virt/disk/mount/nbd.py: 'qemu-nbd', '-d', device
|
# nova/virt/disk/mount/nbd.py: 'qemu-nbd', '-d', device
|
||||||
qemu-nbd: CommandFilter, qemu-nbd, root
|
qemu-nbd: CommandFilter, qemu-nbd, root
|
||||||
|
|
||||||
|
# nova/virt/disk/mount/nbd.py: 'blockdev', '--flushbufs', device
|
||||||
|
blockdev: CommandFilter, blockdev, root
|
||||||
|
|
||||||
# nova/virt/disk/mount/loop.py: 'losetup', '--find', '--show', image
|
# nova/virt/disk/mount/loop.py: 'losetup', '--find', '--show', image
|
||||||
# nova/virt/disk/mount/loop.py: 'losetup', '--detach', device
|
# nova/virt/disk/mount/loop.py: 'losetup', '--detach', device
|
||||||
losetup: CommandFilter, losetup, root
|
losetup: CommandFilter, losetup, root
|
||||||
|
|
|
@ -227,12 +227,14 @@ class TestVirtDisk(test.NoDBTestCase):
|
||||||
|
|
||||||
disk_api.teardown_container('/mnt/nbd/nopart')
|
disk_api.teardown_container('/mnt/nbd/nopart')
|
||||||
expected_commands += [
|
expected_commands += [
|
||||||
|
('blockdev', '--flushbufs', '/dev/nbd15'),
|
||||||
('umount', '/dev/nbd15'),
|
('umount', '/dev/nbd15'),
|
||||||
('qemu-nbd', '-d', '/dev/nbd15'),
|
('qemu-nbd', '-d', '/dev/nbd15'),
|
||||||
]
|
]
|
||||||
|
|
||||||
disk_api.teardown_container('/mnt/nbd/part')
|
disk_api.teardown_container('/mnt/nbd/part')
|
||||||
expected_commands += [
|
expected_commands += [
|
||||||
|
('blockdev', '--flushbufs', '/dev/nbd15'),
|
||||||
('umount', '/dev/mapper/nbd15p1'),
|
('umount', '/dev/mapper/nbd15p1'),
|
||||||
('kpartx', '-d', '/dev/nbd15'),
|
('kpartx', '-d', '/dev/nbd15'),
|
||||||
('qemu-nbd', '-d', '/dev/nbd15'),
|
('qemu-nbd', '-d', '/dev/nbd15'),
|
||||||
|
|
|
@ -205,10 +205,14 @@ class Mount(object):
|
||||||
"""Unmount the device from the file system."""
|
"""Unmount the device from the file system."""
|
||||||
if not self.mounted:
|
if not self.mounted:
|
||||||
return
|
return
|
||||||
|
self.flush_dev()
|
||||||
LOG.debug(_("Umount %s") % self.mapped_device)
|
LOG.debug(_("Umount %s") % self.mapped_device)
|
||||||
utils.execute('umount', self.mapped_device, run_as_root=True)
|
utils.execute('umount', self.mapped_device, run_as_root=True)
|
||||||
self.mounted = False
|
self.mounted = False
|
||||||
|
|
||||||
|
def flush_dev(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def do_mount(self):
|
def do_mount(self):
|
||||||
"""Call the get, map and mnt operations."""
|
"""Call the get, map and mnt operations."""
|
||||||
status = False
|
status = False
|
||||||
|
|
|
@ -129,3 +129,12 @@ class NbdMount(api.Mount):
|
||||||
utils.execute('qemu-nbd', '-d', self.device, run_as_root=True)
|
utils.execute('qemu-nbd', '-d', self.device, run_as_root=True)
|
||||||
self.linked = False
|
self.linked = False
|
||||||
self.device = None
|
self.device = None
|
||||||
|
|
||||||
|
def flush_dev(self):
|
||||||
|
"""flush NBD block device buffer."""
|
||||||
|
# Perform an explicit BLKFLSBUF to support older qemu-nbd(s).
|
||||||
|
# Without this flush, when a nbd device gets re-used the
|
||||||
|
# qemu-nbd intermittently hangs.
|
||||||
|
if self.device:
|
||||||
|
utils.execute('blockdev', '--flushbufs',
|
||||||
|
self.device, run_as_root=True)
|
||||||
|
|
Loading…
Reference in New Issue