update_engine: resume suspended PostInstall action to handle termination
PostinstallRunnerActionTest.RunAsRootCancelPostinstallActionTest exposes
an issue when PostinstallRunnerAction tries to terminate an action that
has been suspended. PostinstallRunnerAction::TerminateProcessing() uses
Subprocess::KillExec() to terminate the action by sending SIGTERM to the
child process associated with the action. However, if the action has
been suspended by PostinstallRunnerAction::SuspendAction(), the child
process won't receive the SIGTERM until it's resumed. This CL changes
PostinstallRunnerAction::TerminateProcessing() to resume the child
process after issuing SIGTERM.
BUG=chromium:678643
TEST=Verified that no orphaned 'sleep' process is left after running
PostinstallRunnerActionTest.RunAsRootCancelPostinstallActionTest.
Reviewed-on: https://chromium-review.googlesource.com/426878
Commit-Ready: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Luigi Semenzato <semenzato@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
(cherry picked from commit f13a40924e0b1d71df07738078cebc933dd90a7e)
Change-Id: I631da8bb5bf29141623f3eef3fc7c438cbccc98a
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index 11eec34..27a9ed6 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -360,6 +360,8 @@
return;
if (kill(current_command_, SIGSTOP) != 0) {
PLOG(ERROR) << "Couldn't pause child process " << current_command_;
+ } else {
+ is_current_command_suspended_ = true;
}
}
@@ -368,6 +370,8 @@
return;
if (kill(current_command_, SIGCONT) != 0) {
PLOG(ERROR) << "Couldn't resume child process " << current_command_;
+ } else {
+ is_current_command_suspended_ = false;
}
}
@@ -377,6 +381,13 @@
// Calling KillExec() will discard the callback we registered and therefore
// the unretained reference to this object.
Subprocess::Get().KillExec(current_command_);
+
+ // If the command has been suspended, resume it after KillExec() so that the
+ // process can process the SIGTERM sent by KillExec().
+ if (is_current_command_suspended_) {
+ ResumeAction();
+ }
+
current_command_ = 0;
Cleanup();
}