[CRIU] [PATCH 4/5] cgroups: add support for c/r of the devices cgroup

Tycho Andersen tycho.andersen at canonical.com
Mon Jun 6 08:20:16 PDT 2016


This one is a little big ugly, see comments for details. At some point we
should invent a better way to do these special cases, since we have them
for freezer, cpuset, and now devices. Perhaps something like fstype, where
you can ask the cgroup how to restore itself.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
CC: Cyrill Gorcunov <gorcunov at openvz.org>
---
 criu/cgroup-props.c |  6 ++++++
 criu/cgroup.c       | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/criu/cgroup-props.c b/criu/cgroup-props.c
index ec55e13..40946b4 100644
--- a/criu/cgroup-props.c
+++ b/criu/cgroup-props.c
@@ -480,6 +480,12 @@ static int cgp_parse_builtins(void)
 			" - \"properties\": "
 			"[ "
 				"\"pids.current\" "
+			"]\n"
+		"\"devices\":\n"
+			" - \"strategy\": \"replace\"\n"
+			" - \"properties\": "
+			"[ "
+				"\"devices.list\" "
 			"]\n";
 
 	return cgp_parse_stream((void *)predefined_stream,
diff --git a/criu/cgroup.c b/criu/cgroup.c
index 1746191..924830f 100644
--- a/criu/cgroup.c
+++ b/criu/cgroup.c
@@ -1253,6 +1253,46 @@ static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **e
 				if (special)
 					continue;
 
+				/* The devices cgroup must be restored in a
+				 * special way: only the contents of
+				 * devices.list can be read, and it is a
+				 * whitelist of all the devices the cgroup is
+				 * allowed to create. To re-creat this
+				 * whitelist, we first deny everything via
+				 * devices.deny, and then write the list back
+				 * into devices.allow.
+				 */
+				if (!strcmp(e->properties[j]->name, "devices.list")) {
+					CgroupPropEntry *pe = e->properties[j];
+					char *old_val = pe->value, *old_name = pe->name;
+					int ret;
+
+					/* A bit of a fudge here. These are
+					 * write only by owner by default, but
+					 * the container engine could have
+					 * changed the perms. We should come up
+					 * with a better way to restore all of
+					 * this stuff.
+					 */
+					pe->perms->mode = 0200;
+
+					pe->name = "devices.deny";
+					pe->value = "a";
+					ret = restore_cgroup_prop(e->properties[j], path, off2);
+					pe->name = old_name;
+					pe->name = old_val;
+
+					if (ret < 0)
+						return -1;
+
+					pe->name = xstrdup("devices.allow");
+					if (!pe->name) {
+						pe->name = old_name;
+						return -1;
+					}
+					xfree(old_name);
+				}
+
 				if (restore_cgroup_prop(e->properties[j], path, off2) < 0)
 					return -1;
 			}
-- 
2.7.4



More information about the CRIU mailing list