[CRIU] [PATCH 1/2] cg: use one path style throughout cg restore code

Tycho Andersen tycho.andersen at canonical.com
Mon Oct 6 07:03:29 PDT 2014


This commit is in preparation for the (hopefully last :) restore special cpuset
patch.

Previously, we installed the cgroup service fd after calling
prepare_cgroup_dirs, which meant that we had to carry around the temporary
directory name in order to put things in the right place. The
restore_cgroup_prop function uses the cg service fd instead of carrying around
the full path. This means that we can't sue restore_cgroup_prop, without first
sanitizing the path. Instead, we install the service fd before calling
prepare_cgroup_dirs, and all the code just references that instead of carrying
around the temporary path.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 cgroup.c       | 44 ++++++++++++++++++++++++++------------------
 include/util.h |  2 +-
 util.c         |  4 ++--
 3 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/cgroup.c b/cgroup.c
index 29e373d..9fd739c 100644
--- a/cgroup.c
+++ b/cgroup.c
@@ -1153,10 +1153,12 @@ static int prepare_cgroup_dirs(char *paux, size_t off, CgroupDirEntry **ents, si
 {
 	size_t i;
 	CgroupDirEntry *e;
+	int cg = get_service_fd(CGROUP_YARD);
 
 	for (i = 0; i < n_ents; i++) {
 		size_t off2 = off;
 		e = ents[i];
+		struct stat st;
 
 		off2 += sprintf(paux + off, "/%s", e->dir_name);
 
@@ -1165,12 +1167,13 @@ static int prepare_cgroup_dirs(char *paux, size_t off, CgroupDirEntry **ents, si
 		 * it does exist, prevent us from overwriting the properties
 		 * later by removing the CgroupDirEntry's properties.
 		 */
-		if (access(paux, F_OK) < 0) {
+		if (fstatat(cg, paux, &st, 0) < 0) {
 			if (errno != ENOENT) {
 				pr_perror("Failed accessing file %s", paux);
 				return -1;
 			}
-			if (mkdirp(paux)) {
+
+			if (mkdirpat(cg, paux)) {
 				pr_perror("Can't make cgroup dir %s", paux);
 				return -1;
 			}
@@ -1211,7 +1214,7 @@ static int prepare_cgroup_dirs(char *paux, size_t off, CgroupDirEntry **ents, si
 
 static int prepare_cgroup_sfd(CgroupEntry *ce)
 {
-	int off, i;
+	int off, i, ret;
 	char paux[PATH_MAX];
 
 	pr_info("Preparing cgroups yard\n");
@@ -1238,11 +1241,24 @@ static int prepare_cgroup_sfd(CgroupEntry *ce)
 		goto err;
 	}
 
+	pr_debug("Opening %s as cg yard\n", cg_yard);
+	i = open(cg_yard, O_DIRECTORY);
+	if (i < 0) {
+		pr_perror("Can't open cgyard");
+		goto err;
+	}
+
+	ret = install_service_fd(CGROUP_YARD, i);
+	close(i);
+	if (ret < 0)
+		goto err;
+
+
 	paux[off++] = '/';
 
 	for (i = 0; i < ce->n_controllers; i++) {
-		int ctl_off = off;
-		char opt[128];
+		int ctl_off = off, yard_off;
+		char opt[128], *yard;
 		CgControllerEntry *ctrl = ce->controllers[i];
 
 		if (ctrl->n_cnames < 1) {
@@ -1265,24 +1281,16 @@ static int prepare_cgroup_sfd(CgroupEntry *ce)
 			goto err;
 		}
 
+		/* We skip over the .criu.cgyard.XXXXXX/, since those will be
+		 * referred to by the cg yard service fd. */
+		yard = paux + strlen(cg_yard) + 1;
+		yard_off = ctl_off - (strlen(cg_yard) + 1);
 		if (opts.manage_cgroups &&
-		    prepare_cgroup_dirs(paux, ctl_off, ctrl->dirs, ctrl->n_dirs))
+		    prepare_cgroup_dirs(yard, yard_off, ctrl->dirs, ctrl->n_dirs))
 			goto err;
 
 	}
 
-	pr_debug("Opening %s as cg yard\n", cg_yard);
-	i = open(cg_yard, O_DIRECTORY);
-	if (i < 0) {
-		pr_perror("Can't open cgyard");
-		goto err;
-	}
-
-	off = install_service_fd(CGROUP_YARD, i);
-	close(i);
-	if (off < 0)
-		goto err;
-
 	return 0;
 
 err:
diff --git a/include/util.h b/include/util.h
index 717aeee..0816029 100644
--- a/include/util.h
+++ b/include/util.h
@@ -212,7 +212,7 @@ static inline bool strstartswith(const char *str, const char *sub)
 /*
  * mkdir -p
  */
-int mkdirp(const char *path);
+int mkdirpat(int fd, const char *path);
 
 /*
  * Tests whether a path is a prefix of another path. This is different than
diff --git a/util.c b/util.c
index 8283730..dd76863 100644
--- a/util.c
+++ b/util.c
@@ -687,7 +687,7 @@ struct vma_area *alloc_vma_area(void)
 	return p;
 }
 
-int mkdirp(const char *path)
+int mkdirpat(int fd, const char *path)
 {
 	size_t i;
 	char made_path[PATH_MAX], *pos;
@@ -707,7 +707,7 @@ int mkdirp(const char *path)
 		pos = strchr(made_path + i, '/');
 		if (pos)
 			*pos = '\0';
-		if (mkdir(made_path, 0755) < 0 && errno != EEXIST) {
+		if (mkdirat(fd, made_path, 0755) < 0 && errno != EEXIST) {
 			pr_perror("couldn't mkdirpat directory %s", made_path);
 			return -1;
 		}
-- 
1.9.1



More information about the CRIU mailing list