From: Yaping Li <202858510+YapingLi04@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:19:42 +0000 (-0700) Subject: cgroup-util: add cg_get_keyed_attribute_uint64() helper X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6fe4a16f364ad268cb0717879d68a007cd7e652f;p=thirdparty%2Fsystemd.git cgroup-util: add cg_get_keyed_attribute_uint64() helper 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. --- diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index d613e65c4b8..1e42aa60aa4 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -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; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 68a771e5aed..7cf0f779b8b 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -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); diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index a9bf64a6165..0c93339a029 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -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; } diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 7bcd6777df2..baf7dde1272 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -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; diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 55e17df46f0..c0e04041a7e 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -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);