From 99d67bd77cbc83c0a465c64fce2827ee5d5d0afc Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Tue, 17 Mar 2015 19:38:42 -0400 Subject: [PATCH] Remove error messages from multipath command output before parsing This fixes an issue in _get_multipath_device_name() that fails to parse the output from 'multipath -ll ' command when the stdout contains error messages in addition to the expected output. Change-Id: I59bf37a932acd97cf915d086b4072b71e8214936 Related-Bug: #1380742 Partial-Bug: #1433204 --- os_brick/initiator/connector.py | 4 +++- os_brick/tests/initiator/test_connector.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/os_brick/initiator/connector.py b/os_brick/initiator/connector.py index c60a89e..9296a1f 100644 --- a/os_brick/initiator/connector.py +++ b/os_brick/initiator/connector.py @@ -23,6 +23,7 @@ each of the supported transport protocols. import copy import os import platform +import re import socket import time @@ -47,6 +48,7 @@ LOG = logging.getLogger(__name__) synchronized = lockutils.synchronized_with_prefix('os-brick-') DEVICE_SCAN_ATTEMPTS_DEFAULT = 3 +MULTIPATH_ERROR_REGEX = re.compile("\w{3} \d+ \d\d:\d\d:\d\d \|.*$") def _check_multipathd_running(root_helper, enforce_multipath): @@ -590,7 +592,7 @@ class ISCSIConnector(InitiatorConnector): device], check_exit_code=[0, 1])[0] mpath_line = [line for line in out.splitlines() - if "scsi_id" not in line] # ignore udev errors + if not re.match(MULTIPATH_ERROR_REGEX, line)] if len(mpath_line) > 0 and len(mpath_line[0]) > 0: return "/dev/mapper/%s" % mpath_line[0].split(" ")[0] diff --git a/os_brick/tests/initiator/test_connector.py b/os_brick/tests/initiator/test_connector.py index 65fd901..debd6da 100644 --- a/os_brick/tests/initiator/test_connector.py +++ b/os_brick/tests/initiator/test_connector.py @@ -521,6 +521,23 @@ class ISCSIConnectorTestCase(ConnectorTestCase): self.connector. _get_multipath_device_name('/dev/md-1')) + @mock.patch.object(os.path, 'realpath') + @mock.patch.object(connector.ISCSIConnector, '_run_multipath') + def test_get_multipath_device_name_with_error(self, multipath_mock, + realpath_mock): + multipath_mock.return_value = [ + "Mar 17 14:32:37 | sda: No fc_host device for 'host-1'\n" + "mpathb (36e00000000010001) dm-4 IET ,VIRTUAL-DISK\n" + "size=1.0G features='0' hwhandler='0' wp=rw\n" + "|-+- policy='service-time 0' prio=0 status=active\n" + "| `- 2:0:0:1 sda 8:0 active undef running\n" + "`-+- policy='service-time 0' prio=0 status=enabled\n" + " `- 3:0:0:1 sdb 8:16 active undef running\n"] + expected = '/dev/mapper/mpathb' + self.assertEqual(expected, + self.connector. + _get_multipath_device_name('/dev/sda')) + @mock.patch.object(os, 'walk') def test_get_iscsi_devices(self, walk_mock): paths = [('ip-10.0.0.1:3260-iscsi-iqn.2013-01.ro.'