Merge "Allow to drop existing fd cache of cgroup path" am: 1e13891988
am: 9b54f0f73c

Change-Id: I9a7f22da7af150070e4965806eb4e1ea25cbf1bc
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 7e6bf45..f73ec2d 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -39,6 +39,11 @@
 
 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 d3ac26b..7c191be 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -111,6 +111,10 @@
     return memcg_supported;
 }
 
+void DropTaskProfilesResourceCaching() {
+    TaskProfiles::GetInstance().DropResourceCaching();
+}
+
 bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles,
                         bool use_fd_cache) {
     const TaskProfiles& tp = TaskProfiles::GetInstance();
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index edc316a..aee5f0c 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -173,6 +173,15 @@
     fd_ = std::move(fd);
 }
 
+void SetCgroupAction::DropResourceCaching() {
+    std::lock_guard<std::mutex> 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 @@
     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 77bac2d..891d5b5 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -51,6 +51,7 @@
     virtual bool ExecuteForTask(int) const { return false; };
 
     virtual void EnableResourceCaching() {}
+    virtual void DropResourceCaching() {}
 };
 
 // Profile actions
@@ -114,6 +115,7 @@
     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 @@
     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 @@
 
     TaskProfile* GetProfile(const std::string& name) const;
     const ProfileAttribute* GetAttribute(const std::string& name) const;
+    void DropResourceCaching() const;
 
   private:
     std::map<std::string, std::unique_ptr<TaskProfile>> profiles_;