diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-03-01 16:24:19 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-03-02 12:15:25 +0100 |
commit | 5ad096b3f1331b175340129a8c9a5a9d711e5415 (patch) | |
tree | 41896760dde9b0ca2d45d04484c4a2308a600b0e /src/core/cgroup.c | |
parent | 606303a93ea52a70ebba55bb3152820e630f2164 (diff) |
core: expose consumed CPU time per unit
This adds support for showing the accumulated consumed CPU time per-unit
in the "systemctl status" output. The property is also readable via the
bus.
Diffstat (limited to 'src/core/cgroup.c')
-rw-r--r-- | src/core/cgroup.c | 98 |
1 files changed, 91 insertions, 7 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 10fdcc9984..6b8abb4802 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1029,16 +1029,100 @@ int manager_notify_cgroup_empty(Manager *m, const char *cgroup) { assert(cgroup); u = manager_get_unit_by_cgroup(m, cgroup); - if (u) { - r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); - if (r > 0) { - if (UNIT_VTABLE(u)->notify_cgroup_empty) - UNIT_VTABLE(u)->notify_cgroup_empty(u); + if (!u) + return 0; - unit_add_to_gc_queue(u); - } + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); + if (r <= 0) + return r; + + if (UNIT_VTABLE(u)->notify_cgroup_empty) + UNIT_VTABLE(u)->notify_cgroup_empty(u); + + unit_add_to_gc_queue(u); + return 0; +} + +int unit_get_memory_current(Unit *u, uint64_t *ret) { + _cleanup_free_ char *v = NULL; + int r; + + assert(u); + assert(ret); + + if (!u->cgroup_path) + return -ENODATA; + + if ((u->cgroup_realized_mask & CGROUP_MEMORY) == 0) + return -ENODATA; + + r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v); + if (r == -ENOENT) + return -ENODATA; + if (r < 0) + return r; + + return safe_atou64(v, ret); +} + +static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) { + _cleanup_free_ char *v = NULL; + uint64_t ns; + int r; + + assert(u); + assert(ret); + + if (!u->cgroup_path) + return -ENODATA; + + if ((u->cgroup_realized_mask & CGROUP_CPUACCT) == 0) + return -ENODATA; + + r = cg_get_attribute("cpuacct", u->cgroup_path, "cpuacct.usage", &v); + if (r == -ENOENT) + return -ENODATA; + if (r < 0) + return r; + + r = safe_atou64(v, &ns); + if (r < 0) + return r; + + *ret = ns; + return 0; +} + +int unit_get_cpu_usage(Unit *u, nsec_t *ret) { + nsec_t ns; + int r; + + r = unit_get_cpu_usage_raw(u, &ns); + if (r < 0) + return r; + + if (ns > u->cpuacct_usage_base) + ns -= u->cpuacct_usage_base; + else + ns = 0; + + *ret = ns; + return 0; +} + +int unit_reset_cpu_usage(Unit *u) { + nsec_t ns; + int r; + + assert(u); + + r = unit_get_cpu_usage_raw(u, &ns); + if (r < 0) { + u->cpuacct_usage_base = 0; + return r; } + u->cpuacct_usage_base = ns; return 0; } |