The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/372

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From 1e6143f9f3a703a6bfe12be967ece81e83401b97 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Mon, 16 Mar 2020 13:18:57 +0100
Subject: [PATCH] cgroup_fuse: fix cgroupfs virtualization needed on non-cgns
 systems

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 src/cgroup_fuse.c    | 52 +++++++++++++++++++++++++++++++++-----------
 src/cgroups/cgfsng.c |  4 ++--
 src/cgroups/cgroup.h |  1 +
 src/lxcfs.c          | 25 +++++++++++++++++----
 src/macro.h          |  1 +
 5 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/src/cgroup_fuse.c b/src/cgroup_fuse.c
index 2130d7a..2e4aa2c 100644
--- a/src/cgroup_fuse.c
+++ b/src/cgroup_fuse.c
@@ -60,6 +60,32 @@ struct pid_ns_clone_args {
        int (*wrapped) (int, pid_t);
 };
 
+static inline int get_cgroup_fd_handle_named(const char *controller)
+{
+       if (strcmp(controller, "systemd") == 0)
+               return get_cgroup_fd("name=systemd");
+
+       return get_cgroup_fd(controller);
+}
+
+static char *get_pid_cgroup_handle_named(pid_t pid, const char *controller)
+{
+       if (strcmp(controller, "systemd") == 0)
+               return get_pid_cgroup(pid, "name=systemd");
+
+       return get_pid_cgroup(pid, controller);
+}
+
+static bool get_cgroup_handle_named(struct cgroup_ops *ops,
+                                   const char *controller, const char *cgroup,
+                                   const char *file, char **value)
+{
+       if (strcmp(controller, "systemd") == 0)
+               return cgroup_ops->get(ops, "name=systemd", cgroup, file, 
value);
+
+       return cgroup_ops->get(cgroup_ops, controller, cgroup, file, value);
+}
+
 /*
  * given /cgroup/freezer/a/b, return "freezer".
  * the returned char* should NOT be freed.
@@ -144,7 +170,7 @@ static bool is_child_cgroup(const char *controller, const 
char *cgroup, const ch
        int ret;
        struct stat sb;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return false;
 
@@ -176,7 +202,7 @@ static bool caller_may_see_dir(pid_t pid, const char 
*contrl, const char *cg)
        if (strcmp(cg, "/") == 0 || strcmp(cg, "./") == 0)
                return true;
 
-       c2 = get_pid_cgroup(pid, contrl);
+       c2 = get_pid_cgroup_handle_named(pid, contrl);
        if (!c2)
                return false;
        prune_init_slice(c2);
@@ -251,7 +277,7 @@ static char *get_next_cgroup_dir(const char *taskcg, const 
char *querycg)
 static bool caller_is_in_ancestor(pid_t pid, const char *contrl, const char 
*cg, char **nextcg)
 {
        bool answer = false;
-       char *c2 = get_pid_cgroup(pid, contrl);
+       char *c2 = get_pid_cgroup_handle_named(pid, contrl);
        char *linecmp;
 
        if (!c2)
@@ -293,7 +319,7 @@ static struct cgfs_files *cgfs_get_key(const char 
*controller,
        struct stat sb;
        struct cgfs_files *newkey;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return false;
 
@@ -659,7 +685,7 @@ static int cgfs_create(const char *controller, const char 
*cg, uid_t uid, gid_t
        size_t len;
        char *dirnam;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return -EINVAL;
 
@@ -807,7 +833,7 @@ static bool cgfs_remove(const char *controller, const char 
*cg)
        char *dirnam;
        bool bret;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return false;
 
@@ -897,7 +923,7 @@ static bool cgfs_chmod_file(const char *controller, const 
char *file, mode_t mod
        size_t len;
        char *pathname;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return false;
 
@@ -1016,7 +1042,7 @@ static int cgfs_chown_file(const char *controller, const 
char *file, uid_t uid,
        size_t len;
        char *pathname;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return false;
 
@@ -1299,7 +1325,7 @@ static bool do_read_pids(pid_t tpid, const char *contrl, 
const char *cg,
        struct ucred cred;
        size_t sz = 0, asz = 0;
 
-       if (!cgroup_ops->get(cgroup_ops, contrl, cg, file, &tmpdata))
+       if (!get_cgroup_handle_named(cgroup_ops, contrl, cg, file, &tmpdata))
                return false;
 
        /*
@@ -1416,7 +1442,7 @@ __lxcfs_fuse_ops int cg_read(const char *path, char *buf, 
size_t size,
                // special case - we have to translate the pids
                r = do_read_pids(fc->pid, f->controller, f->cgroup, f->file, 
&data);
        else
-               r = cgroup_ops->get(cgroup_ops, f->controller, f->cgroup, 
f->file, &data);
+               r = get_cgroup_handle_named(cgroup_ops, f->controller, 
f->cgroup, f->file, &data);
 
        if (!r) {
                ret = -EINVAL;
@@ -1513,7 +1539,7 @@ static FILE *open_pids_file(const char *controller, const 
char *cgroup)
        size_t len;
        char *pathname;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return false;
 
@@ -1808,7 +1834,7 @@ static bool cgfs_set_value(const char *controller, const 
char *cgroup,
        size_t len;
        char *fnam;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        if (cfd < 0)
                return false;
 
@@ -1894,7 +1920,7 @@ static bool cgfs_iterate_cgroup(const char *controller, 
const char *cgroup,
        struct dirent *dirent;
        DIR *dir;
 
-       cfd = get_cgroup_fd(controller);
+       cfd = get_cgroup_fd_handle_named(controller);
        *list = NULL;
        if (cfd < 0)
                return false;
diff --git a/src/cgroups/cgfsng.c b/src/cgroups/cgfsng.c
index 98d8ca6..aba457b 100644
--- a/src/cgroups/cgfsng.c
+++ b/src/cgroups/cgfsng.c
@@ -500,7 +500,7 @@ static bool cgfsng_mount(struct cgroup_ops *ops, const char 
*root)
                                        "Error creating cgroup path: %s",
                                        controllerpath);
 
-               ret = cg_mount_cgroup_full( h, controllerpath);
+               ret = cg_mount_cgroup_full(h, controllerpath);
                if (ret < 0)
                        goto on_error;
        }
@@ -971,7 +971,7 @@ struct cgroup_ops *cgfsng_ops_init(void)
        cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies;
        cgfsng_ops->get = cgfsng_get;
        cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies;
-       cgfsng_ops->get_hierarchy = get_hierarchy;
+       cgfsng_ops->get_hierarchy = cgfsng_get_hierarchy;
        cgfsng_ops->driver = "cgfsng";
        cgfsng_ops->version = "1.0.0";
        cgfsng_ops->mount = cgfsng_mount;
diff --git a/src/cgroups/cgroup.h b/src/cgroups/cgroup.h
index dfcee0e..84049c7 100644
--- a/src/cgroups/cgroup.h
+++ b/src/cgroups/cgroup.h
@@ -17,6 +17,7 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <sys/types.h>
+#include <unistd.h>
 
 #include "../config.h"
 #include "../macro.h"
diff --git a/src/lxcfs.c b/src/lxcfs.c
index 44e7956..161907f 100644
--- a/src/lxcfs.c
+++ b/src/lxcfs.c
@@ -1058,9 +1058,16 @@ static int set_pidfile(char *pidfile)
        return move_fd(fd);
 }
 
+static inline bool cgns_supported(void)
+{
+       return access("/proc/self/ns/cgroup", F_OK);
+}
+
 int main(int argc, char *argv[])
 {
        __do_close_prot_errno int pidfile_fd = -EBADF;
+       char __default_opts[] = 
"default_permissions,allow_other,direct_io,entry_timeout=0.5,attr_timeout=0.5,nonempty";
+       char *default_opts = __default_opts;
        int ret = EXIT_FAILURE;
        char *pidfile = NULL, *saveptr = NULL, *token = NULL, *v = NULL;
        char pidfile_buf[STRLITERALLEN(RUNTIME_PATH) + 
STRLITERALLEN("/lxcfs.pid") + 1] = {};
@@ -1159,10 +1166,20 @@ int main(int argc, char *argv[])
        else
                newargv[cnt++] = "-f";
        newargv[cnt++] = "-o";
-       if (nonempty)
-               newargv[cnt++] = 
"default_permissions,allow_other,direct_io,entry_timeout=0.5,attr_timeout=0.5,nonempty";
-       else
-               newargv[cnt++] = 
"default_permissions,allow_other,direct_io,entry_timeout=0.5,attr_timeout=0.5";
+
+       if (!nonempty)
+               default_opts[STRARRAYLEN(__default_opts) - 
STRLITERALLEN("nonempty,")] = '\0';
+
+       /*
+        * If cgroup namespaces are not supported lxcfs will need to supply
+        * cgroup virtualization support. In this case we need custom access
+        * permission checking and can't rely on fuse.
+        */
+       if (!cgns_supported())
+               default_opts += STRLITERALLEN("default_permissions,");
+
+       newargv[cnt++] = default_opts;
+
        newargv[cnt++] = argv[1];
        newargv[cnt++] = NULL;
 
diff --git a/src/macro.h b/src/macro.h
index 29b5ed7..5d82509 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -67,6 +67,7 @@
        })
 
 #define STRLITERALLEN(x) (sizeof(""x"") - 1)
+#define STRARRAYLEN(x) (sizeof(x) - 1)
 
 /* Calculate the number of chars needed to represent a given integer as a C
  * string. Include room for '-' to indicate negative numbers and the \0 byte.
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to