]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Multipath commands with error messages in stdout fail to parse
authorPatrick East <patrick.east@purestorage.com>
Tue, 14 Oct 2014 22:45:38 +0000 (15:45 -0700)
committerPatrick East <patrick.east@purestorage.com>
Wed, 15 Oct 2014 20:47:28 +0000 (13:47 -0700)
This change fixes an issue in find_multipath_device() where the command
output of ‘multipath -l <device>’ would sometimes fail to be parsed if
there were error messages in the stdout string in addition to the
expected output. We will now strip out the error messages before we
attempt to parse the lines.

Change-Id: I3d48debc7d64f6a891ac37d4c2c5ebddfb5b00b0
Closes-Bug: #1380742

cinder/brick/initiator/linuxscsi.py
cinder/tests/brick/test_brick_linuxscsi.py

index a374ce61f70ddfece128984ed5fc2e31d7346b83..1b3b87390300af9c09cf20df215d3aae48655c5d 100644 (file)
@@ -17,6 +17,7 @@
    Note, this is not iSCSI.
 """
 import os
+import re
 
 from cinder.brick import executor
 from cinder.i18n import _
@@ -25,6 +26,8 @@ from cinder.openstack.common import processutils as putils
 
 LOG = logging.getLogger(__name__)
 
+MULTIPATH_ERROR_REGEX = re.compile("\w{3} \d+ \d\d:\d\d:\d\d \|.*$")
+
 
 class LinuxSCSI(executor.Executor):
     def __init__(self, root_helper, execute=putils.execute,
@@ -143,6 +146,8 @@ class LinuxSCSI(executor.Executor):
         if out:
             lines = out.strip()
             lines = lines.split("\n")
+            lines = [line for line in lines
+                     if not re.match(MULTIPATH_ERROR_REGEX, line)]
             if lines:
                 line = lines[0]
                 info = line.split(" ")
index 5dc46130ebe8274f4c7a317b8e10a85dbc199695..fcea805a2c07343c56f658081454c9d778fc0dbf 100644 (file)
@@ -181,3 +181,32 @@ class LinuxSCSITestCase(test.TestCase):
         self.assertEqual("1", info['devices'][1]['channel'])
         self.assertEqual("0", info['devices'][1]['id'])
         self.assertEqual("3", info['devices'][1]['lun'])
+
+    def test_find_multipath_device_with_error(self):
+        def fake_execute(*cmd, **kwargs):
+            out = ("Oct 13 10:24:01 | /lib/udev/scsi_id exitted with 1\n"
+                   "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(self.linuxscsi, '_execute', fake_execute)
+
+        info = self.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'])