[CRIU] [PATCH 2/2] image: Open images via openat

Pavel Emelyanov xemul at parallels.com
Fri Mar 16 09:24:20 EDT 2012


Using absolute paths for this is dangerous - while doing c/r we should
be extremely carefully and not change tasks' roots and mount namespaces
too early. Sometimes it will not work -- when restoring containers we'll
be unable to switch to new CT and still have the ability to open images.

Rework the images opening via openat and keep the image dir fd open all
the time as the service fd (introduced earlier).

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>

---
-------------- next part --------------
diff --git a/cr-restore.c b/cr-restore.c
index e1692f0..be616e4 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -716,10 +716,9 @@ static int prepare_and_sigreturn(int pid)
 		goto out;
 	}
 
-	if (get_image_path(path, sizeof(path), FMT_FNAME_CORE_OUT, pid))
-		goto out;
-
-	fd_new = open(path, O_RDWR | O_CREAT | O_TRUNC, CR_FD_PERM);
+	sprintf(path, FMT_FNAME_CORE_OUT, pid);
+	fd_new = openat(image_dir_fd, path,
+			O_RDWR | O_CREAT | O_TRUNC, CR_FD_PERM);
 	if (fd_new < 0) {
 		pr_perror("%d: Can't open new image", pid);
 		goto out;
@@ -1842,6 +1841,8 @@ static void sigreturn_restore(pid_t pid)
 
 	}
 
+	close_image_dir();
+
 	pr_info("task_args: %p\n"
 		"task_args->pid: %d\n"
 		"task_args->fd_core: %d\n"
diff --git a/crtools.c b/crtools.c
index 469a7b3..d5a7e09 100644
--- a/crtools.c
+++ b/crtools.c
@@ -23,7 +23,6 @@
 
 static struct cr_options opts;
 struct page_entry zero_page_entry;
-char image_dir[PATH_MAX];
 
 /*
  * The cr fd set is the set of files where the information
@@ -205,20 +204,17 @@ static struct cr_fdset *cr_fdset_open(int pid, unsigned long use_mask,
 		if (fdset->fds[i] != -1)
 			continue;
 
-		ret = get_image_path(path, sizeof(path),
-				fdset_template[i].fmt, pid);
-		if (ret)
-			goto err;
+		sprintf(path, fdset_template[i].fmt, pid);
 
 		if (flags & O_EXCL) {
-			ret = unlink(path);
+			ret = unlinkat(image_dir_fd, path, 0);
 			if (ret && errno != ENOENT) {
 				pr_perror("Unable to unlink %s", path);
 				goto err;
 			}
 		}
 
-		ret = open(path, flags, CR_FD_PERM);
+		ret = openat(image_dir_fd, path, flags, CR_FD_PERM);
 		if (ret < 0) {
 			if (!(flags & O_CREAT))
 				/* caller should check himself */
@@ -381,8 +377,9 @@ int main(int argc, char *argv[])
 			return ret;
 	}
 
-	if (!getcwd(image_dir, sizeof(image_dir))) {
-		pr_perror("can't get currect directory");
+	ret = open_image_dir();
+	if (ret < 0) {
+		pr_perror("can't open currect directory");
 		return -1;
 	}
 
diff --git a/include/crtools.h b/include/crtools.h
index ee35cc7..ac8710d 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -84,9 +91,13 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
 #define FMT_FNAME_IPCNS_SEM	"ipcns-sem-%d.img"
 #define FMT_FNAME_SK_QUEUES	"sk-queues-%d.img"
 
-extern int get_image_path(char *path, int size, const char *fmt, int pid);
-
-extern char image_dir[];
+/*
+ * FIXME -- this is required for legacy image copy only.
+ * Don't use it for other reason and remove the former one.
+ */
+extern int image_dir_fd;
+extern int open_image_dir(void);
+extern void close_image_dir(void);
 extern int open_image_ro(int type, int pid);
 extern int open_image_ro_nocheck(const char *fmt, int pid);
 
diff --git a/util.c b/util.c
index 72c2c8f..729de54 100644
--- a/util.c
+++ b/util.c
@@ -148,28 +148,13 @@ int move_img_fd(int *img_fd, int want_fd)
 	return 0;
 }
 
-int get_image_path(char *path, int size, const char *fmt, int pid)
-{
-	int len;
-
-	len = snprintf(path, size, "%s/", image_dir);
-	len += snprintf(path + len, size - len, fmt, pid);
-	if (len > size) {
-		pr_err("Image path buffer overflow %d/%d\n", size, len);
-		return -1;
-	}
-
-	return 0;
-}
-
 int open_image_ro_nocheck(const char *fmt, int pid)
 {
 	char path[PATH_MAX];
 	int tmp;
 
-	tmp = get_image_path(path, sizeof(path), fmt, pid);
-	if (tmp == 0)
-		tmp = open(path, O_RDONLY);
+	sprintf(path, fmt, pid);
+	tmp = openat(image_dir_fd, path, O_RDONLY);
 	if (tmp < 0)
 		pr_warn("Can't open image %s for %d: %m\n", fmt, pid);
 
@@ -195,6 +180,35 @@ int open_image_ro(int type, int pid)
 	return fd;
 }
 
+int image_dir_fd = -1;
+
+int open_image_dir(void)
+{
+	int fd;
+
+	image_dir_fd = get_service_fd(IMG_FD_OFF);
+	if (image_dir_fd < 0) {
+		pr_perror("Can't get image fd");
+		return -1;
+	}
+
+	fd = open(".", O_RDONLY);
+	if (fd < 0) {
+		pr_perror("Can't open cwd");
+		return -1;
+	}
+
+	pr_info("Image dir fd is %d\n", image_dir_fd);
+
+	return reopen_fd_as(image_dir_fd, fd);
+}
+
+void close_image_dir(void)
+{
+	close(image_dir_fd);
+	image_dir_fd = -1;
+}
+
 static pid_t open_proc_pid = 0;
 static int open_proc_fd = -1;
 


More information about the CRIU mailing list