diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-02-09 19:07:01 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-02-09 19:07:39 +0100 |
commit | cc6271f17d3c5c200e8a391f10d0afb71403fc28 (patch) | |
tree | 446b2b8ab60c11c3c9d65a7bc0a0474dee1b0f34 /src | |
parent | 1f73aa0021417c8ba70c78d16d6f68d3032db4ac (diff) | |
download | systemd-cc6271f17d3c5c200e8a391f10d0afb71403fc28.tar.gz |
core: turn on memory/cpu/tasks accounting by default for the root slice
The kernel exposes the necessary data in /proc anyway, let's expose it
hence by default.
With this in place "systemctl status -- -.slice" will show accounting
data out-of-the-box now.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/cgroup.c | 27 | ||||
-rw-r--r-- | src/core/cgroup.h | 1 | ||||
-rw-r--r-- | src/core/slice.c | 32 |
3 files changed, 48 insertions, 12 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 924285de82..0527996c28 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -37,19 +37,34 @@ #include "stdio-util.h" #include "string-table.h" #include "string-util.h" +#include "virt.h" #define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC) +bool manager_owns_root_cgroup(Manager *m) { + assert(m); + + /* Returns true if we are managing the root cgroup. Note that it isn't sufficient to just check whether the + * group root path equals "/" since that will also be the case if CLONE_NEWCGROUP is in the mix. Since there's + * appears to be no nice way to detect whether we are in a CLONE_NEWCGROUP namespace we instead just check if + * we run in any kind of container virtualization. */ + + if (detect_container() > 0) + return false; + + return isempty(m->cgroup_root) || path_equal(m->cgroup_root, "/"); +} + bool unit_has_root_cgroup(Unit *u) { assert(u); - /* Returns whether this unit manages the root cgroup. Note that this is different from being named "-.slice", - * as inside of containers the root slice won't be identical to the root cgroup. */ + /* Returns whether this unit manages the root cgroup. This will return true if this unit is the root slice and + * the manager manages the root cgroup. */ - if (!u->cgroup_path) + if (!manager_owns_root_cgroup(u->manager)) return false; - return isempty(u->cgroup_path) || path_equal(u->cgroup_path, "/"); + return unit_has_name(u, SPECIAL_ROOT_SLICE); } static void cgroup_compat_warn(void) { @@ -58,7 +73,9 @@ static void cgroup_compat_warn(void) { if (cgroup_compat_warned) return; - log_warning("cgroup compatibility translation between legacy and unified hierarchy settings activated. See cgroup-compat debug messages for details."); + log_warning("cgroup compatibility translation between legacy and unified hierarchy settings activated. " + "See cgroup-compat debug messages for details."); + cgroup_compat_warned = true; } diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 1f50441412..bc8a6951c9 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -208,6 +208,7 @@ int unit_reset_ip_accounting(Unit *u); cc ? cc->name : false; \ }) +bool manager_owns_root_cgroup(Manager *m); bool unit_has_root_cgroup(Unit *u); int manager_notify_cgroup_empty(Manager *m, const char *group); diff --git a/src/core/slice.c b/src/core/slice.c index ef2177279a..9cb828cae1 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -313,19 +313,18 @@ _pure_ static const char *slice_sub_state_to_string(Unit *u) { return slice_state_to_string(SLICE(u)->state); } -static void slice_enumerate_perpetual(Manager *m, const char *name) { +static int slice_make_perpetual(Manager *m, const char *name, Unit **ret) { Unit *u; int r; assert(m); + assert(name); u = manager_get_unit(m, name); if (!u) { r = unit_new_for_name(m, sizeof(Slice), name, &u); - if (r < 0) { - log_error_errno(r, "Failed to allocate the special %s unit: %m", name); - return; - } + if (r < 0) + return log_error_errno(r, "Failed to allocate the special %s unit: %m", name); } u->perpetual = true; @@ -333,15 +332,34 @@ static void slice_enumerate_perpetual(Manager *m, const char *name) { unit_add_to_load_queue(u); unit_add_to_dbus_queue(u); + + if (ret) + *ret = u; + + return 0; } static void slice_enumerate(Manager *m) { + Unit *u; + int r; + assert(m); - slice_enumerate_perpetual(m, SPECIAL_ROOT_SLICE); + r = slice_make_perpetual(m, SPECIAL_ROOT_SLICE, &u); + if (r >= 0 && manager_owns_root_cgroup(m)) { + Slice *s = SLICE(u); + + /* If we are managing the root cgroup then this means our root slice covers the whole system, which + * means the kernel will track CPU/tasks/memory for us anyway, and it is all available in /proc. Let's + * hence turn accounting on here, so that our APIs to query this data are available. */ + + s->cgroup_context.cpu_accounting = true; + s->cgroup_context.tasks_accounting = true; + s->cgroup_context.memory_accounting = true; + } if (MANAGER_IS_SYSTEM(m)) - slice_enumerate_perpetual(m, SPECIAL_SYSTEM_SLICE); + (void) slice_make_perpetual(m, SPECIAL_SYSTEM_SLICE, NULL); } const UnitVTable slice_vtable = { |