[CRIU] [PATCH 20/27] servicefd: add a service fd for current root

Andrey Vagin avagin at openvz.org
Thu Apr 10 04:04:03 PDT 2014


It's already used for dumping files and it will be used for restoring,
so it should be service fd to avoid intersection with restored
descriptors.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-restore.c        |  3 +++
 files-reg.c         | 11 +++++++++--
 include/mount.h     |  1 -
 include/servicefd.h |  1 +
 irmap.c             | 10 +++++++++-
 mount.c             | 17 +++++++++++++----
 sk-unix.c           |  3 +++
 7 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 3142e05..6a9c4e5 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2548,6 +2548,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 
 	close_image_dir();
 
+	close_service_fd(PROC_FD_OFF);
+	close_service_fd(ROOT_FD_OFF);
+
 	__gcov_flush();
 
 	pr_info("task_args: %p\n"
diff --git a/files-reg.c b/files-reg.c
index 750b356..fba683b 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -334,10 +334,12 @@ dump_entry:
 static void __rollback_link_remaps(bool do_unlink)
 {
 	struct link_remap_rlb *rlb, *tmp;
+	int mntns_root;
 
 	if (!opts.link_remap_ok)
 		return;
 
+	mntns_root = get_service_fd(ROOT_FD_OFF);
 	list_for_each_entry_safe(rlb, tmp, &link_remaps, list) {
 		list_del(&rlb->list);
 		if (do_unlink)
@@ -356,6 +358,7 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
 	RegFileEntry rfe = REG_FILE_ENTRY__INIT;
 	FownEntry fwn = FOWN_ENTRY__INIT;
 	struct link_remap_rlb *rlb;
+	int mntns_root;
 
 	if (!opts.link_remap_ok) {
 		pr_err("Can't create link remap for %s. "
@@ -363,6 +366,8 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
 		return -1;
 	}
 
+	mntns_root = get_service_fd(ROOT_FD_OFF);
+
 	/*
 	 * Linked remapping -- we create a hard link on a removed file
 	 * in the directory original file used to sit.
@@ -467,9 +472,9 @@ static inline bool nfs_silly_rename(char *rpath, const struct fd_parms *parms)
 
 static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms, int lfd, u32 id)
 {
-	int ret;
-	struct stat pst;
 	const struct stat *ost = &parms->stat;
+	int ret, mntns_root;
+	struct stat pst;
 
 	if (ost->st_nlink == 0)
 		/*
@@ -492,6 +497,8 @@ static int check_path_remap(char *rpath, int plen, const struct fd_parms *parms,
 		return dump_linked_remap(rpath + 1, plen - 1, ost, lfd, id);
 	}
 
+	mntns_root = get_service_fd(ROOT_FD_OFF);
+
 	ret = fstatat(mntns_root, rpath, &pst, 0);
 	if (ret < 0) {
 		/*
diff --git a/include/mount.h b/include/mount.h
index 67c506e..b312c83 100644
--- a/include/mount.h
+++ b/include/mount.h
@@ -1,7 +1,6 @@
 #ifndef __CR_MOUNT_H__
 #define __CR_MOUNT_H__
 
-extern int mntns_root;
 extern int mntns_collect_root(pid_t pid);
 
 struct proc_mountinfo;
diff --git a/include/servicefd.h b/include/servicefd.h
index f855fe8..0e1992c 100644
--- a/include/servicefd.h
+++ b/include/servicefd.h
@@ -15,6 +15,7 @@ enum sfd_type {
 			 *  For dump -- target ns' proc
 			 *  For restore -- CRIU ns' proc
 			 */
+	ROOT_FD_OFF, /* paths are resolved relative to this root */
 
 	SERVICE_FD_MAX
 };
diff --git a/irmap.c b/irmap.c
index 1af4a95..2be1331 100644
--- a/irmap.c
+++ b/irmap.c
@@ -67,10 +67,13 @@ static int irmap_update_stat(struct irmap *i)
 {
 	struct stat st;
 	unsigned hv;
+	int mntns_root;
 
 	if (i->ino)
 		return 0;
 
+	mntns_root = get_service_fd(ROOT_FD_OFF);
+
 	pr_debug("Refresh stat for %s\n", i->path);
 	if (fstatat(mntns_root, i->path + 1, &st, AT_SYMLINK_NOFOLLOW)) {
 		pr_perror("Can't stat %s", i->path);
@@ -96,13 +99,15 @@ static int irmap_update_stat(struct irmap *i)
  */
 static int irmap_update_dir(struct irmap *t)
 {
-	int fd, nr = 0, dlen;
+	int fd, nr = 0, dlen, mntns_root;
 	DIR *dfd;
 	struct dirent *de;
 
 	if (t->nr_kids >= 0)
 		return 0;
 
+	mntns_root = get_service_fd(ROOT_FD_OFF);
+
 	pr_debug("Refilling %s dir\n", t->path);
 	fd = openat(mntns_root, t->path + 1, O_RDONLY);
 	if (fd < 0) {
@@ -184,6 +189,9 @@ static struct irmap *irmap_scan(struct irmap *t, unsigned int dev, unsigned long
 static int irmap_revalidate(struct irmap *c, struct irmap **p)
 {
 	struct stat st;
+	int mntns_root;
+
+	mntns_root = get_service_fd(ROOT_FD_OFF);
 
 	pr_debug("Revalidate stat for %s\n", c->path);
 	if (fstatat(mntns_root, c->path + 1, &st, AT_SYMLINK_NOFOLLOW)) {
diff --git a/mount.c b/mount.c
index f807ba9..d606022 100644
--- a/mount.c
+++ b/mount.c
@@ -38,7 +38,6 @@ static struct mount_info *mntinfo;
  * for umounting or path resolution.
  */
 static struct mount_info *mntinfo_tree;
-int mntns_root = -1;
 
 static DIR *open_mountpoint(struct mount_info *pm);
 static int close_mountpoint(DIR *dfd);
@@ -74,6 +73,9 @@ static inline int fsroot_mounted(struct mount_info *mi)
 int open_mount(unsigned int s_dev)
 {
 	struct mount_info *i;
+	int mntns_root;
+
+	mntns_root = get_service_fd(ROOT_FD_OFF);
 
 	for (i = mntinfo; i != NULL; i = i->next)
 		if (s_dev == i->s_dev) {
@@ -525,6 +527,10 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
 	int ret;
 
 	if (mnt_fd == -1) {
+		int mntns_root;
+
+		mntns_root = get_service_fd(ROOT_FD_OFF);
+
 		snprintf(path, sizeof(path), ".%s", pm->mountpoint);
 		mnt_fd = openat(mntns_root, path, O_RDONLY);
 		if (mnt_fd < 0) {
@@ -1757,7 +1763,7 @@ int mntns_collect_root(pid_t pid)
 	int ret;
 	char path[PATH_MAX + 1];
 
-	close_safe(&mntns_root);
+	close_service_fd(ROOT_FD_OFF);
 
 	if (!(root_ns_mask & CLONE_NEWNS)) {
 		/*
@@ -1804,8 +1810,11 @@ int mntns_collect_root(pid_t pid)
 	}
 
 set_root:
-	mntns_root = fd;
-	return 0;
+	ret = 0;
+	if (install_service_fd(ROOT_FD_OFF, fd) < 0)
+		ret = -1;
+	close(fd);
+	return ret;
 }
 
 struct ns_desc mnt_ns_desc = NS_DESC_ENTRY(CLONE_NEWNS, "mnt");
diff --git a/sk-unix.c b/sk-unix.c
index c2991ae..a36a1a1 100644
--- a/sk-unix.c
+++ b/sk-unix.c
@@ -403,6 +403,7 @@ static int unix_collect_one(const struct unix_diag_msg *m,
 			struct stat st;
 			char rpath[PATH_MAX];
 			bool drop_path = false;
+			int mntns_root;
 
 			if (name[0] != '/') {
 				pr_warn("Relative bind path '%s' "
@@ -416,6 +417,8 @@ static int unix_collect_one(const struct unix_diag_msg *m,
 				goto skip;
 			}
 
+			mntns_root = get_service_fd(ROOT_FD_OFF);
+
 			uv = RTA_DATA(tb[UNIX_DIAG_VFS]);
 			snprintf(rpath, sizeof(rpath), ".%s", name);
 			if (fstatat(mntns_root, rpath, &st, 0)) {
-- 
1.8.5.3



More information about the CRIU mailing list