summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-06-10 23:30:50 +0000
committerGerrit Code Review <review@openstack.org>2013-06-10 23:30:50 +0000
commit5bfa143c56dc2c6fa79acc4417e80823336fc46a (patch)
tree641f1fd719a94fd0620051a350a5902c8b4c3ace
parentf85e4ec079283f4217415b4fd6a37ced189bc49a (diff)
parent080476b2d383b148f6fc8d202c3b0509f9bb1d66 (diff)
downloadnova-5bfa143c56dc2c6fa79acc4417e80823336fc46a.tar.gz
nova-5bfa143c56dc2c6fa79acc4417e80823336fc46a.tar.xz
nova-5bfa143c56dc2c6fa79acc4417e80823336fc46a.zip
Merge "Fix dangling LUN issue under load with multipath"
-rw-r--r--nova/storage/linuxscsi.py4
-rw-r--r--nova/tests/test_linuxscsi.py11
-rw-r--r--nova/tests/virt/libvirt/test_libvirt_volume.py1
-rw-r--r--nova/virt/libvirt/volume.py10
4 files changed, 25 insertions, 1 deletions
diff --git a/nova/storage/linuxscsi.py b/nova/storage/linuxscsi.py
index afd8aa81c..d8c8b7f50 100644
--- a/nova/storage/linuxscsi.py
+++ b/nova/storage/linuxscsi.py
@@ -112,8 +112,11 @@ def find_multipath_device(device):
# on /etc/multipath.conf settings.
if info[1][:2] == "dm":
mdev = "/dev/%s" % info[1]
+ mdev_id = info[0]
elif info[2][:2] == "dm":
mdev = "/dev/%s" % info[2]
+ mdev_id = info[1].replace('(', '')
+ mdev_id = mdev_id.replace(')', '')
if mdev is None:
LOG.warn(_("Couldn't find multipath device %(line)s")
@@ -139,6 +142,7 @@ def find_multipath_device(device):
if mdev is not None:
info = {"device": mdev,
+ "id": mdev_id,
"devices": devices}
return info
return None
diff --git a/nova/tests/test_linuxscsi.py b/nova/tests/test_linuxscsi.py
index 0775b9d5b..8c098a846 100644
--- a/nova/tests/test_linuxscsi.py
+++ b/nova/tests/test_linuxscsi.py
@@ -43,11 +43,20 @@ class StorageLinuxSCSITestCase(test.TestCase):
out = ("mpath6 (350002ac20398383d) dm-3 3PARdata,VV\n"
"size=2.0G features='0' hwhandler='0' wp=rw\n"
"`-+- policy='round-robin 0' prio=-1 status=active\n"
- " |- 0:0:0:1 sde 8:64 active undef running\n"
+ " |- 0:0:0:1 sde 8:64 active undef running\n"
" `- 2:0:0:1 sdf 8:80 active undef running\n"
)
return out, None
+ def fake_execute2(*cmd, **kwargs):
+ out = ("350002ac20398383d dm-3 3PARdata,VV\n"
+ "size=2.0G features='0' hwhandler='0' wp=rw\n"
+ "`-+- policy='round-robin 0' prio=-1 status=active\n"
+ " |- 0:0:0:1 sde 8:64 active undef running\n"
+ " `- 2:0:0:1 sdf 8:80 active undef running\n"
+ )
+ return out, None
+
self.stubs.Set(utils, 'execute', fake_execute)
info = linuxscsi.find_multipath_device('/dev/sde')
diff --git a/nova/tests/virt/libvirt/test_libvirt_volume.py b/nova/tests/virt/libvirt/test_libvirt_volume.py
index c96bc8dda..07a1a7b2f 100644
--- a/nova/tests/virt/libvirt/test_libvirt_volume.py
+++ b/nova/tests/virt/libvirt/test_libvirt_volume.py
@@ -593,6 +593,7 @@ class LibvirtVolumeTestCase(test.TestCase):
libvirt_driver = volume.LibvirtFibreChannelVolumeDriver(self.fake_conn)
multipath_devname = '/dev/md-1'
devices = {"device": multipath_devname,
+ "id": "1234567890",
"devices": [{'device': '/dev/sdb',
'address': '1:0:0:1',
'host': 1, 'channel': 0,
diff --git a/nova/virt/libvirt/volume.py b/nova/virt/libvirt/volume.py
index 34fd9c772..4a11e2704 100644
--- a/nova/virt/libvirt/volume.py
+++ b/nova/virt/libvirt/volume.py
@@ -753,6 +753,7 @@ class LibvirtFibreChannelVolumeDriver(LibvirtBaseVolumeDriver):
% {'device': mdev_info['device']})
device_path = mdev_info['device']
connection_info['data']['devices'] = mdev_info['devices']
+ connection_info['data']['multipath_id'] = mdev_info['id']
else:
# we didn't find a multipath device.
# so we assume the kernel only sees 1 device
@@ -774,6 +775,15 @@ class LibvirtFibreChannelVolumeDriver(LibvirtBaseVolumeDriver):
self).disconnect_volume(connection_info, mount_device)
devices = connection_info['data']['devices']
+ # If this is a multipath device, we need to search again
+ # and make sure we remove all the devices. Some of them
+ # might not have shown up at attach time.
+ if 'multipath_id' in connection_info['data']:
+ multipath_id = connection_info['data']['multipath_id']
+ mdev_info = linuxscsi.find_multipath_device(multipath_id)
+ devices = mdev_info['devices']
+ LOG.debug("devices to remove = %s" % devices)
+
# There may have been more than 1 device mounted
# by the kernel for this volume. We have to remove
# all of them