Example #1
0
 def _get_pid_to_kill(self):
     pid = self._process.pid
     # If root helper was used, two or more processes will be created:
     #
     #  - a root helper process (e.g. sudo myscript)
     #  - possibly a rootwrap script (e.g. neutron-rootwrap)
     #  - a child process (e.g. myscript)
     #
     # Killing the root helper process will leave the child process
     # running, re-parented to init, so the only way to ensure that both
     # die is to target the child process directly.
     if self.root_helper:
         try:
             pid = utils.find_child_pids(pid)[0]
         except IndexError:
             # Process is already dead
             return None
         while True:
             try:
                 # We shouldn't have more than one child per process
                 # so keep getting the children of the first one
                 pid = utils.find_child_pids(pid)[0]
             except IndexError:
                 # Last process in the tree, return it
                 break
     return pid
Example #2
0
 def _get_pid_to_kill(self):
     pid = self._process.pid
     # If root helper was used, two or more processes will be created:
     #
     #  - a root helper process (e.g. sudo myscript)
     #  - possibly a rootwrap script (e.g. neutron-rootwrap)
     #  - a child process (e.g. myscript)
     #
     # Killing the root helper process will leave the child process
     # running, re-parented to init, so the only way to ensure that both
     # die is to target the child process directly.
     if self.root_helper:
         try:
             pid = utils.find_child_pids(pid)[0]
         except IndexError:
             # Process is already dead
             return None
         while True:
             try:
                 # We shouldn't have more than one child per process
                 # so keep getting the children of the first one
                 pid = utils.find_child_pids(pid)[0]
             except IndexError:
                 # Last process in the tree, return it
                 break
     return pid
Example #3
0
 def test_returns_list_of_child_process_ids_recursively(self):
     with mock.patch.object(utils, 'execute',
                            side_effect=[' 123 \n 185\n',
                                         ' 40 \n', '\n',
                                         '41\n', '\n']):
         actual = utils.find_child_pids(-1, True)
         self.assertEqual(actual, ['123', '185', '40', '41'])
Example #4
0
def _kill_listen_processes(namespace, force=False):
    """Identify all listening processes within the given namespace.

    Then, for each one, find its top parent with same cmdline (in case this
    process forked) and issue a SIGTERM to all of them. If force is True,
    then a SIGKILL will be issued to all parents and all their children. Also,
    this function returns the number of listening processes.
    """
    pids = find_listen_pids_namespace(namespace)
    pids_to_kill = {utils.find_fork_top_parent(pid) for pid in pids}
    kill_signal = signal.SIGTERM
    if force:
        kill_signal = signal.SIGKILL
        children = [utils.find_child_pids(pid, True) for pid in pids_to_kill]
        pids_to_kill.update(itertools.chain.from_iterable(children))

    for pid in pids_to_kill:
        # Throw a warning since this particular cleanup may need a specific
        # implementation in the right module. Ideally, netns_cleanup wouldn't
        # kill any processes as the responsible module should've killed them
        # before cleaning up the namespace
        LOG.warning(_LW("Killing (%(signal)d) [%(pid)s] %(cmdline)s"),
                    {'signal': kill_signal,
                     'pid': pid,
                     'cmdline': ' '.join(utils.get_cmdline_from_pid(pid))[:80]
                     })
        try:
            utils.kill_process(pid, kill_signal, run_as_root=True)
        except Exception as ex:
            LOG.error(_LE('An error occurred while killing '
                          '[%(pid)s]: %(msg)s'), {'pid': pid, 'msg': ex})
    return len(pids)
Example #5
0
def _kill_listen_processes(namespace, force=False):
    """Identify all listening processes within the given namespace.

    Then, for each one, find its top parent with same cmdline (in case this
    process forked) and issue a SIGTERM to all of them. If force is True,
    then a SIGKILL will be issued to all parents and all their children. Also,
    this function returns the number of listening processes.
    """
    pids = find_listen_pids_namespace(namespace)
    pids_to_kill = {utils.find_fork_top_parent(pid) for pid in pids}
    kill_signal = signal.SIGTERM
    if force:
        kill_signal = signal.SIGKILL
        children = [utils.find_child_pids(pid, True) for pid in pids_to_kill]
        pids_to_kill.update(itertools.chain.from_iterable(children))

    for pid in pids_to_kill:
        # Throw a warning since this particular cleanup may need a specific
        # implementation in the right module. Ideally, netns_cleanup wouldn't
        # kill any processes as the responsible module should've killed them
        # before cleaning up the namespace
        LOG.warning("Killing (%(signal)d) [%(pid)s] %(cmdline)s",
                    {'signal': kill_signal,
                     'pid': pid,
                     'cmdline': ' '.join(utils.get_cmdline_from_pid(pid))[:80]
                     })
        try:
            utils.kill_process(pid, kill_signal, run_as_root=True)
        except Exception as ex:
            LOG.error('An error occurred while killing '
                      '[%(pid)s]: %(msg)s', {'pid': pid, 'msg': ex})
    return len(pids)
Example #6
0
    def test_find_child_pids(self):
        pid = os.getppid()
        child_pids = utils.find_child_pids(pid)
        child_pids_recursive = utils.find_child_pids(pid, recursive=True)
        for _pid in child_pids:
            self.assertIn(_pid, child_pids_recursive)

        cmd = ['sleep', '100']
        process = async_process.AsyncProcess(cmd)
        process.start()
        common_utils.wait_until_true(lambda: process._process.pid,
                                     sleep=0.5,
                                     timeout=10)
        self.addCleanup(self._stop_process, process)

        child_pids_after = utils.find_child_pids(pid)
        child_pids_recursive_after = utils.find_child_pids(pid, recursive=True)
        self.assertEqual(child_pids, child_pids_after)
        for _pid in child_pids + [process.pid]:
            self.assertIn(_pid, child_pids_recursive_after)
Example #7
0
 def _get_pid_to_kill(self):
     pid = self._process.pid
     # If root helper was used, two processes will be created:
     #
     #  - a root helper process (e.g. sudo myscript)
     #  - a child process (e.g. myscript)
     #
     # Killing the root helper process will leave the child process
     # as a zombie, so the only way to ensure that both die is to
     # target the child process directly.
     if self.root_helper:
         pids = utils.find_child_pids(pid)
         if pids:
             # The root helper will only ever launch a single child.
             pid = pids[0]
         else:
             # Process is already dead.
             pid = None
     return pid
Example #8
0
 def test_raises_unknown_exception(self):
     with testtools.ExpectedException(RuntimeError):
         with mock.patch.object(utils, 'execute',
                                side_effect=RuntimeError()):
             utils.find_child_pids(-1)
Example #9
0
 def test_returns_list_of_child_process_ids_for_good_ouput(self):
     with mock.patch.object(utils, 'execute', return_value=' 123 \n 185\n'):
         self.assertEqual(utils.find_child_pids(-1), ['123', '185'])
Example #10
0
 def test_returns_empty_list_for_no_output(self):
     with mock.patch.object(utils, 'execute', return_value=''):
         self.assertEqual([], utils.find_child_pids(-1))
Example #11
0
 def test_returns_empty_list_for_exit_code_1(self):
     with mock.patch.object(utils, 'execute',
                            side_effect=exceptions.ProcessExecutionError(
                                '', returncode=1)):
         self.assertEqual([], utils.find_child_pids(-1))
Example #12
0
 def test_returns_list_of_child_process_ids_for_good_ouput(self):
     with mock.patch.object(utils, "execute", return_value=" 123 \n 185\n"):
         self.assertEqual(utils.find_child_pids(-1), ["123", "185"])
Example #13
0
 def test_returns_list_of_child_process_ids_for_good_ouput(self):
     with mock.patch.object(utils, 'execute', return_value=' 123 \n 185\n'):
         self.assertEqual(utils.find_child_pids(-1), ['123', '185'])
Example #14
0
 def test_find_non_existing_process(self):
     with open('/proc/sys/kernel/pid_max', 'r') as fd:
         pid_max = int(fd.readline().strip())
     self.assertEqual([], utils.find_child_pids(pid_max))
Example #15
0
 def test_returns_list_of_child_process_ids_recursively(self):
     with mock.patch.object(utils, "execute", side_effect=[" 123 \n 185\n", " 40 \n", "\n", "41\n", "\n"]):
         actual = utils.find_child_pids(-1, True)
         self.assertEqual(actual, ["123", "185", "40", "41"])
Example #16
0
 def test_returns_empty_list_for_exit_code_1(self):
     with mock.patch.object(utils, 'execute',
                            side_effect=RuntimeError('Exit code: 1')):
         self.assertEqual(utils.find_child_pids(-1), [])
Example #17
0
 def test_returns_empty_list_for_no_output(self):
     with mock.patch.object(utils, 'execute', return_value=''):
         self.assertEqual(utils.find_child_pids(-1), [])
Example #18
0
 def test_returns_empty_list_for_exit_code_1(self):
     with mock.patch.object(utils,
                            'execute',
                            side_effect=RuntimeError('Exit code: 1')):
         self.assertEqual(utils.find_child_pids(-1), [])
Example #19
0
 def test_raises_unknown_exception(self):
     with testtools.ExpectedException(RuntimeError):
         with mock.patch.object(utils, 'execute',
                                side_effect=RuntimeError()):
             utils.find_child_pids(-1)
Example #20
0
 def test_returns_empty_list_for_no_output(self):
     with mock.patch.object(utils, "execute", return_value=""):
         self.assertEqual([], utils.find_child_pids(-1))