FlashSystem reports error in _find_host_exhaustive()

While host was deleted by someone else, the deleted host still
existed in hosts. In _find_host_exhaustive(), all hosts would be
enumerated. Thus, 'lshost' command would fail in this situation.

In this fix,
* Adds hostname check before issue 'lshost' command for FC.
* Modifies map(lambda, x) to list comprehension for python 3
compatibility.
* Bump version to 1.0.7.

Change-Id: I989092e7aacbcd296717d4172035b3edd5b63348
Close-bug: 1505477
This commit is contained in:
Edwin Wang 2015-11-19 08:26:52 -06:00
parent 925a5c31b9
commit cc7616dd82
4 changed files with 33 additions and 12 deletions

View File

@ -1202,6 +1202,13 @@ class FlashSystemDriverTestCase(test.TestCase):
self.assertIsNone(self.driver._find_host_exhaustive(conn3,
[host1, host2]))
# case 2: hosts contains non-existent host info
with mock.patch.object(FlashSystemFakeDriver,
'_ssh') as mock_ssh:
mock_ssh.return_value = ("pass", "")
self.driver._find_host_exhaustive(conn1, [host2])
self.assertFalse(mock_ssh.called)
# clear environment
self.driver._delete_host(host1)
self.driver._delete_host(host2)

View File

@ -75,10 +75,12 @@ class FlashSystemDriver(san.SanDriver):
1.0.5 - Report capability of volume multiattach
1.0.6 - Fix bug #1469581, add I/T mapping check in
terminate_connection
1.0.7 - Fix bug #1505477, add host name check in
_find_host_exhaustive for FC
"""
VERSION = "1.0.6"
VERSION = "1.0.7"
def __init__(self, *args, **kwargs):
super(FlashSystemDriver, self).__init__(*args, **kwargs)
@ -419,7 +421,7 @@ class FlashSystemDriver(san.SanDriver):
'name' in header,
'_get_host_from_connector', ssh_cmd, out, err)
name_index = header.index('name')
hosts = map(lambda x: x.split('!')[name_index], host_lines)
hosts = [x.split('!')[name_index] for x in host_lines]
hostname = self._find_host_exhaustive(connector, hosts)
LOG.debug('leave: _get_host_from_connector: host %s.', hostname)

View File

@ -32,7 +32,7 @@ from oslo_utils import excutils
import six
from cinder import exception
from cinder.i18n import _, _LE, _LI
from cinder.i18n import _, _LE, _LI, _LW
from cinder import utils
import cinder.volume.driver
from cinder.volume.drivers.ibm import flashsystem_common as fscommon
@ -67,10 +67,12 @@ class FlashSystemFCDriver(fscommon.FlashSystemDriver,
1.0.5 - Report capability of volume multiattach
1.0.6 - Fix bug #1469581, add I/T mapping check in
terminate_connection
1.0.7 - Fix bug #1505477, add host name check in
_find_host_exhaustive for FC
"""
VERSION = "1.0.6"
VERSION = "1.0.7"
def __init__(self, *args, **kwargs):
super(FlashSystemFCDriver, self).__init__(*args, **kwargs)
@ -133,19 +135,27 @@ class FlashSystemFCDriver(fscommon.FlashSystemDriver,
return host_name
def _find_host_exhaustive(self, connector, hosts):
for host in hosts:
hname = connector['host']
hnames = [ihost[0:ihost.rfind('-')] for ihost in hosts]
if hname in hnames:
host = hosts[hnames.index(hname)]
ssh_cmd = ['svcinfo', 'lshost', '-delim', '!', host]
out, err = self._ssh(ssh_cmd)
self._assert_ssh_return(
out.strip(),
'_find_host_exhaustive', ssh_cmd, out, err)
for attr_line in out.split('\n'):
# If '!' not found, return the string and two empty strings
attr_lines = [attr_line for attr_line in out.split('\n')]
attr_parm = {}
for attr_line in attr_lines:
attr_name, foo, attr_val = attr_line.partition('!')
if (attr_name == 'WWPN' and
'wwpns' in connector and attr_val.lower() in
map(str.lower, map(str, connector['wwpns']))):
return host
attr_parm[attr_name] = attr_val
if ('WWPN' in attr_parm.keys() and 'wwpns' in connector and
attr_parm['WWPN'].lower() in
map(str.lower, map(str, connector['wwpns']))):
return host
else:
LOG.warning(_LW('Host %(host)s was not found on backend storage.'),
{'host': hname})
return None
def _get_conn_fc_wwpns(self):

View File

@ -65,10 +65,12 @@ class FlashSystemISCSIDriver(fscommon.FlashSystemDriver,
1.0.5 - Report capability of volume multiattach
1.0.6 - Fix bug #1469581, add I/T mapping check in
terminate_connection
1.0.7 - Fix bug #1505477, add host name check in
_find_host_exhaustive for FC
"""
VERSION = "1.0.6"
VERSION = "1.0.7"
def __init__(self, *args, **kwargs):
super(FlashSystemISCSIDriver, self).__init__(*args, **kwargs)