Skip to content
Snippets Groups Projects
Commit 09b72783 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

RunCmd: Expose "postfork" callback


The “_postfork_fn” parameter was only used for tests until now. To
implement a good locking scheme, remote commands must also make use of
this callback to release a lock when the command was successfully
started (but did not yet finish).

Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent 551a29df
No related branches found
No related tags found
No related merge requests found
......@@ -142,7 +142,7 @@ def _BuildCmdEnvironment(env, reset):
def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False,
interactive=False, timeout=None, noclose_fds=None,
input_fd=None, _postfork_fn=None):
input_fd=None, postfork_fn=None):
"""Execute a (shell) command.
The command should not read from its standard input, as it will be
......@@ -172,7 +172,8 @@ def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False,
open for the child process
@type input_fd: C{file}-like object or numeric file descriptor
@param input_fd: File descriptor for process' standard input
@param _postfork_fn: Callback run after fork but before timeout (unittest)
@type postfork_fn: Callable receiving PID as parameter
@param postfork_fn: Callback run after fork but before timeout
@rtype: L{RunResult}
@return: RunResult instance
@raise errors.ProgrammerError: if we call this when forks are disabled
......@@ -211,10 +212,11 @@ def RunCmd(cmd, env=None, output=None, cwd="/", reset_env=False,
out, err, status, timeout_action = _RunCmdPipe(cmd, cmd_env, shell, cwd,
interactive, timeout,
noclose_fds, input_fd,
_postfork_fn=_postfork_fn)
postfork_fn=postfork_fn)
else:
assert _postfork_fn is None, \
"_postfork_fn not supported if output provided"
if postfork_fn:
raise errors.ProgrammerError("postfork_fn is not supported if output"
" should be captured")
assert input_fd is None
timeout_action = _TIMEOUT_NONE
status = _RunCmdFile(cmd, cmd_env, shell, output, cwd, noclose_fds)
......@@ -490,9 +492,8 @@ def _WaitForProcess(child, timeout):
def _RunCmdPipe(cmd, env, via_shell, cwd, interactive, timeout, noclose_fds,
input_fd,
_linger_timeout=constants.CHILD_LINGER_TIMEOUT,
_postfork_fn=None):
input_fd, postfork_fn=None,
_linger_timeout=constants.CHILD_LINGER_TIMEOUT):
"""Run a command and return its output.
@type cmd: string or list
......@@ -512,7 +513,8 @@ def _RunCmdPipe(cmd, env, via_shell, cwd, interactive, timeout, noclose_fds,
open for the child process
@type input_fd: C{file}-like object or numeric file descriptor
@param input_fd: File descriptor for process' standard input
@param _postfork_fn: Function run after fork but before timeout (unittest)
@type postfork_fn: Callable receiving PID as parameter
@param postfork_fn: Function run after fork but before timeout
@rtype: tuple
@return: (out, err, status)
......@@ -548,8 +550,8 @@ def _RunCmdPipe(cmd, env, via_shell, cwd, interactive, timeout, noclose_fds,
cwd=cwd,
preexec_fn=preexec_fn)
if _postfork_fn:
_postfork_fn(child.pid)
if postfork_fn:
postfork_fn(child.pid)
out = StringIO()
err = StringIO()
......
......@@ -155,7 +155,7 @@ class TestIsProcessHandlingSignal(unittest.TestCase):
class _PostforkProcessReadyHelper:
"""A helper to use with _postfork_fn in RunCmd.
"""A helper to use with C{postfork_fn} in RunCmd.
It makes sure a process has reached a certain state by reading from a fifo.
......@@ -264,7 +264,7 @@ class TestRunCmd(testutils.GanetiTestCase):
(self.proc_ready_helper.write_fd, self.fifo_file))
result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2,
noclose_fds=[self.proc_ready_helper.write_fd],
_postfork_fn=self.proc_ready_helper.Ready)
postfork_fn=self.proc_ready_helper.Ready)
self.assertEqual(result.exit_code, 0)
def testTimeoutKill(self):
......@@ -276,7 +276,7 @@ class TestRunCmd(testutils.GanetiTestCase):
timeout, [self.proc_ready_helper.write_fd],
None,
_linger_timeout=0.2,
_postfork_fn=self.proc_ready_helper.Ready)
postfork_fn=self.proc_ready_helper.Ready)
self.assert_(status < 0)
self.assertEqual(-status, signal.SIGKILL)
......@@ -285,7 +285,7 @@ class TestRunCmd(testutils.GanetiTestCase):
(self.proc_ready_helper.write_fd, self.fifo_file))
result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2,
noclose_fds=[self.proc_ready_helper.write_fd],
_postfork_fn=self.proc_ready_helper.Ready)
postfork_fn=self.proc_ready_helper.Ready)
self.assert_(result.failed)
self.assertEqual(result.stdout, "sigtermed\n")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment