diff options
author | Suren Baghdasaryan <surenb@google.com> | 2022-04-28 13:24:28 -0700 |
---|---|---|
committer | Suren Baghdasaryan <surenb@google.com> | 2022-05-04 00:44:39 +0000 |
commit | 6761b6dcdc31a10d7e1b3652400bfae9eb2eed17 (patch) | |
tree | 3639ed9f6b9f3c7316250cb577e07732c382e0e8 | |
parent | 7e0df03bc9df8ca31e422959fba0bf5f0c8b196f (diff) | |
download | core-6761b6dcdc31a10d7e1b3652400bfae9eb2eed17.tar.gz |
libprocessgroup: Add a function to remove only empty process groups
When system_server and zygote crash or get killed, all apps also get
killed but their process groups are left empty. Provide a function to
remove all empty process groups so that init can purge them when this
even happens.
Bug: 228160715
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Change-Id: Ife38ca021e80cd38106f218ae13183e8c2631bf0
Merged-In: Ife38ca021e80cd38106f218ae13183e8c2631bf0
-rw-r--r-- | libprocessgroup/include/processgroup/processgroup.h | 1 | ||||
-rw-r--r-- | libprocessgroup/processgroup.cpp | 33 |
2 files changed, 29 insertions, 5 deletions
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h index c5badc941..39b9f3fc0 100644 --- a/libprocessgroup/include/processgroup/processgroup.h +++ b/libprocessgroup/include/processgroup/processgroup.h @@ -67,6 +67,7 @@ bool setProcessGroupSoftLimit(uid_t uid, int initialPid, int64_t softLimitInByte bool setProcessGroupLimit(uid_t uid, int initialPid, int64_t limitInBytes); void removeAllProcessGroups(void); +void removeAllEmptyProcessGroups(void); // Provides the path for an attribute in a specific process group // Returns false in case of error, true in case of success diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp index e3a80e97b..267e62c67 100644 --- a/libprocessgroup/processgroup.cpp +++ b/libprocessgroup/processgroup.cpp @@ -200,7 +200,7 @@ static int RemoveProcessGroup(const char* cgroup, uid_t uid, int pid, unsigned i return ret; } -static bool RemoveUidProcessGroups(const std::string& uid_path) { +static bool RemoveUidProcessGroups(const std::string& uid_path, bool empty_only) { std::unique_ptr<DIR, decltype(&closedir)> uid(opendir(uid_path.c_str()), closedir); bool empty = true; if (uid != NULL) { @@ -215,6 +215,21 @@ static bool RemoveUidProcessGroups(const std::string& uid_path) { } auto path = StringPrintf("%s/%s", uid_path.c_str(), dir->d_name); + if (empty_only) { + struct stat st; + auto procs_file = StringPrintf("%s/%s", path.c_str(), + PROCESSGROUP_CGROUP_PROCS_FILE); + if (stat(procs_file.c_str(), &st) == -1) { + PLOG(ERROR) << "Failed to get stats for " << procs_file; + continue; + } + if (st.st_size > 0) { + // skip non-empty groups + LOG(VERBOSE) << "Skipping non-empty group " << path; + empty = false; + continue; + } + } LOG(VERBOSE) << "Removing " << path; if (rmdir(path.c_str()) == -1) { if (errno != EBUSY) { @@ -227,9 +242,7 @@ static bool RemoveUidProcessGroups(const std::string& uid_path) { return empty; } -void removeAllProcessGroups() { - LOG(VERBOSE) << "removeAllProcessGroups()"; - +void removeAllProcessGroupsInternal(bool empty_only) { std::vector<std::string> cgroups; std::string path, memcg_apps_path; @@ -256,7 +269,7 @@ void removeAllProcessGroups() { } auto path = StringPrintf("%s/%s", cgroup_root_path.c_str(), dir->d_name); - if (!RemoveUidProcessGroups(path)) { + if (!RemoveUidProcessGroups(path, empty_only)) { LOG(VERBOSE) << "Skip removing " << path; continue; } @@ -269,6 +282,16 @@ void removeAllProcessGroups() { } } +void removeAllProcessGroups() { + LOG(VERBOSE) << "removeAllProcessGroups()"; + removeAllProcessGroupsInternal(false); +} + +void removeAllEmptyProcessGroups() { + LOG(VERBOSE) << "removeAllEmptyProcessGroups()"; + removeAllProcessGroupsInternal(true); +} + /** * Process groups are primarily created by the Zygote, meaning that uid/pid groups are created by * the user root. Ownership for the newly created cgroup and all of its files must thus be |