Browse Source

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'.

NOTE(dmllr): Also merged regression fix:

    Consolidate the blockdev related filters

    Seeing a "/usr/local/bin/nova-rootwrap: Unauthorized command" error
    in the logs when  "blockdev --flushbufs" is executed because of the
    existing blockdev in compute.filters. We need to merge both into a
    single RegExpFilter

    Change-Id: Ic323ff00e5c23786a6e376e67a4ad08f92708aef

(cherry-picked from dd3f96e915)
(cherry-picked from 31b2791e6b)

Closes-Bug: #973413
Partial-Bug: #1254890
Change-Id: I2b7053b9a069d6e82f6f6baf9ad480efa4388d91
tags/2013.2.4
Davanum Srinivas 6 years ago
parent
commit
1681b957bf
4 changed files with 19 additions and 0 deletions
  1. +4
    -0
      etc/nova/rootwrap.d/compute.filters
  2. +2
    -0
      nova/tests/virt/test_virt.py
  3. +4
    -0
      nova/virt/disk/mount/api.py
  4. +9
    -0
      nova/virt/disk/mount/nbd.py

+ 4
- 0
etc/nova/rootwrap.d/compute.filters View File

@@ -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


+ 2
- 0
nova/tests/virt/test_virt.py View File

@@ -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'),

+ 4
- 0
nova/virt/disk/mount/api.py View File

@@ -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

+ 9
- 0
nova/virt/disk/mount/nbd.py View File

@@ -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)

Loading…
Cancel
Save