Commit 560cbec1 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Handle ESRCH when sending signals

Upon sending signals, ESRCH can be reported when the target no
longer exists.
Signed-off-by: default avatarMichael Hanselmann <>
Reviewed-by: default avatarGuido Trotter <>
parent c51580b3
......@@ -459,7 +459,7 @@ class ChildProcess(subprocess.Popen):
""""Sending signal %s to child process", signum)
os.killpg(, signum)
utils.IgnoreProcessNotFound(os.killpg,, signum)
def ForceQuit(self):
"""Ensure child process is no longer running.
......@@ -2764,7 +2764,7 @@ def AbortImportExport(name):
if pid:"Import/export %s is running with PID %s, sending SIGTERM",
name, pid)
os.kill(pid, signal.SIGTERM)
utils.IgnoreProcessNotFound(os.kill, pid, signal.SIGTERM)
def CleanupImportExport(name):
......@@ -344,6 +344,7 @@ class ChildIOProcessor(object):
# Process no longer exists
logging.debug("dd exited")
self._dd_pid = None
return True
......@@ -2342,8 +2342,7 @@ def KillProcess(pid, signal_=signal.SIGTERM, timeout=30,
def _helper(pid, signal_, wait):
"""Simple helper to encapsulate the kill/waitpid sequence"""
os.kill(pid, signal_)
if wait:
if IgnoreProcessNotFound(os.kill, pid, signal_) and wait:
os.waitpid(pid, os.WNOHANG)
except OSError:
......@@ -3122,6 +3121,26 @@ def RunInSeparateProcess(fn, *args):
return bool(exitcode)
def IgnoreProcessNotFound(fn, *args, **kwargs):
"""Ignores ESRCH when calling a process-related function.
ESRCH is raised when a process is not found.
@rtype: bool
@return: Whether process was found
fn(*args, **kwargs)
except EnvironmentError, err:
# Ignore ESRCH
if err.errno == errno.ESRCH:
return False
return True
def IgnoreSignals(fn, *args, **kwargs):
"""Tries to call a function ignoring failures due to EINTR.
......@@ -2393,5 +2393,27 @@ class TestFormatSeconds(unittest.TestCase):
self.assertEqual(utils.FormatSeconds(3912.8), "1h 5m 13s")
class RunIgnoreProcessNotFound(unittest.TestCase):
def _WritePid(fd):
os.write(fd, str(os.getpid()))
return True
def test(self):
(pid_read_fd, pid_write_fd) = os.pipe()
# Start short-lived process which writes its PID to pipe
self.assert_(utils.RunInSeparateProcess(self._WritePid, pid_write_fd))
# Read PID from pipe
pid = int(, 1024))
# Try to send signal to process which exited recently
self.assertFalse(utils.IgnoreProcessNotFound(os.kill, pid, 0))
if __name__ == '__main__':
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment