Fix for volume detach error when use NFS as the cinder backend

For NFS volumes, every time you detach a volume, nova tries to umount
the device path. If the device path is busy (or in use), it should
output a message to log and continue.
In current code, if the device is busy, it cannot catch the ‘device is busy’
message returned by umount, because it looking for the ‘target is busy’.
 Therefore, current code skip the ‘if’ statement and run the ‘else’ and
raise the exception.
Fix: Add ‘device is busy’ to if statement.

Add a mock test to check the behaviour of the
virt.libvirt.volume.LibvirtNFSVolumeDriver.disconnect_volume
when it has umount errors.

Closes-Bug: #1340552

Change-Id: Iac946c37064c5f5bf5a102305de40d21d16846c1
This commit is contained in:
Sampath Priyankara 2014-08-03 15:23:23 +09:00
parent 5f28f7df45
commit bd5c5d5bbd
2 changed files with 24 additions and 1 deletions

View File

@ -712,6 +712,28 @@ class LibvirtVolumeTestCase(test.NoDBTestCase):
('umount', export_mnt_base)]
self.assertEqual(expected_commands, self.executes)
@mock.patch.object(volume.utils, 'execute')
@mock.patch.object(volume.LOG, 'debug')
@mock.patch.object(volume.LOG, 'exception')
def test_libvirt_nfs_driver_umount_error(self, mock_LOG_exception,
mock_LOG_debug, mock_utils_exe):
export_string = '192.168.1.1:/nfs/share1'
connection_info = {'data': {'export': export_string,
'name': self.name}}
libvirt_driver = volume.LibvirtNFSVolumeDriver(self.fake_conn)
mock_utils_exe.side_effect = processutils.ProcessExecutionError(
None, None, None, 'umount', 'umount: device is busy.')
libvirt_driver.disconnect_volume(connection_info, "vde")
self.assertTrue(mock_LOG_debug.called)
mock_utils_exe.side_effect = processutils.ProcessExecutionError(
None, None, None, 'umount', 'umount: target is busy.')
libvirt_driver.disconnect_volume(connection_info, "vde")
self.assertTrue(mock_LOG_debug.called)
mock_utils_exe.side_effect = processutils.ProcessExecutionError(
None, None, None, 'umount', 'umount: Other error.')
libvirt_driver.disconnect_volume(connection_info, "vde")
self.assertTrue(mock_LOG_exception.called)
def test_libvirt_nfs_driver_already_mounted(self):
# NOTE(vish) exists is to make driver assume connecting worked
mnt_base = '/mnt'

View File

@ -663,7 +663,8 @@ class LibvirtNFSVolumeDriver(LibvirtBaseVolumeDriver):
try:
utils.execute('umount', mount_path, run_as_root=True)
except processutils.ProcessExecutionError as exc:
if 'target is busy' in exc.message:
if ('device is busy' in exc.message or
'target is busy' in exc.message):
LOG.debug("The NFS share %s is still in use.", export)
else:
LOG.exception(_LE("Couldn't unmount the NFS share %s"), export)