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)
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)
def _kill_process(self, sig, pid): if self.kill_scripts_path: kill_file = "%s-kill" % self.service if os.path.isfile(os.path.join(self.kill_scripts_path, kill_file)): utils.execute([kill_file, sig, pid], run_as_root=self.run_as_root) return utils.kill_process(pid, sig, run_as_root=self.run_as_root)
def _test_kill_process(self, pid, exception_message=None, kill_signal=signal.SIGKILL): if exception_message: exc = utils.ProcessExecutionError(exception_message, returncode=0) else: exc = None with mock.patch.object(utils, "execute", side_effect=exc) as mock_execute: utils.kill_process(pid, kill_signal, run_as_root=True) mock_execute.assert_called_with(["kill", "-%d" % kill_signal, pid], run_as_root=True)
def _kill_monitor(self): if self.monitor: # Kill PID instead of calling self.monitor.stop() because the ip # monitor is running as root while keepalived-state-change is not # (dropped privileges after launching the ip monitor) and will fail # with "Permission denied". Also, we can safely do this because the # monitor was launched with respawn_interval=None so it won't be # automatically respawned agent_utils.kill_process(self.monitor.pid, signal.SIGKILL, run_as_root=True)
def test_metadata_proxy_respawned(self): pm, network = self._spawn_network_metadata_proxy() old_pid = pm.pid utils.kill_process(old_pid, signal.SIGKILL, run_as_root=True) common_utils.wait_until_true( lambda: pm.active and pm.pid != old_pid, timeout=5, sleep=0.1, exception=RuntimeError("Metadata proxy didn't respawn"))
def _kill_process(self, pid, kill_signal): try: # A process started by a root helper will be running as # root and need to be killed via the same helper. utils.kill_process(pid, kill_signal, self.run_as_root) except Exception: LOG.exception('An error occurred while killing [%s].', self.cmd) return False if self._process: self._process.wait() return True
def _test_kill_process(self, pid, exception_message=None, kill_signal=signal.SIGKILL): if exception_message: exc = utils.ProcessExecutionError(exception_message, returncode=0) else: exc = None with mock.patch.object(utils, 'execute', side_effect=exc) as mock_execute: utils.kill_process(pid, kill_signal, run_as_root=True) mock_execute.assert_called_with(['kill', '-%d' % kill_signal, pid], run_as_root=True)
def _cleanup_nflog_process(self, router_info): LOG.debug("Delete router_info %s", router_info) if router_info in self.nflog_proc_map: pid = self.nflog_proc_map[router_info] try: # A process started by a root helper will be running as # root and need to be killed via the same helper. LOG.debug('Trying to kill NFLOG process %d', pid) utils.kill_process(pid, signal.SIGKILL, run_as_root=True) del self.nflog_proc_map[router_info] except Exception: LOG.exception('An error occurred while killing process %d', pid)
def destroy(self): # TODO(ralonsoh): once the issue in LP#1838793 is properly fixed, we # can remove this workaround (TestTimer context). with helpers.TestTimer(5): try: if self.ip_wrapper.netns.exists(self.name): for pid in ip_lib.list_namespace_pids(self.name): utils.kill_process(pid, signal.SIGKILL, run_as_root=True, extra_ok_codes=[errno.ESRCH]) self.ip_wrapper.netns.delete(self.name) except helpers.TestTimerTimeout: LOG.warning('Namespace %s was not deleted due to a timeout.', self.name)
def _test_kill_process(self, pid, raise_exception=False, kill_signal=signal.SIGKILL, pid_killed=True): if raise_exception: exc = exceptions.ProcessExecutionError('', returncode=0) else: exc = None with mock.patch.object(utils, 'execute', side_effect=exc) as mock_execute: with mock.patch.object(utils, 'process_is_running', return_value=not pid_killed): utils.kill_process(pid, kill_signal, run_as_root=True) mock_execute.assert_called_with(['kill', '-%d' % kill_signal, pid], run_as_root=True)
def test_root_no_such_proces_hidden(self): self.assertEqual( errno.ESRCH, utils.kill_process(self.NON_EXISTING_PID, signal.SIGUSR1, run_as_root=True, extra_ok_codes=[errno.ESRCH]))
def test_root_exception_not_risen(self): self.assertEqual( errno.ESRCH, utils.kill_process(self.NON_EXISTING_PID, signal.SIGUSR1, run_as_root=True, raise_exception=False))
def test_async_process_respawns(self): proc = async_process.AsyncProcess(['tail', '-f', self.test_file_path], respawn_interval=0) self.addCleanup(self._safe_stop, proc) proc.start() # Ensure that the same output is read twice self._check_stdout(proc) pid = proc.pid utils.kill_process(pid, signal.SIGKILL) common_utils.wait_until_true( lambda: proc.is_active() and pid != proc.pid, timeout=5, sleep=0.01, exception=RuntimeError(_("Async process didn't respawn"))) self._check_stdout(proc)
def kill(self, sig=signal.SIGKILL): pid = self.child_pid or str(self.pid) if utils.kill_process(pid, sig, run_as_root=True, extra_ok_codes=[errno.ESRCH]): LOG.debug('Process %s did not exists already so it could not be ' 'killed', pid)
def destroy(self): if self.ip_wrapper.netns.exists(self.name): for pid in ip_lib.list_namespace_pids(self.name): utils.kill_process(pid, signal.SIGKILL, run_as_root=True) self.ip_wrapper.netns.delete(self.name)
def test_non_root_operation_not_permitted_hidden(self): self.assertEqual( errno.EPERM, utils.kill_process(1, signal.SIGUSR1, extra_ok_codes=[errno.EPERM]))
def _test_exception(self, pid, error_no, run_as_root=False): try: utils.kill_process(pid, signal.SIGUSR1, run_as_root=run_as_root) except OSError as exc: self.assertEqual(error_no, exc.errno)