[lxc-devel] [lxc/master] cgfs: various fixes

brauner on Github lxc-bot at linuxcontainers.org
Sun Oct 30 14:15:03 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1287 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161030/311d4a96/attachment.bin>
-------------- next part --------------
From 1a704014eeedf1c52135e520962fcff94fdf67c3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at canonical.com>
Date: Sun, 30 Oct 2016 10:45:13 +0100
Subject: [PATCH 1/3] cgfs: add print_cgfs_init_debuginfo()

Signed-off-by: Christian Brauner <christian.brauner at canonical.com>
---
 src/lxc/cgroups/cgfs.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c
index 26cccad..c10253b 100644
--- a/src/lxc/cgroups/cgfs.c
+++ b/src/lxc/cgroups/cgfs.c
@@ -2270,6 +2270,33 @@ static bool init_cpuset_if_needed(struct cgroup_mount_point *mp,
 		do_init_cpuset_file(mp, path, "/cpuset.mems") );
 }
 
+static void print_cgfs_init_debuginfo(struct cgfs_data *d)
+{
+	int i;
+
+	if (!getenv("LXC_DEBUG_CGFS"))
+		return;
+
+	DEBUG("Cgroup information:");
+	DEBUG("  container name: %s", d->name);
+	if (!d->meta || !d->meta->hierarchies) {
+		DEBUG("  No hierarchies found.");
+		return;
+	}
+	DEBUG("  Controllers:");
+	for (i = 0; i <= d->meta->maximum_hierarchy; i++) {
+		char **p;
+		struct cgroup_hierarchy *h = d->meta->hierarchies[i];
+		if (!h) {
+			DEBUG("     Empty hierarchy number %d.", i);
+			continue;
+		}
+		for (p = h->subsystems; p && *p; p++) {
+			DEBUG("     %2d: %s", i, *p);
+		}
+	}
+}
+
 struct cgroup_ops *cgfs_ops_init(void)
 {
 	return &cgfs_ops;
@@ -2295,6 +2322,9 @@ static void *cgfs_init(const char *name)
 		ERROR("cgroupfs failed to detect cgroup metadata");
 		goto err2;
 	}
+
+	print_cgfs_init_debuginfo(d);
+
 	return d;
 
 err2:

From 82a2fe03a61febcc1b2300550a70ac698cb1fd11 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at canonical.com>
Date: Sun, 30 Oct 2016 13:42:37 +0100
Subject: [PATCH 2/3] cgfs: skip empty entries under /proc/self/cgroup

If cgroupv2 is enabled either alone or together with legacy hierarchies
/proc/self/cgroup can contain entries of the form:

        0::/

These entries need to be skipped.

Signed-off-by: Christian Brauner <christian.brauner at canonical.com>
---
 src/lxc/cgroups/cgfs.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c
index c10253b..a30ad91 100644
--- a/src/lxc/cgroups/cgfs.c
+++ b/src/lxc/cgroups/cgfs.c
@@ -364,6 +364,14 @@ static bool find_cgroup_hierarchies(struct cgroup_meta_data *meta_data,
 		*colon2 = '\0';
 
 		colon2 = NULL;
+
+		/* With cgroupv2 /proc/self/cgroup can contain entries of the
+		 * form: 0::/
+		 * These entries need to be skipped.
+		 */
+		if (!strcmp(colon1, ""))
+			continue;
+
 		hierarchy_number = strtoul(line, &colon2, 10);
 		if (!colon2 || *colon2)
 			continue;
@@ -1685,6 +1693,14 @@ lxc_cgroup_process_info_getx(const char *proc_pid_cgroup_str,
 		*colon2++ = '\0';
 
 		endptr = NULL;
+
+		/* With cgroupv2 /proc/self/cgroup can contain entries of the
+		 * form: 0::/
+		 * These entries need to be skipped.
+		 */
+		if (!strcmp(colon1, ""))
+			continue;
+
 		hierarchy_number = strtoul(line, &endptr, 10);
 		if (!endptr || *endptr)
 			continue;

From e138cc68b3a3ba2fdb72d633bc2cfd004de15008 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at canonical.com>
Date: Sun, 30 Oct 2016 14:44:33 +0100
Subject: [PATCH 3/3] cgfs: start counter for cgroups hierarchies at 1

Somehow this implementation of a cgroupfs backend decided to use the hierarchy
numbers it detects in /proc/cgroups and /proc/self/cgroups as indices for
the hierarchy struct. Controller numbering usually starts at 1 but may start at
0 if:

    a) the controller is not mounted on a cgroups v1 hierarchy;
    b) the controller is bound to the cgroups v2 single unified hierarchy; or
    c) the controller is disabled

To avoid having to rework our fallback backend significantly, we should
explicitly check for each controller if hierarchy[i] != NULL.

Signed-off-by: Christian Brauner <christian.brauner at canonical.com>
---
 src/lxc/cgroups/cgfs.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c
index a30ad91..8499200 100644
--- a/src/lxc/cgroups/cgfs.c
+++ b/src/lxc/cgroups/cgfs.c
@@ -512,7 +512,7 @@ static bool find_hierarchy_mountpts( struct cgroup_meta_data *meta_data, char **
 			goto out;
 
 		h = NULL;
-		for (k = 1; k <= meta_data->maximum_hierarchy; k++) {
+		for (k = 0; k <= meta_data->maximum_hierarchy; k++) {
 			if (meta_data->hierarchies[k] &&
 			    meta_data->hierarchies[k]->subsystems[0] &&
 			    lxc_string_in_array(meta_data->hierarchies[k]->subsystems[0], (const char **)subsystems)) {
@@ -654,6 +654,8 @@ static struct cgroup_hierarchy *lxc_cgroup_find_hierarchy(struct cgroup_meta_dat
 	size_t i;
 	for (i = 0; i <= meta_data->maximum_hierarchy; i++) {
 		struct cgroup_hierarchy *h = meta_data->hierarchies[i];
+		if (!h)
+			continue;
 		if (h && lxc_string_in_array(subsystem, (const char **)h->subsystems))
 			return h;
 	}
@@ -892,6 +894,8 @@ static struct cgroup_process_info *lxc_cgroupfs_create(const char *name, const c
 	/* find mount points we can use */
 	for (info_ptr = base_info; info_ptr; info_ptr = info_ptr->next) {
 		h = info_ptr->hierarchy;
+		if (!h)
+			continue;
 		mp = lxc_cgroup_find_mount_point(h, info_ptr->cgroup_path, true);
 		if (!mp) {
 			ERROR("Could not find writable mount point for cgroup hierarchy %d while trying to create cgroup.", h->index);
@@ -981,6 +985,9 @@ static struct cgroup_process_info *lxc_cgroupfs_create(const char *name, const c
 		for (i = 0, info_ptr = base_info; info_ptr; info_ptr = info_ptr->next, i++) {
 			char *parts2[3];
 
+			if (!info_ptr->hierarchy)
+				continue;
+
 			if (lxc_string_in_array("ns", (const char **)info_ptr->hierarchy->subsystems))
 				continue;
 			current_entire_path = NULL;
@@ -1079,6 +1086,8 @@ static struct cgroup_process_info *lxc_cgroupfs_create(const char *name, const c
 
 	/* we're done, now update the paths */
 	for (i = 0, info_ptr = base_info; info_ptr; info_ptr = info_ptr->next, i++) {
+		if (!info_ptr->hierarchy)
+			continue;
 		/* ignore legacy 'ns' subsystem here, lxc_cgroup_create_legacy
 		 * will take care of it
 		 * Since we do a continue in above loop, new_cgroup_paths[i] is
@@ -1116,6 +1125,9 @@ static int lxc_cgroup_create_legacy(struct cgroup_process_info *base_info, const
 	int r;
 
 	for (info_ptr = base_info; info_ptr; info_ptr = info_ptr->next) {
+		if (!info_ptr->hierarchy)
+			continue;
+
 		if (!lxc_string_in_array("ns", (const char **)info_ptr->hierarchy->subsystems))
 			continue;
 		/*
@@ -1200,6 +1212,9 @@ static int lxc_cgroupfs_enter(struct cgroup_process_info *info, pid_t pid, bool
 
 	snprintf(pid_buf, 32, "%lu", (unsigned long)pid);
 	for (info_ptr = info; info_ptr; info_ptr = info_ptr->next) {
+		if (!info_ptr->hierarchy)
+			continue;
+
 		char *cgroup_path = (enter_sub && info_ptr->cgroup_path_sub) ?
 			info_ptr->cgroup_path_sub :
 			info_ptr->cgroup_path;
@@ -1444,6 +1459,10 @@ static bool cgroupfs_mount_cgroup(void *hdata, const char *root, int type)
 	for (info = base_info; info; info = info->next) {
 		size_t subsystem_count, i;
 		struct cgroup_mount_point *mp = info->designated_mount_point;
+
+		if (!info->hierarchy)
+			continue;
+
 		if (!mountpoint_is_accessible(mp))
 			mp = lxc_cgroup_find_mount_point(info->hierarchy, info->cgroup_path, true);
 
@@ -1930,6 +1949,8 @@ find_info_for_subsystem(struct cgroup_process_info *info, const char *subsystem)
 	struct cgroup_process_info *info_ptr;
 	for (info_ptr = info; info_ptr; info_ptr = info_ptr->next) {
 		struct cgroup_hierarchy *h = info_ptr->hierarchy;
+		if (!h)
+			continue;
 		if (lxc_string_in_array(subsystem, (const char **)h->subsystems))
 			return info_ptr;
 	}
@@ -2426,7 +2447,7 @@ static bool cgfs_escape(void *hdata)
 	if (!md)
 		return false;
 
-	for (i = 1; i <= md->maximum_hierarchy; i++) {
+	for (i = 0; i <= md->maximum_hierarchy; i++) {
 		struct cgroup_hierarchy *h = md->hierarchies[i];
 		struct cgroup_mount_point *mp;
 		char *tasks;
@@ -2636,6 +2657,9 @@ static bool cgfs_chown(void *hdata, struct lxc_conf *conf)
 		return false;
 
 	for (info_ptr = d->info; info_ptr; info_ptr = info_ptr->next) {
+		if (!info_ptr->hierarchy)
+			continue;
+
 		if (!info_ptr->designated_mount_point) {
 			info_ptr->designated_mount_point = lxc_cgroup_find_mount_point(info_ptr->hierarchy, info_ptr->cgroup_path, true);
 			if (!info_ptr->designated_mount_point) {


More information about the lxc-devel mailing list