diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json index b668dcb13..7e0396467 100644 --- a/libprocessgroup/profiles/task_profiles.json +++ b/libprocessgroup/profiles/task_profiles.json @@ -15,21 +15,48 @@ "Controller": "cpuset", "File": "top-app/cpus" }, + { + "Name": "MemStats", + "Controller": "memory", + "File": "memory.stat" + }, { "Name": "MemLimit", "Controller": "memory", - "File": "memory.limit_in_bytes" + "File": "memory.limit_in_bytes", + "FileV2": "memory.max" }, { "Name": "MemSoftLimit", "Controller": "memory", - "File": "memory.soft_limit_in_bytes" + "File": "memory.soft_limit_in_bytes", + "FileV2": "memory.low" }, { "Name": "MemSwappiness", "Controller": "memory", "File": "memory.swappiness" }, + { + "Name": "MemUsage", + "Controller": "memory", + "File": "memory.usage_in_bytes" + }, + { + "Name": "MemAndSwapUsage", + "Controller": "memory", + "File": "memory.memsw.usage_in_bytes" + }, + { + "Name": "MemPressureLevel", + "Controller": "memory", + "File": "memory.pressure_level" + }, + { + "Name": "MemCgroupEventControl", + "Controller": "memory", + "File": "cgroup.event_control" + }, { "Name": "UClampMin", "Controller": "cpu", diff --git a/libprocessgroup/profiles/task_profiles.proto b/libprocessgroup/profiles/task_profiles.proto index 2a09217ab..ebcd9b56e 100644 --- a/libprocessgroup/profiles/task_profiles.proto +++ b/libprocessgroup/profiles/task_profiles.proto @@ -25,12 +25,13 @@ message TaskProfiles { repeated AggregateProfiles aggregateprofiles = 3 [json_name = "AggregateProfiles"]; } -// Next: 5 +// Next: 6 message Attribute { string name = 1 [json_name = "Name"]; string controller = 2 [json_name = "Controller"]; string file = 3 [json_name = "File"]; - string optional = 4 [json_name = "Optional"]; + string filev2 = 4 [json_name = "FileV2"]; + string optional = 5 [json_name = "Optional"]; } // Next: 3 diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp index 4a2bf381b..78a316a6f 100644 --- a/libprocessgroup/task_profiles.cpp +++ b/libprocessgroup/task_profiles.cpp @@ -129,11 +129,12 @@ 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; } @@ -633,12 +634,19 @@ bool TaskProfiles::Load(const CgroupMap& cg_map, const std::string& file_name) { std::string name = attr[i]["Name"].asString(); std::string controller_name = attr[i]["Controller"].asString(); std::string file_attr = attr[i]["File"].asString(); + std::string file_v2_attr = attr[i]["FileV2"].asString(); + + if (!file_v2_attr.empty() && file_attr.empty()) { + LOG(ERROR) << "Attribute " << name << " has FileV2 but no File property"; + return false; + } auto controller = cg_map.FindController(controller_name); if (controller.HasValue()) { auto iter = attributes_.find(name); if (iter == attributes_.end()) { - attributes_[name] = std::make_unique(controller, file_attr); + attributes_[name] = + std::make_unique(controller, file_attr, file_v2_attr); } else { iter->second->Reset(controller, file_attr); } diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h index 47475115e..df08f65c7 100644 --- a/libprocessgroup/task_profiles.h +++ b/libprocessgroup/task_profiles.h @@ -37,8 +37,12 @@ class IProfileAttribute { class ProfileAttribute : public IProfileAttribute { public: - ProfileAttribute(const CgroupController& controller, const std::string& file_name) - : controller_(controller), file_name_(file_name) {} + // Cgroup attributes may have different names in the v1 and v2 hierarchies. If `file_v2_name` is + // not empty, `file_name` is the name for the v1 hierarchy and `file_v2_name` is the name for + // the v2 hierarchy. If `file_v2_name` is empty, `file_name` is used for both hierarchies. + ProfileAttribute(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) {} ~ProfileAttribute() = default; const CgroupController* controller() const override { return &controller_; } @@ -50,6 +54,7 @@ class ProfileAttribute : public IProfileAttribute { private: CgroupController controller_; std::string file_name_; + std::string file_v2_name_; }; // Abstract profile element