Loading init/service.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -289,6 +289,10 @@ void Service::Reap(const siginfo_t& siginfo) { if (flags_ & SVC_EXEC) UnSetExec(); if (name_ == "zygote" || name_ == "zygote64") { removeAllEmptyProcessGroups(); } if (flags_ & SVC_TEMPORARY) return; pid_ = 0; Loading libprocessgroup/include/processgroup/processgroup.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading libprocessgroup/processgroup.cpp +28 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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) { Loading @@ -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; Loading @@ -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; } Loading @@ -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 Loading Loading
init/service.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -289,6 +289,10 @@ void Service::Reap(const siginfo_t& siginfo) { if (flags_ & SVC_EXEC) UnSetExec(); if (name_ == "zygote" || name_ == "zygote64") { removeAllEmptyProcessGroups(); } if (flags_ & SVC_TEMPORARY) return; pid_ = 0; Loading
libprocessgroup/include/processgroup/processgroup.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
libprocessgroup/processgroup.cpp +28 −5 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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) { Loading @@ -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; Loading @@ -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; } Loading @@ -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 Loading