'iscsiadm -m session' failure handling

Sometimes 'iscsiadm -m session' outputs warnings on stderr, but
still serves its purpose (usable stdout). We should not give up on
it when stderr is non-empty - instead, rely on the exit status, log
the stderr as a warning, and move on.

This change also removes 1 (ISCSI_ERR) from the list of acceptable
exit codes for the iscsiadm command, to ensure that failures get
caught.

Change-Id: Id8183cf3d8baf2f8ba6a00a47fa2ad7cc2a96aa5
Closes-Bug: #1732199
This commit is contained in:
imacdonn 2018-09-25 03:40:31 +00:00
parent 10ea64db9c
commit d398fa8233
2 changed files with 13 additions and 9 deletions

View File

@ -118,9 +118,8 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
""" """
out, err = self._run_iscsi_session() out, err = self._run_iscsi_session()
if err: if err:
LOG.warning("Couldn't find iscsi sessions because " LOG.warning("iscsiadm stderr output when getting sessions: %s",
"iscsiadm err: %s", err) err)
return []
# Parse and clean the output from iscsiadm, which is in the form of: # Parse and clean the output from iscsiadm, which is in the form of:
# transport_name: [session_id] ip_address:port,tpgt iqn node_type # transport_name: [session_id] ip_address:port,tpgt iqn node_type
@ -1091,7 +1090,7 @@ class ISCSIConnector(base.BaseLinuxConnector, base_iscsi.BaseISCSIConnector):
def _run_iscsi_session(self): def _run_iscsi_session(self):
(out, err) = self._run_iscsiadm_bare(('-m', 'session'), (out, err) = self._run_iscsiadm_bare(('-m', 'session'),
check_exit_code=[0, 1, 21, 255]) check_exit_code=[0, 21, 255])
LOG.debug("iscsi session list stdout=%(out)s stderr=%(err)s", LOG.debug("iscsi session list stdout=%(out)s stderr=%(err)s",
{'out': out, 'err': err}) {'out': out, 'err': err})
return (out, err) return (out, err)

View File

@ -70,12 +70,17 @@ class ISCSIConnectorTestCase(test_connector.ConnectorTestCase):
('tcp:', 'session3', 'ip3:port3', '1', 'tgt3')] ('tcp:', 'session3', 'ip3:port3', '1', 'tgt3')]
self.assertListEqual(expected, res) self.assertListEqual(expected, res)
@mock.patch.object(iscsi.ISCSIConnector, '_run_iscsi_session', @mock.patch.object(iscsi.ISCSIConnector, '_run_iscsi_session')
return_value=(None, 'error')) def test_get_iscsi_sessions_full_stderr(self, sessions_mock):
def test_get_iscsi_sessions_full_error(self, sessions_mock): iscsiadm_result = ('tcp: [session1] ip1:port1,1 tgt1 (non-flash)\n'
'tcp: [session2] ip2:port2,-1 tgt2 (non-flash)\n'
'tcp: [session3] ip3:port3,1 tgt3\n')
sessions_mock.return_value = (iscsiadm_result, 'error')
res = self.connector._get_iscsi_sessions_full() res = self.connector._get_iscsi_sessions_full()
self.assertEqual([], res) expected = [('tcp:', 'session1', 'ip1:port1', '1', 'tgt1'),
sessions_mock.assert_called() ('tcp:', 'session2', 'ip2:port2', '-1', 'tgt2'),
('tcp:', 'session3', 'ip3:port3', '1', 'tgt3')]
self.assertListEqual(expected, res)
@mock.patch.object(iscsi.ISCSIConnector, '_get_iscsi_sessions_full') @mock.patch.object(iscsi.ISCSIConnector, '_get_iscsi_sessions_full')
def test_get_iscsi_sessions(self, sessions_mock): def test_get_iscsi_sessions(self, sessions_mock):