From d93e466857f75073b243fea9901ea21b77753485 Mon Sep 17 00:00:00 2001 From: Patrick Schaefer Date: Tue, 28 May 2013 17:44:15 +0200 Subject: Enhance multipath parsing The output of the multipath command is not always parseable from the current implementation. This causes attach to fail. Fixes Bug: #1184861 Change-Id: I1afa96a695b1008672226e7e76eb8e0feca52578 --- nova/storage/linuxscsi.py | 22 ++++++++-------- nova/tests/test_linuxscsi.py | 61 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/nova/storage/linuxscsi.py b/nova/storage/linuxscsi.py index 95cec192d..afd8aa81c 100644 --- a/nova/storage/linuxscsi.py +++ b/nova/storage/linuxscsi.py @@ -123,17 +123,19 @@ def find_multipath_device(device): LOG.debug(_("Found multipath device = %(mdev)s") % locals()) device_lines = lines[3:] for dev_line in device_lines: - dev_line = dev_line.strip() - dev_line = dev_line[3:] + if dev_line.find("policy") != -1: + continue + + dev_line = dev_line.lstrip(' |-`') dev_info = dev_line.split() - if dev_line.find("policy") == -1: - address = dev_info[0].split(":") - - dev = {'device': '/dev/%s' % dev_info[1], - 'host': address[0], 'channel': address[1], - 'id': address[2], 'lun': address[3] - } - devices.append(dev) + address = dev_info[0].split(":") + + dev = {'device': '/dev/%s' % dev_info[1], + 'host': address[0], 'channel': address[1], + 'id': address[2], 'lun': address[3] + } + + devices.append(dev) if mdev is not None: info = {"device": mdev, diff --git a/nova/tests/test_linuxscsi.py b/nova/tests/test_linuxscsi.py index 7f66974d0..0775b9d5b 100644 --- a/nova/tests/test_linuxscsi.py +++ b/nova/tests/test_linuxscsi.py @@ -38,7 +38,7 @@ class StorageLinuxSCSITestCase(test.TestCase): self.stubs.Set(utils, 'execute', fake_execute) - def test_find_multipath_device(self): + def test_find_multipath_device_3par(self): def fake_execute(*cmd, **kwargs): out = ("mpath6 (350002ac20398383d) dm-3 3PARdata,VV\n" "size=2.0G features='0' hwhandler='0' wp=rw\n" @@ -64,3 +64,62 @@ class StorageLinuxSCSITestCase(test.TestCase): self.assertEqual("0", info['devices'][1]['id']) self.assertEqual("0", info['devices'][1]['channel']) self.assertEqual("1", info['devices'][1]['lun']) + + def test_find_multipath_device_svc(self): + def fake_execute(*cmd, **kwargs): + out = ("36005076da00638089c000000000004d5 dm-2 IBM,2145\n" + "size=954M features='1 queue_if_no_path' hwhandler='0'" + " wp=rw\n" + "|-+- policy='round-robin 0' prio=-1 status=active\n" + "| |- 6:0:2:0 sde 8:64 active undef running\n" + "| `- 6:0:4:0 sdg 8:96 active undef running\n" + "`-+- policy='round-robin 0' prio=-1 status=enabled\n" + " |- 6:0:3:0 sdf 8:80 active undef running\n" + " `- 6:0:5:0 sdh 8:112 active undef running\n" + ) + return out, None + + self.stubs.Set(utils, 'execute', fake_execute) + + info = linuxscsi.find_multipath_device('/dev/sde') + LOG.error("info = %s" % info) + self.assertEqual("/dev/dm-2", info["device"]) + self.assertEqual("/dev/sde", info['devices'][0]['device']) + self.assertEqual("6", info['devices'][0]['host']) + self.assertEqual("0", info['devices'][0]['channel']) + self.assertEqual("2", info['devices'][0]['id']) + self.assertEqual("0", info['devices'][0]['lun']) + + self.assertEqual("/dev/sdf", info['devices'][2]['device']) + self.assertEqual("6", info['devices'][2]['host']) + self.assertEqual("0", info['devices'][2]['channel']) + self.assertEqual("3", info['devices'][2]['id']) + self.assertEqual("0", info['devices'][2]['lun']) + + def test_find_multipath_device_ds8000(self): + def fake_execute(*cmd, **kwargs): + out = ("36005076303ffc48e0000000000000101 dm-2 IBM,2107900\n" + "size=1.0G features='1 queue_if_no_path' hwhandler='0'" + " wp=rw\n" + "`-+- policy='round-robin 0' prio=-1 status=active\n" + " |- 6:0:2:0 sdd 8:64 active undef running\n" + " `- 6:1:0:3 sdc 8:32 active undef running\n" + ) + return out, None + + self.stubs.Set(utils, 'execute', fake_execute) + + info = linuxscsi.find_multipath_device('/dev/sdd') + LOG.error("info = %s" % info) + self.assertEqual("/dev/dm-2", info["device"]) + self.assertEqual("/dev/sdd", info['devices'][0]['device']) + self.assertEqual("6", info['devices'][0]['host']) + self.assertEqual("0", info['devices'][0]['channel']) + self.assertEqual("2", info['devices'][0]['id']) + self.assertEqual("0", info['devices'][0]['lun']) + + self.assertEqual("/dev/sdc", info['devices'][1]['device']) + self.assertEqual("6", info['devices'][1]['host']) + self.assertEqual("1", info['devices'][1]['channel']) + self.assertEqual("0", info['devices'][1]['id']) + self.assertEqual("3", info['devices'][1]['lun']) -- cgit