diff --git a/etc/nova/rootwrap.d/compute.filters b/etc/nova/rootwrap.d/compute.filters index e98c3f265daf..87f3d37624c7 100644 --- a/etc/nova/rootwrap.d/compute.filters +++ b/etc/nova/rootwrap.d/compute.filters @@ -31,6 +31,10 @@ qemu-nbd: CommandFilter, qemu-nbd, root # nova/virt/disk/mount/loop.py: 'losetup', '--detach', device losetup: CommandFilter, losetup, root +# nova/virt/libvirt/utils.py: 'blockdev', '--getsize64', path +# nova/virt/disk/mount/nbd.py: 'blockdev', '--flushbufs', device +blockdev: RegExpFilter, blockdev, root, blockdev, (--getsize64|--flushbufs), /dev/.* + # nova/virt/disk/vfs/localfs.py: 'tee', canonpath tee: CommandFilter, tee, root diff --git a/nova/tests/virt/test_virt.py b/nova/tests/virt/test_virt.py index 5048fc7562e7..6fa1a63cc674 100644 --- a/nova/tests/virt/test_virt.py +++ b/nova/tests/virt/test_virt.py @@ -125,12 +125,14 @@ class TestVirtDisk(test.NoDBTestCase): disk_api.teardown_container('/mnt/nbd/nopart') expected_commands += [ + ('blockdev', '--flushbufs', '/dev/nbd15'), ('umount', '/dev/nbd15'), ('qemu-nbd', '-d', '/dev/nbd15'), ] disk_api.teardown_container('/mnt/nbd/part') expected_commands += [ + ('blockdev', '--flushbufs', '/dev/nbd15'), ('umount', '/dev/mapper/nbd15p1'), ('kpartx', '-d', '/dev/nbd15'), ('qemu-nbd', '-d', '/dev/nbd15'), diff --git a/nova/virt/disk/mount/api.py b/nova/virt/disk/mount/api.py index fb0ba8d5fe55..6a545b7000d5 100644 --- a/nova/virt/disk/mount/api.py +++ b/nova/virt/disk/mount/api.py @@ -205,10 +205,14 @@ class Mount(object): """Unmount the device from the file system.""" if not self.mounted: return + self.flush_dev() LOG.debug(_("Umount %s") % self.mapped_device) utils.execute('umount', self.mapped_device, run_as_root=True) self.mounted = False + def flush_dev(self): + pass + def do_mount(self): """Call the get, map and mnt operations.""" status = False diff --git a/nova/virt/disk/mount/nbd.py b/nova/virt/disk/mount/nbd.py index 801e25eba35c..cc33bc64b448 100644 --- a/nova/virt/disk/mount/nbd.py +++ b/nova/virt/disk/mount/nbd.py @@ -129,3 +129,12 @@ class NbdMount(api.Mount): utils.execute('qemu-nbd', '-d', self.device, run_as_root=True) self.linked = False 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)