summaryrefslogtreecommitdiff
path: root/src/cgtop
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-02-09 17:25:30 +0100
committerLennart Poettering <lennart@poettering.net>2018-02-09 17:31:55 +0100
commitba4b1544f2a69c6786295d437b2f970f5ed1f68f (patch)
treebe6678eab986a0a0b3f7d3663e5cefe2040acc8d /src/cgtop
parentad078b4181d4b62de4b841fcb39b5707542bd38e (diff)
downloadsystemd-ba4b1544f2a69c6786295d437b2f970f5ed1f68f.tar.gz
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.
Diffstat (limited to 'src/cgtop')
-rw-r--r--src/cgtop/cgtop.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index 4e406e4ad2..27e713fd93 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;