[CRIU] [PATCH 2/4] servicefd: add a service fd for current root

Andrey Vagin avagin at openvz.org
Tue Apr 15 01:31:40 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>
---
 files-reg.c         | 10 +++++++++-
 include/mount.h     |  1 -
 include/servicefd.h |  1 +
 irmap.c             | 10 +++++++++-
 mount.c             | 13 ++++++++++---
 sk-unix.c           |  3 +++
 6 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/files-reg.c b/files-reg.c
index 7c783b5..5b6c4a3 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -333,10 +333,13 @@ 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)
@@ -355,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. "
@@ -389,6 +393,8 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp)
 	/* Any 'unique' name works here actually. Remap works by reg-file ids. */
 	snprintf(tmp + 1, sizeof(link_name) - (size_t)(tmp - link_name - 1), "link_remap.%d", rfe.id);
 
+	mntns_root = get_service_fd(ROOT_FD_OFF);
+
 	if (linkat(lfd, "", mntns_root, link_name, AT_EMPTY_PATH) < 0) {
 		pr_perror("Can't link remap to %s", path);
 		return -1;
@@ -466,7 +472,7 @@ 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;
+	int ret, mntns_root;
 	struct stat pst;
 	const struct stat *ost = &parms->stat;
 
@@ -491,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 a76c027..a2bc17d 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..1cf93de 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,
 
 	SERVICE_FD_MAX
 };
diff --git a/irmap.c b/irmap.c
index 1af4a95..22750d2 100644
--- a/irmap.c
+++ b/irmap.c
@@ -66,11 +66,14 @@ static struct irmap hints[] = {
 static int irmap_update_stat(struct irmap *i)
 {
 	struct stat st;
+	int mntns_root;
 	unsigned hv;
 
 	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 0dcfcfd..adce76a 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 int open_mountpoint(struct mount_info *pm);
 
@@ -73,6 +72,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) {
@@ -482,6 +484,10 @@ static int __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) {
@@ -1569,8 +1575,9 @@ int mntns_collect_root(pid_t pid)
 	}
 
 set_root:
-	mntns_root = fd;
-	return 0;
+	ret = install_service_fd(ROOT_FD_OFF, fd);
+	close(fd);
+	return ret < 0 ? -1 : 0;
 }
 
 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