summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-02-09 19:07:01 +0100
committerLennart Poettering <lennart@poettering.net>2018-02-09 19:07:39 +0100
commitcc6271f17d3c5c200e8a391f10d0afb71403fc28 (patch)
tree446b2b8ab60c11c3c9d65a7bc0a0474dee1b0f34 /src
parent1f73aa0021417c8ba70c78d16d6f68d3032db4ac (diff)
downloadsystemd-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.c27
-rw-r--r--src/core/cgroup.h1
-rw-r--r--src/core/slice.c32
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 = {