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