From 2c28502bc4363b6654b617afbaeecb1efdbb98b1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 30 Nov 2025 19:09:21 +0100 Subject: [PATCH] Add getCgroupStats() function --- src/libutil/linux/cgroup.cc | 51 +++++++++++--------- src/libutil/linux/include/nix/util/cgroup.hh | 6 +++ 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/libutil/linux/cgroup.cc b/src/libutil/linux/cgroup.cc index 9e78ac6d2..928b44d6c 100644 --- a/src/libutil/linux/cgroup.cc +++ b/src/libutil/linux/cgroup.cc @@ -49,6 +49,33 @@ StringMap getCgroups(const Path & cgroupFile) return cgroups; } +CgroupStats getCgroupStats(const std::filesystem::path & cgroup) +{ + CgroupStats stats; + + auto cpustatPath = cgroup / "cpu.stat"; + + if (pathExists(cpustatPath)) { + for (auto & line : tokenizeString>(readFile(cpustatPath), "\n")) { + std::string_view userPrefix = "user_usec "; + if (hasPrefix(line, userPrefix)) { + auto n = string2Int(line.substr(userPrefix.size())); + if (n) + stats.cpuUser = std::chrono::microseconds(*n); + } + + std::string_view systemPrefix = "system_usec "; + if (hasPrefix(line, systemPrefix)) { + auto n = string2Int(line.substr(systemPrefix.size())); + if (n) + stats.cpuSystem = std::chrono::microseconds(*n); + } + } + } + + return stats; +} + static CgroupStats destroyCgroup(const std::filesystem::path & cgroup, bool returnStats) { if (!pathExists(cgroup)) @@ -114,28 +141,8 @@ static CgroupStats destroyCgroup(const std::filesystem::path & cgroup, bool retu } CgroupStats stats; - - if (returnStats) { - auto cpustatPath = cgroup / "cpu.stat"; - - if (pathExists(cpustatPath)) { - for (auto & line : tokenizeString>(readFile(cpustatPath), "\n")) { - std::string_view userPrefix = "user_usec "; - if (hasPrefix(line, userPrefix)) { - auto n = string2Int(line.substr(userPrefix.size())); - if (n) - stats.cpuUser = std::chrono::microseconds(*n); - } - - std::string_view systemPrefix = "system_usec "; - if (hasPrefix(line, systemPrefix)) { - auto n = string2Int(line.substr(systemPrefix.size())); - if (n) - stats.cpuSystem = std::chrono::microseconds(*n); - } - } - } - } + if (returnStats) + stats = getCgroupStats(cgroup); if (rmdir(cgroup.c_str()) == -1) throw SysError("deleting cgroup %s", cgroup); diff --git a/src/libutil/linux/include/nix/util/cgroup.hh b/src/libutil/linux/include/nix/util/cgroup.hh index 59de13d46..a759bdd08 100644 --- a/src/libutil/linux/include/nix/util/cgroup.hh +++ b/src/libutil/linux/include/nix/util/cgroup.hh @@ -3,6 +3,7 @@ #include #include +#include #include "nix/util/types.hh" @@ -17,6 +18,11 @@ struct CgroupStats std::optional cpuUser, cpuSystem; }; +/** + * Read statistics from the given cgroup. + */ +CgroupStats getCgroupStats(const std::filesystem::path & cgroup); + /** * Destroy the cgroup denoted by 'path'. The postcondition is that * 'path' does not exist, and thus any processes in the cgroup have