From dbe9ec6c6d7585667d9dce9cd5234b926c3e1936 Mon Sep 17 00:00:00 2001 From: Avishay Traeger Date: Mon, 25 Jun 2018 09:43:36 +0300 Subject: [PATCH] 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 (cherry picked from commit 9b729ef0e7461f5ca2d80b7f991aeacf547a1819) --- os_brick/initiator/linuxscsi.py | 3 +- os_brick/tests/initiator/test_linuxscsi.py | 38 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/os_brick/initiator/linuxscsi.py b/os_brick/initiator/linuxscsi.py index 9c631dc64..432e6e666 100644 --- a/os_brick/initiator/linuxscsi.py +++ b/os_brick/initiator/linuxscsi.py @@ -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] diff --git a/os_brick/tests/initiator/test_linuxscsi.py b/os_brick/tests/initiator/test_linuxscsi.py index 0c5d65eb0..4c1f67c9a 100644 --- a/os_brick/tests/initiator/test_linuxscsi.py +++ b/os_brick/tests/initiator/test_linuxscsi.py @@ -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 ," + "FlashArray\n" + "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/mapper/3624a93707edcfde1127040370004ee62", + info["device"]) + + 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