]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cgroup-util: add cg_get_keyed_attribute_uint64() helper
authorYaping Li <202858510+YapingLi04@users.noreply.github.com>
Wed, 8 Apr 2026 17:19:42 +0000 (10:19 -0700)
committerYaping Li <202858510+YapingLi04@users.noreply.github.com>
Thu, 9 Apr 2026 21:45:05 +0000 (14:45 -0700)
Multiple callers of cg_get_keyed_attribute() follow the same pattern of
reading a single keyed attribute and then parsing it as uint64_t with
safe_atou64(). Add a helper that combines both steps.

Convert all existing single-key + uint64 call sites in cgtop, cgroup.c,
and oomd-util.c to use the new helper.

src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/cgtop/cgtop.c
src/core/cgroup.c
src/oom/oomd-util.c

index d613e65c4b8202b06d1cc1ffcbdd3916e915b2ea..1e42aa60aa4ccb74f92f23946dccb63837f1ddaf 100644 (file)
@@ -1560,6 +1560,24 @@ fail:
         return r;
 }
 
+int cg_get_keyed_attribute_uint64(const char *path, const char *attribute, const char *key, uint64_t *ret) {
+        _cleanup_free_ char *val = NULL;
+        int r;
+
+        assert(key);
+        assert(ret);
+
+        r = cg_get_keyed_attribute(path, attribute, STRV_MAKE(key), &val);
+        if (r < 0)
+                return r;
+
+        r = safe_atou64(val, ret);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to parse value '%s' of key '%s' in cgroup attribute '%s': %m", val, key, attribute);
+
+        return 0;
+}
+
 int cg_mask_to_string(CGroupMask mask, char **ret) {
         _cleanup_free_ char *s = NULL;
         bool space = false;
index 68a771e5aed6478d7dcac158c31b0a54e3ed1332..7cf0f779b8b95475bcc4c75e50485a81904e2242 100644 (file)
@@ -165,6 +165,7 @@ int cg_get_attribute_as_uint64(const char *path, const char *attribute, uint64_t
 int cg_get_attribute_as_bool(const char *path, const char *attribute);
 
 int cg_get_keyed_attribute(const char *path, const char *attribute, char * const *keys, char **values);
+int cg_get_keyed_attribute_uint64(const char *path, const char *attribute, const char *key, uint64_t *ret);
 
 int cg_get_owner(const char *path, uid_t *ret_uid);
 
index a9bf64a61651dc77c0d2e6256df435a1d74a2701..0c93339a029ec69e1cbb6791f7fc8ebe8ec367a6 100644 (file)
@@ -285,19 +285,14 @@ static int process_cpu(Group *g, unsigned iteration) {
                 if (r < 0)
                         return r;
         } else {
-                _cleanup_free_ char *val = NULL;
                 uint64_t u;
 
-                r = cg_get_keyed_attribute(g->path, "cpu.stat", STRV_MAKE("usage_usec"), &val);
+                r = cg_get_keyed_attribute_uint64(g->path, "cpu.stat", "usage_usec", &u);
                 if (IN_SET(r, -ENOENT, -ENXIO))
                         return 0;
                 if (r < 0)
                         return r;
 
-                r = safe_atou64(val, &u);
-                if (r < 0)
-                        return r;
-
                 new_usage = u * NSEC_PER_USEC;
         }
 
index 7bcd6777df244b9d214e5c3fa538bdc685a1671f..baf7dde12724a8e211a16c5ed8b6c9558d93609f 100644 (file)
@@ -2980,9 +2980,8 @@ int unit_check_oomd_kill(Unit *u) {
 }
 
 int unit_check_oom(Unit *u) {
-        _cleanup_free_ char *oom_kill = NULL;
         bool increased;
-        uint64_t c;
+        uint64_t c = 0;
         int r;
 
         CGroupRuntime *crt = unit_get_cgroup_runtime(u);
@@ -2997,33 +2996,25 @@ int unit_check_oom(Unit *u) {
          * back to reading oom_kill if we can't find the file or field. */
 
         if (ctx->memory_oom_group) {
-                r = cg_get_keyed_attribute(
+                r = cg_get_keyed_attribute_uint64(
                                 crt->cgroup_path,
                                 "memory.events.local",
-                                STRV_MAKE("oom_group_kill"),
-                                &oom_kill);
+                                "oom_group_kill",
+                                &c);
                 if (r < 0 && !IN_SET(r, -ENOENT, -ENXIO))
                         return log_unit_debug_errno(u, r, "Failed to read oom_group_kill field of memory.events.local cgroup attribute, ignoring: %m");
         }
 
-        if (isempty(oom_kill)) {
-                r = cg_get_keyed_attribute(
+        if (!ctx->memory_oom_group || r < 0) {
+                r = cg_get_keyed_attribute_uint64(
                                 crt->cgroup_path,
                                 "memory.events",
-                                STRV_MAKE("oom_kill"),
-                                &oom_kill);
+                                "oom_kill",
+                                &c);
                 if (r < 0 && !IN_SET(r, -ENOENT, -ENXIO))
                         return log_unit_debug_errno(u, r, "Failed to read oom_kill field of memory.events cgroup attribute: %m");
         }
 
-        if (!oom_kill)
-                c = 0;
-        else {
-                r = safe_atou64(oom_kill, &c);
-                if (r < 0)
-                        return log_unit_debug_errno(u, r, "Failed to parse memory.events cgroup oom field: %m");
-        }
-
         increased = c > crt->oom_kill_last;
         crt->oom_kill_last = c;
 
@@ -3569,14 +3560,9 @@ static int unit_get_cpu_usage_raw(const Unit *u, const CGroupRuntime *crt, nsec_
         if (unit_has_host_root_cgroup(u))
                 return procfs_cpu_get_usage(ret);
 
-        _cleanup_free_ char *val = NULL;
         uint64_t us;
 
-        r = cg_get_keyed_attribute(crt->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val);
-        if (r < 0)
-                return r;
-
-        r = safe_atou64(val, &us);
+        r = cg_get_keyed_attribute_uint64(crt->cgroup_path, "cpu.stat", "usage_usec", &us);
         if (r < 0)
                 return r;
 
index 55e17df46f08c32a1663bcfe2a066f6ad8cfd98f..c0e04041a7e6a83ea0293efcba61901aa866850d 100644 (file)
@@ -624,7 +624,7 @@ int oomd_select_by_swap_usage(Hashmap *h, uint64_t threshold_usage, OomdCGroupCo
 
 int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
         _cleanup_(oomd_cgroup_context_unrefp) OomdCGroupContext *ctx = NULL;
-        _cleanup_free_ char *p = NULL, *val = NULL;
+        _cleanup_free_ char *p = NULL;
         bool is_root;
         int r;
 
@@ -678,13 +678,9 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
                 else if (r < 0)
                         return log_debug_errno(r, "Error getting memory.swap.current from %s: %m", path);
 
-                r = cg_get_keyed_attribute(path, "memory.stat", STRV_MAKE("pgscan"), &val);
+                r = cg_get_keyed_attribute_uint64(path, "memory.stat", "pgscan", &ctx->pgscan);
                 if (r < 0)
                         return log_debug_errno(r, "Error getting pgscan from memory.stat under %s: %m", path);
-
-                r = safe_atou64(val, &ctx->pgscan);
-                if (r < 0)
-                        return log_debug_errno(r, "Error converting pgscan value to uint64_t: %m");
         }
 
         *ret = TAKE_PTR(ctx);