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 <device>' command when the
stdout contains error messages in addition to the expected output.

Change-Id: I59bf37a932acd97cf915d086b4072b71e8214936
Related-Bug: #1380742
Partial-Bug: #1433204
This commit is contained in:
Tomoki Sekiyama 2015-03-17 19:38:42 -04:00
parent 9a1913db07
commit 99d67bd77c
2 changed files with 20 additions and 1 deletions

View File

@ -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]

View File

@ -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.'