[lxc-devel] [lxcfs/master] cgroup_fuse: fix cgroupfs virtualization needed on non-cgns systems
brauner on Github
lxc-bot at linuxcontainers.org
Mon Mar 16 12:20:14 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 365 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200316/cfb4d3d1/attachment.bin>
-------------- next part --------------
From 1e6143f9f3a703a6bfe12be967ece81e83401b97 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at 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.brauner at 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.
More information about the lxc-devel
mailing list