Re-enable file descriptor caching and add option to skip caching
This reverts commit bee9f5718bd2dfedb615767bbd25147b4f3eed15
"libprocessgroup: Disable file descriptor caching temporarily" and adds
option to use SetTaskProfiles and SetProcessProfiles without file caching.
This option is used from JNI to avoid access denials because cached files
are not whitelisted for JNI usage.
Bug: 123868658
Bug: 123043091
Test: boot using svelte target
Change-Id: I76b9d6af8a1dd4464cb3cf3e6dc327980efdf361
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 4b45c87..40d8d90 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -138,31 +138,38 @@
SetCgroupAction::SetCgroupAction(const CgroupController& c, const std::string& p)
: controller_(c), path_(p) {
-#ifdef CACHE_FILE_DESCRIPTORS
- // cache file descriptor only if path is app independent
+ // file descriptors for app-dependent paths can't be cached
if (IsAppDependentPath(path_)) {
// file descriptor is not cached
- fd_.reset(-2);
+ fd_.reset(FDS_APP_DEPENDENT);
return;
}
- std::string tasks_path = c.GetTasksFilePath(p);
+ // file descriptor can be cached later on request
+ fd_.reset(FDS_NOT_CACHED);
+}
+
+void SetCgroupAction::EnableResourceCaching() {
+ if (fd_ != FDS_NOT_CACHED) {
+ return;
+ }
+
+ std::string tasks_path = controller_.GetTasksFilePath(path_);
if (access(tasks_path.c_str(), W_OK) != 0) {
// file is not accessible
- fd_.reset(-1);
+ fd_.reset(FDS_INACCESSIBLE);
return;
}
unique_fd fd(TEMP_FAILURE_RETRY(open(tasks_path.c_str(), O_WRONLY | O_CLOEXEC)));
if (fd < 0) {
PLOG(ERROR) << "Failed to cache fd '" << tasks_path << "'";
- fd_.reset(-1);
+ fd_.reset(FDS_INACCESSIBLE);
return;
}
fd_ = std::move(fd);
-#endif
}
bool SetCgroupAction::AddTidToCgroup(int tid, int fd) {
@@ -184,8 +191,7 @@
}
bool SetCgroupAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
-#ifdef CACHE_FILE_DESCRIPTORS
- if (fd_ >= 0) {
+ if (IsFdValid()) {
// fd is cached, reuse it
if (!AddTidToCgroup(pid, fd_)) {
LOG(ERROR) << "Failed to add task into cgroup";
@@ -194,12 +200,12 @@
return true;
}
- if (fd_ == -1) {
+ if (fd_ == FDS_INACCESSIBLE) {
// no permissions to access the file, ignore
return true;
}
- // this is app-dependent path, file descriptor is not cached
+ // this is app-dependent path and fd is not cached or cached fd can't be used
std::string procs_path = controller()->GetProcsFilePath(path_, uid, pid);
unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(procs_path.c_str(), O_WRONLY | O_CLOEXEC)));
if (tmp_fd < 0) {
@@ -212,25 +218,10 @@
}
return true;
-#else
- std::string procs_path = controller()->GetProcsFilePath(path_, uid, pid);
- unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(procs_path.c_str(), O_WRONLY | O_CLOEXEC)));
- if (tmp_fd < 0) {
- // no permissions to access the file, ignore
- return true;
- }
- if (!AddTidToCgroup(pid, tmp_fd)) {
- LOG(ERROR) << "Failed to add task into cgroup";
- return false;
- }
-
- return true;
-#endif
}
bool SetCgroupAction::ExecuteForTask(int tid) const {
-#ifdef CACHE_FILE_DESCRIPTORS
- if (fd_ >= 0) {
+ if (IsFdValid()) {
// fd is cached, reuse it
if (!AddTidToCgroup(tid, fd_)) {
LOG(ERROR) << "Failed to add task into cgroup";
@@ -239,20 +230,23 @@
return true;
}
- if (fd_ == -1) {
+ if (fd_ == FDS_INACCESSIBLE) {
// no permissions to access the file, ignore
return true;
}
- // application-dependent path can't be used with tid
- LOG(ERROR) << "Application profile can't be applied to a thread";
- return false;
-#else
+ if (fd_ == FDS_APP_DEPENDENT) {
+ // application-dependent path can't be used with tid
+ PLOG(ERROR) << "Application profile can't be applied to a thread";
+ return false;
+ }
+
+ // fd was not cached because cached fd can't be used
std::string tasks_path = controller()->GetTasksFilePath(path_);
unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(tasks_path.c_str(), O_WRONLY | O_CLOEXEC)));
if (tmp_fd < 0) {
- // no permissions to access the file, ignore
- return true;
+ PLOG(WARNING) << "Failed to open " << tasks_path << ": " << strerror(errno);
+ return false;
}
if (!AddTidToCgroup(tid, tmp_fd)) {
LOG(ERROR) << "Failed to add task into cgroup";
@@ -260,7 +254,6 @@
}
return true;
-#endif
}
bool TaskProfile::ExecuteForProcess(uid_t uid, pid_t pid) const {
@@ -284,6 +277,18 @@
return true;
}
+void TaskProfile::EnableResourceCaching() {
+ if (res_cached_) {
+ return;
+ }
+
+ for (auto& element : elements_) {
+ element->EnableResourceCaching();
+ }
+
+ res_cached_ = true;
+}
+
TaskProfiles& TaskProfiles::GetInstance() {
// Deliberately leak this object to avoid a race between destruction on
// process exit and concurrent access from another thread.
@@ -411,7 +416,7 @@
return true;
}
-const TaskProfile* TaskProfiles::GetProfile(const std::string& name) const {
+TaskProfile* TaskProfiles::GetProfile(const std::string& name) const {
auto iter = profiles_.find(name);
if (iter != profiles_.end()) {