From ba4b1544f2a69c6786295d437b2f970f5ed1f68f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 9 Feb 2018 17:25:30 +0100 Subject: [PATCH] cgtop: tweak root cgroup detection a bit Inside a cgroup-namespaced container we shouldn't assume that "/" is really the root cgroup, because it generally is not. --- src/cgtop/cgtop.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index 4e406e4ad25..27e713fd931 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -46,6 +46,7 @@ #include "terminal-util.h" #include "unit-name.h" #include "util.h" +#include "virt.h" typedef struct Group { char *path; @@ -126,6 +127,26 @@ static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, uint64 } static bool is_root_cgroup(const char *path) { + + /* Returns true if the specified path belongs to the root cgroup. The root cgroup is special on cgroupsv2 as it + * carries only very few attributes in order not to export multiple truth about system state as most + * information is available elsewhere in /proc anyway. We need to be able to deal with that, and need to get + * our data from different sources in that case. + * + * There's one extra complication in all of this, though 😣: if the path to the cgroup indicates we are in the + * root cgroup this might actually not be the case, because cgroup namespacing might be in effect + * (CLONE_NEWCGROUP). Since there's no nice way to distuingish a real cgroup root from a fake namespaced one we + * do an explicit container check here, under the assumption that CLONE_NEWCGROUP is generally used when + * container managers are used too. + * + * Note that checking for a container environment is kinda ugly, since in theory people could use cgtop from + * inside a container where cgroup namespacing is turned off to watch the host system. However, that's mostly a + * theoretic usecase, and if people actually try all they'll lose is accounting for the top-level cgroup. Which + * isn't too bad. */ + + if (detect_container() > 0) + return false; + return isempty(path) || path_equal(path, "/"); } @@ -176,7 +197,8 @@ static int process( } } - if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES)) { + if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && + IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES)) { _cleanup_fclose_ FILE *f = NULL; pid_t pid; -- 2.47.3