From: Christian Brauner Date: Tue, 31 Oct 2017 16:07:57 +0000 (+0100) Subject: cgroupfs/cgfsng: improve cgroup2 handling X-Git-Tag: lxc-2.0.10~588 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a5c220e1d9af41a5e39eff8956b466207ac1d99;p=thirdparty%2Flxc.git cgroupfs/cgfsng: improve cgroup2 handling This fixes a bunch of bugs. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 472e0766b..77df4c3d1 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -210,6 +210,8 @@ static void must_append_controller(char **klist, char **nlist, char ***clist, ch copy = must_copy_string(entry); else if (string_in_list(klist, entry)) copy = must_copy_string(entry); + else if (!strcmp(entry, "cgroup2")) + copy = must_copy_string(entry); else copy = must_prefix_named(entry); @@ -740,18 +742,14 @@ static bool all_controllers_found(void) * options. But we simply assume that the mountpoint must be * /sys/fs/cgroup/controller-list */ -static char **get_controllers(char **klist, char **nlist, char *line) +static char **get_controllers(char **klist, char **nlist, char *line, int type) { /* the fourth field is /sys/fs/cgroup/comma-delimited-controller-list */ int i; char *dup, *p2, *tok; - bool is_cgroup_v2; char *p = line, *saveptr = NULL; char **aret = NULL; - /* handle cgroup v2 */ - is_cgroup_v2 = is_cgroupfs_v2(line); - for (i = 0; i < 4; i++) { p = strchr(p, ' '); if (!p) @@ -775,7 +773,7 @@ static char **get_controllers(char **klist, char **nlist, char *line) *p2 = '\0'; /* cgroup v2 does not have separate mountpoints for controllers */ - if (is_cgroup_v2) { + if (type == CGROUP_V2) { must_append_controller(klist, nlist, &aret, "cgroup2"); return aret; } @@ -1070,13 +1068,14 @@ static bool parse_hierarchies(void) while (getline(&line, &len, f) != -1) { char **controller_list = NULL; char *mountpoint, *base_cgroup; - bool is_cgroup_v2, writeable; + bool writeable; + int type; - is_cgroup_v2 = is_cgroupfs_v2(line); - if (!is_cgroupfs_v1(line) && !is_cgroup_v2) + type = get_cgroup_version(line); + if (type < 0) continue; - controller_list = get_controllers(klist, nlist, line); + controller_list = get_controllers(klist, nlist, line, type); if (!controller_list) continue; @@ -1102,7 +1101,7 @@ static bool parse_hierarchies(void) trim(base_cgroup); prune_init_scope(base_cgroup); - if (is_cgroup_v2) + if (type == CGROUP_V2) writeable = test_writeable_v2(mountpoint, base_cgroup); else writeable = test_writeable_v1(mountpoint, base_cgroup); diff --git a/src/lxc/cgroups/cgroup_utils.c b/src/lxc/cgroups/cgroup_utils.c index c09ba1688..6dda1a617 100644 --- a/src/lxc/cgroups/cgroup_utils.c +++ b/src/lxc/cgroups/cgroup_utils.c @@ -32,6 +32,17 @@ #include "cgroup_utils.h" #include "utils.h" +int get_cgroup_version(char *line) +{ + if (is_cgroupfs_v1(line)) + return CGROUP_V1; + + if (is_cgroupfs_v2(line)) + return CGROUP_V2; + + return -1; +} + bool is_cgroupfs_v1(char *line) { char *p = strstr(line, " - "); @@ -67,20 +78,39 @@ bool test_writeable_v2(char *mountpoint, char *path) * file. */ int ret; - char *cgroup_path, *cgroup_procs_file; + char *cgroup_path, *cgroup_procs_file, *cgroup_threads_file; cgroup_path = must_make_path(mountpoint, path, NULL); cgroup_procs_file = must_make_path(cgroup_path, "cgroup.procs", NULL); ret = access(cgroup_path, W_OK); - free(cgroup_path); if (ret < 0) { + free(cgroup_path); free(cgroup_procs_file); return false; } ret = access(cgroup_procs_file, W_OK); free(cgroup_procs_file); + if (ret < 0) { + free(cgroup_path); + return false; + } + + /* Newer versions of cgroup2 now also require write access to the + * "cgroup.threads" file. + */ + cgroup_threads_file = must_make_path(cgroup_path, "cgroup.threads", NULL); + free(cgroup_path); + if (!file_exists(cgroup_threads_file)) { + free(cgroup_threads_file); + return true; + } + + ret = access(cgroup_threads_file, W_OK); + free(cgroup_threads_file); + if (ret < 0) + return false; return ret == 0; } diff --git a/src/lxc/cgroups/cgroup_utils.h b/src/lxc/cgroups/cgroup_utils.h index 49aae8567..e9e4448a6 100644 --- a/src/lxc/cgroups/cgroup_utils.h +++ b/src/lxc/cgroups/cgroup_utils.h @@ -28,6 +28,13 @@ #include #include +#define CGROUP_V1 0 +#define CGROUP_V2 1 +#define LXCFS_CGROUP 2 + +/* Retrieve the cgroup version of a given entry from /proc//mountinfo. */ +extern int get_cgroup_version(char *line); + /* Check if given entry from /proc//mountinfo is a cgroupfs v1 mount. */ extern bool is_cgroupfs_v1(char *line);