Handle multiple errors in multipath -l parsing

The current code in linuxscsi.py handles the case where there is one
error in the output of "multipath -l", but when there are multiple
errors there is an empty line between error messages. The code filters
out the error lines but not the empty lines, and so it then looks for
the device name in an empty line and so it fails to parse it.

Closes-Bug: #1778468
Change-Id: I7a5bdf285a74e045ce7d11df5e8c0921d3447106
changes/41/577741/1 2.5.2
Avishay Traeger 5 years ago
parent cb2ee2776d
commit 9b729ef0e7
  1. 3
  2. 38

@ -391,7 +391,8 @@ class LinuxSCSI(executor.Executor):
lines = out.strip()
lines = lines.split("\n")
lines = [line for line in lines
if not re.match(MULTIPATH_ERROR_REGEX, line)]
if not re.match(MULTIPATH_ERROR_REGEX, line)
and len(line)]
if lines:
mdev_name = lines[0].split(" ")[0]

@ -420,6 +420,44 @@ class LinuxSCSITestCase(base.TestCase):
self.assertEqual("0", info['devices'][1]['id'])
self.assertEqual("3", info['devices'][1]['lun'])
def test_find_multipath_device_with_multiple_errors(self):
def fake_execute(*cmd, **kwargs):
out = ("Jun 21 04:39:26 | 8:160: path wwid appears to have "
"changed. Using old wwid.\n\n"
"Jun 21 04:39:26 | 65:208: path wwid appears to have "
"changed. Using old wwid.\n\n"
"Jun 21 04:39:26 | 65:208: path wwid appears to have "
"changed. Using old wwid.\n"
"3624a93707edcfde1127040370004ee62 dm-84 PURE ,"
"size=100G features='0' hwhandler='0' wp=rw\n"
"`-+- policy='queue-length 0' prio=1 status=active\n"
" |- 8:0:0:9 sdaa 65:160 active ready running\n"
" `- 8:0:1:9 sdac 65:192 active ready running\n"
return out, None
self.linuxscsi._execute = fake_execute
info = self.linuxscsi.find_multipath_device('/dev/sdaa')
self.assertEqual("3624a93707edcfde1127040370004ee62", info["id"])
self.assertEqual("3624a93707edcfde1127040370004ee62", info["name"])
self.assertEqual("/dev/sdaa", info['devices'][0]['device'])
self.assertEqual("8", info['devices'][0]['host'])
self.assertEqual("0", info['devices'][0]['channel'])
self.assertEqual("0", info['devices'][0]['id'])
self.assertEqual("9", info['devices'][0]['lun'])
self.assertEqual("/dev/sdac", info['devices'][1]['device'])
self.assertEqual("8", info['devices'][1]['host'])
self.assertEqual("0", info['devices'][1]['channel'])
self.assertEqual("1", info['devices'][1]['id'])
self.assertEqual("9", info['devices'][1]['lun'])
@mock.patch.object(time, 'sleep')
def test_wait_for_rw(self, mock_sleep):
lsblk_output = """3624a93709a738ed78583fd1200143029 (dm-2) 0