diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp index 1276a72a6..f51b07671 100644 --- a/libprocessgroup/task_profiles.cpp +++ b/libprocessgroup/task_profiles.cpp @@ -114,9 +114,26 @@ bool FdCacheHelper::IsAppDependentPath(const std::string& path) { IProfileAttribute::~IProfileAttribute() = default; -void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name) { +const std::string& ProfileAttribute::file_name() const { + if (controller()->version() == 2 && !file_v2_name_.empty()) return file_v2_name_; + return file_name_; +} + +void ProfileAttribute::Reset(const CgroupController& controller, const std::string& file_name, + const std::string& file_v2_name) { controller_ = controller; file_name_ = file_name; + file_v2_name_ = file_v2_name; +} + +bool ProfileAttribute::GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const { + if (controller()->version() == 2) { + // all cgroup v2 attributes use the same process group hierarchy + *path = StringPrintf("%s/uid_%u/pid_%d/%s", controller()->path(), uid, pid, + file_name().c_str()); + return true; + } + return GetPathForTask(pid, path); } bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const { @@ -129,12 +146,11 @@ bool ProfileAttribute::GetPathForTask(int tid, std::string* path) const { return true; } - const std::string& file_name = - controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_; if (subgroup.empty()) { - *path = StringPrintf("%s/%s", controller()->path(), file_name.c_str()); + *path = StringPrintf("%s/%s", controller()->path(), file_name().c_str()); } else { - *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(), file_name.c_str()); + *path = StringPrintf("%s/%s/%s", controller()->path(), subgroup.c_str(), + file_name().c_str()); } return true; } @@ -144,9 +160,7 @@ bool ProfileAttribute::GetPathForUID(uid_t uid, std::string* path) const { return true; } - const std::string& file_name = - controller()->version() == 2 && !file_v2_name_.empty() ? file_v2_name_ : file_name_; - *path = StringPrintf("%s/uid_%u/%s", controller()->path(), uid, file_name.c_str()); + *path = StringPrintf("%s/uid_%u/%s", controller()->path(), uid, file_name().c_str()); return true; } @@ -205,18 +219,7 @@ bool SetTimerSlackAction::ExecuteForTask(int) const { #endif -bool SetAttributeAction::ExecuteForProcess(uid_t, pid_t pid) const { - return ExecuteForTask(pid); -} - -bool SetAttributeAction::ExecuteForTask(int tid) const { - std::string path; - - if (!attribute_->GetPathForTask(tid, &path)) { - LOG(ERROR) << "Failed to find cgroup for tid " << tid; - return false; - } - +bool SetAttributeAction::WriteValueToFile(const std::string& path) const { if (!WriteStringToFile(value_, path)) { if (access(path.c_str(), F_OK) < 0) { if (optional_) { @@ -236,6 +239,28 @@ bool SetAttributeAction::ExecuteForTask(int tid) const { return true; } +bool SetAttributeAction::ExecuteForProcess(uid_t uid, pid_t pid) const { + std::string path; + + if (!attribute_->GetPathForProcess(uid, pid, &path)) { + LOG(ERROR) << "Failed to find cgroup for uid " << uid << " pid " << pid; + return false; + } + + return WriteValueToFile(path); +} + +bool SetAttributeAction::ExecuteForTask(int tid) const { + std::string path; + + if (!attribute_->GetPathForTask(tid, &path)) { + LOG(ERROR) << "Failed to find cgroup for tid " << tid; + return false; + } + + return WriteValueToFile(path); +} + bool SetAttributeAction::ExecuteForUID(uid_t uid) const { std::string path; @@ -816,7 +841,7 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) { attributes_[name] = std::make_unique(controller, file_attr, file_v2_attr); } else { - iter->second->Reset(controller, file_attr); + iter->second->Reset(controller, file_attr, file_v2_attr); } } else { LOG(WARNING) << "Controller " << controller_name << " is not found"; diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h index a62c5b0a9..4663f64e2 100644 --- a/libprocessgroup/task_profiles.h +++ b/libprocessgroup/task_profiles.h @@ -32,9 +32,11 @@ class IProfileAttribute { public: virtual ~IProfileAttribute() = 0; - virtual void Reset(const CgroupController& controller, const std::string& file_name) = 0; + virtual void Reset(const CgroupController& controller, const std::string& file_name, + const std::string& file_v2_name) = 0; virtual const CgroupController* controller() const = 0; virtual const std::string& file_name() const = 0; + virtual bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const = 0; virtual bool GetPathForTask(int tid, std::string* path) const = 0; virtual bool GetPathForUID(uid_t uid, std::string* path) const = 0; }; @@ -50,9 +52,11 @@ class ProfileAttribute : public IProfileAttribute { ~ProfileAttribute() = default; const CgroupController* controller() const override { return &controller_; } - const std::string& file_name() const override { return file_name_; } - void Reset(const CgroupController& controller, const std::string& file_name) override; + const std::string& file_name() const override; + void Reset(const CgroupController& controller, const std::string& file_name, + const std::string& file_v2_name) override; + bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override; bool GetPathForTask(int tid, std::string* path) const override; bool GetPathForUID(uid_t uid, std::string* path) const override; @@ -131,6 +135,8 @@ class SetAttributeAction : public ProfileAction { const IProfileAttribute* attribute_; std::string value_; bool optional_; + + bool WriteValueToFile(const std::string& path) const; }; // Set cgroup profile element diff --git a/libprocessgroup/task_profiles_test.cpp b/libprocessgroup/task_profiles_test.cpp index eadbe7697..99d819a7c 100644 --- a/libprocessgroup/task_profiles_test.cpp +++ b/libprocessgroup/task_profiles_test.cpp @@ -102,7 +102,8 @@ class ProfileAttributeMock : public IProfileAttribute { public: ProfileAttributeMock(const std::string& file_name) : file_name_(file_name) {} ~ProfileAttributeMock() override = default; - void Reset(const CgroupController& controller, const std::string& file_name) override { + void Reset(const CgroupController& controller, const std::string& file_name, + const std::string& file_v2_name) override { CHECK(false); } const CgroupController* controller() const override { @@ -110,6 +111,9 @@ class ProfileAttributeMock : public IProfileAttribute { return {}; } const std::string& file_name() const override { return file_name_; } + bool GetPathForProcess(uid_t uid, pid_t pid, std::string* path) const override { + return GetPathForTask(pid, path); + } bool GetPathForTask(int tid, std::string* path) const override { #ifdef __ANDROID__ CHECK(CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, path)); @@ -125,9 +129,7 @@ class ProfileAttributeMock : public IProfileAttribute { return true; }; - bool GetPathForUID(uid_t, std::string*) const override { - return false; - } + bool GetPathForUID(uid_t, std::string*) const override { return false; } private: const std::string file_name_;