summaryrefslogtreecommitdiff
path: root/src/shared/cgroup-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-12-30 01:57:23 +0100
committerLennart Poettering <lennart@poettering.net>2015-01-05 01:40:51 +0100
commitb12afc8c5c5c3ee5720780df9a602288bbcc24ea (patch)
treec31283a2db47472b134744bf353c9953e089bd62 /src/shared/cgroup-util.c
parent714e2e1d56b97dcf2ebae2d0447b48f21e38a600 (diff)
nspawn: mount most of the cgroup tree read-only in nspawn containers except for the container's own subtree in the name=systemd hierarchy
More specifically mount all other hierarchies in their entirety and the name=systemd above the container's subtree read-only.
Diffstat (limited to 'src/shared/cgroup-util.c')
-rw-r--r--src/shared/cgroup-util.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c
index 1bcba01887..86729f14bf 100644
--- a/src/shared/cgroup-util.c
+++ b/src/shared/cgroup-util.c
@@ -502,14 +502,16 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
}
static int check_hierarchy(const char *p) {
- char *cc;
+ const char *cc;
assert(p);
+ if (!filename_is_valid(p))
+ return 0;
+
/* Check if this controller actually really exists */
- cc = alloca(strlen("/sys/fs/cgroup/") + strlen(p) + 1);
- strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
- if (access(cc, F_OK) < 0)
+ cc = strappenda("/sys/fs/cgroup/", p);
+ if (laccess(cc, F_OK) < 0)
return -errno;
return 0;
@@ -1732,3 +1734,54 @@ CGroupControllerMask cg_mask_supported(void) {
return mask;
}
+
+int cg_kernel_controllers(Set *controllers) {
+ _cleanup_fclose_ FILE *f = NULL;
+ char buf[LINE_MAX];
+ int r;
+
+ assert(controllers);
+
+ f = fopen("/proc/cgroups", "re");
+ if (!f) {
+ if (errno == ENOENT)
+ return 0;
+ return -errno;
+ }
+
+ /* Ignore the header line */
+ (void) fgets(buf, sizeof(buf), f);
+
+ for (;;) {
+ char *controller;
+ int enabled = 0;
+
+ errno = 0;
+ if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
+
+ if (feof(f))
+ break;
+
+ if (ferror(f) && errno)
+ return -errno;
+
+ return -EBADMSG;
+ }
+
+ if (!enabled) {
+ free(controller);
+ continue;
+ }
+
+ if (!filename_is_valid(controller)) {
+ free(controller);
+ return -EBADMSG;
+ }
+
+ r = set_consume(controllers, controller);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}