diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h index 7e6bf45cf..f73ec2d41 100644 --- a/libprocessgroup/include/processgroup/processgroup.h +++ b/libprocessgroup/include/processgroup/processgroup.h @@ -39,6 +39,11 @@ static constexpr const char* CGROUPS_RC_PATH = "/dev/cgroup_info/cgroup.rc"; bool UsePerAppMemcg(); +// Drop the fd cache of cgroup path. It is used for when resource caching is enabled and a process +// loses the access to the path, the access checking (See SetCgroupAction::EnableResourceCaching) +// should be active again. E.g. Zygote specialization for child process. +void DropTaskProfilesResourceCaching(); + // Return 0 and removes the cgroup if there are no longer any processes in it. // Returns -1 in the case of an error occurring or if there are processes still running // even after retrying for up to 200ms. diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp index d3ac26bd1..7c191be1b 100644 --- a/libprocessgroup/processgroup.cpp +++ b/libprocessgroup/processgroup.cpp @@ -111,6 +111,10 @@ static bool isMemoryCgroupSupported() { return memcg_supported; } +void DropTaskProfilesResourceCaching() { + TaskProfiles::GetInstance().DropResourceCaching(); +} + bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector& profiles, bool use_fd_cache) { const TaskProfiles& tp = TaskProfiles::GetInstance(); diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp index edc316a8d..aee5f0cce 100644 --- a/libprocessgroup/task_profiles.cpp +++ b/libprocessgroup/task_profiles.cpp @@ -173,6 +173,15 @@ void SetCgroupAction::EnableResourceCaching() { fd_ = std::move(fd); } +void SetCgroupAction::DropResourceCaching() { + std::lock_guard lock(fd_mutex_); + if (fd_ == FDS_NOT_CACHED) { + return; + } + + fd_.reset(FDS_NOT_CACHED); +} + bool SetCgroupAction::AddTidToCgroup(int tid, int fd) { if (tid <= 0) { return true; @@ -292,6 +301,24 @@ void TaskProfile::EnableResourceCaching() { res_cached_ = true; } +void TaskProfile::DropResourceCaching() { + if (!res_cached_) { + return; + } + + for (auto& element : elements_) { + element->DropResourceCaching(); + } + + res_cached_ = false; +} + +void TaskProfiles::DropResourceCaching() const { + for (auto& iter : profiles_) { + iter.second->DropResourceCaching(); + } +} + TaskProfiles& TaskProfiles::GetInstance() { // Deliberately leak this object to avoid a race between destruction on // process exit and concurrent access from another thread. diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h index 77bac2d94..891d5b56a 100644 --- a/libprocessgroup/task_profiles.h +++ b/libprocessgroup/task_profiles.h @@ -51,6 +51,7 @@ class ProfileAction { virtual bool ExecuteForTask(int) const { return false; }; virtual void EnableResourceCaching() {} + virtual void DropResourceCaching() {} }; // Profile actions @@ -114,6 +115,7 @@ class SetCgroupAction : public ProfileAction { virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const; virtual bool ExecuteForTask(int tid) const; virtual void EnableResourceCaching(); + virtual void DropResourceCaching(); const CgroupController* controller() const { return &controller_; } std::string path() const { return path_; } @@ -145,6 +147,7 @@ class TaskProfile { bool ExecuteForProcess(uid_t uid, pid_t pid) const; bool ExecuteForTask(int tid) const; void EnableResourceCaching(); + void DropResourceCaching(); private: bool res_cached_; @@ -158,6 +161,7 @@ class TaskProfiles { TaskProfile* GetProfile(const std::string& name) const; const ProfileAttribute* GetAttribute(const std::string& name) const; + void DropResourceCaching() const; private: std::map> profiles_;