return cg_get_attribute_as_uint64("pids", crt->cgroup_path, "pids.current", ret);
}
-static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
- uint64_t ns;
+static int unit_get_cpu_usage_raw(const Unit *u, const CGroupRuntime *crt, nsec_t *ret) {
int r;
assert(u);
+ assert(crt);
assert(ret);
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt->cgroup_path)
return -ENODATA;
/* The root cgroup doesn't expose this information, let's get it from /proc instead */
r = cg_all_unified();
if (r < 0)
return r;
- if (r > 0) {
- _cleanup_free_ char *val = NULL;
- uint64_t us;
+ if (r == 0)
+ return cg_get_attribute_as_uint64("cpuacct", crt->cgroup_path, "cpuacct.usage", ret);
- r = cg_get_keyed_attribute("cpu", crt->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val);
- if (IN_SET(r, -ENOENT, -ENXIO))
- return -ENODATA;
- if (r < 0)
- return r;
+ _cleanup_free_ char *val = NULL;
+ uint64_t us;
- r = safe_atou64(val, &us);
- if (r < 0)
- return r;
+ r = cg_get_keyed_attribute("cpu", crt->cgroup_path, "cpu.stat", STRV_MAKE("usage_usec"), &val);
+ if (IN_SET(r, -ENOENT, -ENXIO))
+ return -ENODATA;
+ if (r < 0)
+ return r;
- ns = us * NSEC_PER_USEC;
- } else
- return cg_get_attribute_as_uint64("cpuacct", crt->cgroup_path, "cpuacct.usage", ret);
+ r = safe_atou64(val, &us);
+ if (r < 0)
+ return r;
+
+ *ret = us * NSEC_PER_USEC;
- *ret = ns;
return 0;
}
if (!UNIT_CGROUP_BOOL(u, cpu_accounting))
return -ENODATA;
- r = unit_get_cpu_usage_raw(u, &ns);
+ r = unit_get_cpu_usage_raw(u, crt, &ns);
if (r == -ENODATA && crt->cpu_usage_last != NSEC_INFINITY) {
/* If we can't get the CPU usage anymore (because the cgroup was already removed, for example), use our
* cached value. */
return 0;
}
-static int unit_get_io_accounting_raw(Unit *u, uint64_t ret[static _CGROUP_IO_ACCOUNTING_METRIC_MAX]) {
- static const char *const field_names[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
+static int unit_get_io_accounting_raw(
+ const Unit *u,
+ const CGroupRuntime *crt,
+ uint64_t ret[static _CGROUP_IO_ACCOUNTING_METRIC_MAX]) {
+
+ static const char* const field_names[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
[CGROUP_IO_READ_BYTES] = "rbytes=",
[CGROUP_IO_WRITE_BYTES] = "wbytes=",
[CGROUP_IO_READ_OPERATIONS] = "rios=",
[CGROUP_IO_WRITE_OPERATIONS] = "wios=",
};
+
uint64_t acc[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {};
_cleanup_free_ char *path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(u);
+ assert(crt);
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt->cgroup_path)
return -ENODATA;
if (unit_has_host_root_cgroup(u))
if (allow_cache && crt->io_accounting_last[metric] != UINT64_MAX)
goto done;
- r = unit_get_io_accounting_raw(u, raw);
+ r = unit_get_io_accounting_raw(u, crt, raw);
if (r == -ENODATA && crt->io_accounting_last[metric] != UINT64_MAX)
goto done;
if (r < 0)
return 0;
}
-int unit_reset_cpu_accounting(Unit *u) {
+static int unit_reset_cpu_accounting(Unit *unit, CGroupRuntime *crt) {
int r;
- assert(u);
-
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return 0;
+ assert(crt);
+ crt->cpu_usage_base = 0;
crt->cpu_usage_last = NSEC_INFINITY;
- r = unit_get_cpu_usage_raw(u, &crt->cpu_usage_base);
- if (r < 0) {
- crt->cpu_usage_base = 0;
- return r;
+ if (unit) {
+ r = unit_get_cpu_usage_raw(unit, crt, &crt->cpu_usage_base);
+ if (r < 0 && r != -ENODATA)
+ return r;
}
return 0;
}
-void unit_reset_memory_accounting_last(Unit *u) {
- assert(u);
+static int unit_reset_io_accounting(Unit *unit, CGroupRuntime *crt) {
+ int r;
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return;
+ assert(crt);
+
+ zero(crt->io_accounting_base);
+ FOREACH_ELEMENT(i, crt->io_accounting_last)
+ *i = UINT64_MAX;
+
+ if (unit) {
+ r = unit_get_io_accounting_raw(unit, crt, crt->io_accounting_base);
+ if (r < 0 && r != -ENODATA)
+ return r;
+ }
+
+ return 0;
+}
+
+static void cgroup_runtime_reset_memory_accounting_last(CGroupRuntime *crt) {
+ assert(crt);
FOREACH_ELEMENT(i, crt->memory_accounting_last)
*i = UINT64_MAX;
}
-int unit_reset_ip_accounting(Unit *u) {
+static int cgroup_runtime_reset_ip_accounting(CGroupRuntime *crt) {
int r = 0;
- assert(u);
-
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return 0;
+ assert(crt);
if (crt->ip_accounting_ingress_map_fd >= 0)
RET_GATHER(r, bpf_firewall_reset_accounting(crt->ip_accounting_ingress_map_fd));
return r;
}
-void unit_reset_io_accounting_last(Unit *u) {
- assert(u);
-
- CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
- return;
-
- FOREACH_ARRAY(i, crt->io_accounting_last, _CGROUP_IO_ACCOUNTING_METRIC_MAX)
- *i = UINT64_MAX;
-}
-
-int unit_reset_io_accounting(Unit *u) {
- int r;
+int unit_reset_accounting(Unit *u) {
+ int r = 0;
assert(u);
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
- if (!crt || !crt->cgroup_path)
+ if (!crt)
return 0;
- unit_reset_io_accounting_last(u);
-
- r = unit_get_io_accounting_raw(u, crt->io_accounting_base);
- if (r < 0) {
- zero(crt->io_accounting_base);
- return r;
- }
-
- return 0;
-}
-
-int unit_reset_accounting(Unit *u) {
- int r = 0;
-
- assert(u);
-
- RET_GATHER(r, unit_reset_cpu_accounting(u));
- RET_GATHER(r, unit_reset_io_accounting(u));
- RET_GATHER(r, unit_reset_ip_accounting(u));
- unit_reset_memory_accounting_last(u);
+ cgroup_runtime_reset_memory_accounting_last(crt);
+ RET_GATHER(r, unit_reset_cpu_accounting(u, crt));
+ RET_GATHER(r, unit_reset_io_accounting(u, crt));
+ RET_GATHER(r, cgroup_runtime_reset_ip_accounting(crt));
return r;
}
return parse_cpu_set_full(v, cpus, false, NULL, NULL, 0, NULL);
}
-CGroupRuntime *cgroup_runtime_new(void) {
+CGroupRuntime* cgroup_runtime_new(void) {
_cleanup_(cgroup_runtime_freep) CGroupRuntime *crt = NULL;
crt = new(CGroupRuntime, 1);
return NULL;
*crt = (CGroupRuntime) {
- .cpu_usage_last = NSEC_INFINITY,
-
.cgroup_control_inotify_wd = -1,
.cgroup_memory_inotify_wd = -1,
.cgroup_invalidated_mask = _CGROUP_MASK_ALL,
};
- FOREACH_ELEMENT(i, crt->memory_accounting_last)
- *i = UINT64_MAX;
- FOREACH_ELEMENT(i, crt->io_accounting_base)
- *i = UINT64_MAX;
- FOREACH_ELEMENT(i, crt->io_accounting_last)
- *i = UINT64_MAX;
- FOREACH_ELEMENT(i, crt->ip_accounting_extra)
- *i = UINT64_MAX;
+ unit_reset_cpu_accounting(/* unit = */ NULL, crt);
+ unit_reset_io_accounting(/* unit = */ NULL, crt);
+ cgroup_runtime_reset_memory_accounting_last(crt);
+ assert_se(cgroup_runtime_reset_ip_accounting(crt) >= 0);
return TAKE_PTR(crt);
}
-CGroupRuntime *cgroup_runtime_free(CGroupRuntime *crt) {
+CGroupRuntime* cgroup_runtime_free(CGroupRuntime *crt) {
if (!crt)
return NULL;