diff --git a/neutron/agent/linux/utils.py b/neutron/agent/linux/utils.py index 79640877dd6..7f8566f4110 100644 --- a/neutron/agent/linux/utils.py +++ b/neutron/agent/linux/utils.py @@ -323,19 +323,24 @@ def process_is_running(pid): def get_cmdline_from_pid(pid): if not process_is_running(pid): return [] - with open('/proc/%s/cmdline' % pid, 'r') as f: - cmdline = f.readline().split('\0')[:-1] + # NOTE(jh): Even after the above check, the process may terminate + # before the open below happens + try: + with open('/proc/%s/cmdline' % pid, 'r') as f: + cmdline = f.readline().split('\0')[:-1] + except IOError: + return [] - # NOTE(slaweq): sometimes it may happen that values in - # /proc/{pid}/cmdline are separated by space instead of NUL char, - # in such case we would have everything in one element of cmdline_args - # list and it would not match to expected cmd so we need to try to - # split it by spaces - if len(cmdline) == 1: - cmdline = cmdline[0].split(' ') + # NOTE(slaweq): sometimes it may happen that values in + # /proc/{pid}/cmdline are separated by space instead of NUL char, + # in such case we would have everything in one element of cmdline_args + # list and it would not match to expected cmd so we need to try to + # split it by spaces + if len(cmdline) == 1: + cmdline = cmdline[0].split(' ') - LOG.debug("Found cmdline %s for process with PID %s.", cmdline, pid) - return cmdline + LOG.debug("Found cmdline %s for process with PID %s.", cmdline, pid) + return cmdline def cmd_matches_expected(cmd, expected_cmd): diff --git a/neutron/tests/unit/agent/linux/test_utils.py b/neutron/tests/unit/agent/linux/test_utils.py index 50c27e119d7..bb816f0ec39 100644 --- a/neutron/tests/unit/agent/linux/test_utils.py +++ b/neutron/tests/unit/agent/linux/test_utils.py @@ -336,6 +336,16 @@ class TestGetCmdlineFromPid(base.BaseTestCase): mock_open.assert_not_called() self.assertEqual([], cmdline) + def test_cmdline_process_disappearing(self): + self.process_is_running_mock.return_value = True + mock_open = self.useFixture( + lib_fixtures.OpenFixture('/proc/%s/cmdline' % self.pid, 'process') + ).mock_open + mock_open.side_effect = IOError() + cmdline = utils.get_cmdline_from_pid(self.pid) + mock_open.assert_called_once_with('/proc/%s/cmdline' % self.pid, 'r') + self.assertEqual([], cmdline) + class TestFindChildPids(base.BaseTestCase):