summaryrefslogtreecommitdiff
path: root/runtime/exec_utils.h
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2024-06-10 16:28:02 +0100
committer Jiakai Zhang <jiakaiz@google.com> 2024-06-11 12:56:52 +0000
commit0239c6d0185d7ab4f864b63bee4a6855ca499b89 (patch)
tree1aebed8c6b26b886b73dddd6dff9aa684f4b111c /runtime/exec_utils.h
parentd763615a736611f4502cce7fc2516d93737d676c (diff)
Use process groups to manage artd's subprocesses.
This change adds a new option `new_process_group` to ExecUtils, and this option is only used by artd to manage its subprocesses. artd creates a process group for each child process and its descendants, and it uses `kill(-pid, SIGKILL)` to kill the whole process group upon job cancellation. Before this change, ExecUtils always creates a new process group for a child process. This behavior can be dated back to https://android.googlesource.com/platform/art/+/5643b786dd48df1f4b89a39e6024a22d032c79d4%5E%21/. A comment on the `setpgid` call says: "change process groups, so we don't get reaped by ProcessManager". We cannot find out why changing the process group was needed or how process reaping was related to process groups at that time because there isn't such a thing called "ProcessManager" in Android anymore. However, we don't need this behavior today because the usage of the code that does fork and exec has completely changed. At the time where the original CL was submitted, the code was for the runtime to generate a persistent boot image on /data. Today, the runtime never generates a persistent boot image because it's considered insecure. Today, ExecUtils is mostly used in tests. Other than tests, it's only used in four places: Zygote, odrefresh, artd, and dexopt_chroot_setup. - Zygote uses it to call dex2oat to create an in-memory boot image. It doesn't make sense to keep dex2oat running when Zygote (the memfd owner) is killed. - odrefresh uses it to call dex2oat to create persistent boot images. We do want to kill dex2oat when killing odrefresh. - artd uses it to call dex2oat, profman, derive_classpath, and odrefresh. It sets `new_process_group` to true, so it's behavior regarding process groups is unchanged. It's a service managed by the service manager. The service manager uses cgroups, not process grups, to manage and kill processes, so creating new process groups for artd's children is fine. - dexopt_chroot_setup uses it to call apexd and linkerconfig. We do want to kill apexd and linkerconfig when dexopt_chroot_setup is killed. Therefore, changing this behavior is fine. After this change, ExecUtils no longer creates a new process group for a child process unless `new_process_group` is set to true. Bug: 345723405 Bug: 311377497 Test: m test-art-host-gtest-art_runtime_tests Test: m test-art-host-gtest-art_artd_tests Test: - 1. adb shell pm compile -m speed -f -v com.android.settings 2. adb shell pm art cancel <job-id> 3. No change to the existing behavior: dex2oat is still killed. Test: - 1. adb shell pm art pr-dexopt-job --run 2. Press Ctrl+C. 3. Both odrefresh and dex2oat are killed. Change-Id: I3058fc68a6bd5f98617422c1eb0861648b144a51
Diffstat (limited to 'runtime/exec_utils.h')
-rw-r--r--runtime/exec_utils.h9
1 files changed, 7 insertions, 2 deletions
diff --git a/runtime/exec_utils.h b/runtime/exec_utils.h
index 8e3e3df15d..ebcc2e4e66 100644
--- a/runtime/exec_utils.h
+++ b/runtime/exec_utils.h
@@ -94,11 +94,16 @@ class EXPORT ExecUtils {
int timeout_sec,
/*out*/ std::string* error_msg) const;
- // Same as above, but also collects stat of the process and calls callbacks. The stat is collected
- // no matter the child process succeeds or not.
+ // Same as above, but also collects stat of the process, calls callbacks, and supports creating a
+ // new process group. The stat is collected no matter the child process succeeds or not.
+ //
+ // Programs used by artd (odrefresh, dex2oat, profman) should NOT set `new_process_group` to true
+ // when spawning child processes because artd needs to kill an entire process subtree by killing
+ // the process group.
virtual ExecResult ExecAndReturnResult(const std::vector<std::string>& arg_vector,
int timeout_sec,
const ExecCallbacks& callbacks,
+ bool new_process_group,
/*out*/ ProcessStat* stat,
/*out*/ std::string* error_msg) const;