[1/2] mount: temporary create needed ancestor directories for deleted root

Submitted by Pavel Tikhomirov on Feb. 15, 2019, 3:58 p.m.

Details

Message ID 20190215155814.11288-1-ptikhomirov@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Pavel Tikhomirov Feb. 15, 2019, 3:58 p.m.
Else on improved (in next patch) zdtm/static/mntns_deleted we get:

(00.032469)      1: mnt: 	Bind /tmp/.criu.mntns.MsWZ6q/12-0000000000/zdtm/static/mntns_deleted.test/test-mid/test-src to /tmp/.criu.mntns.MsWZ6q/12-0000000000/zdtm/static/mntns_deleted.test/test-dst
(00.032495)      1: Error (criu/mount.c:2279): mnt: Can't re-create deleted directory /tmp/.criu.mntns.MsWZ6q/12-0000000000/zdtm/static/mntns_deleted.test/test-mid/test-src: No such file or directory

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 criu/files-reg.c         | 9 +++++++--
 criu/include/files-reg.h | 3 +++
 criu/mount.c             | 8 ++++++++
 3 files changed, 18 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/files-reg.c b/criu/files-reg.c
index e9dcf5efa..9f80e49c9 100644
--- a/criu/files-reg.c
+++ b/criu/files-reg.c
@@ -1498,7 +1498,7 @@  static int linkat_hard(int odir, char *opath, int ndir, char *npath, uid_t uid,
 	return ret;
 }
 
-static void rm_parent_dirs(int mntns_root, char *path, int count)
+void rm_parent_dirs(int mntns_root, char *path, int count)
 {
 	char *p, *prev = NULL;
 
@@ -1525,7 +1525,7 @@  static void rm_parent_dirs(int mntns_root, char *path, int count)
 }
 
 /* Construct parent dir name and mkdir parent/grandparents if they're not exist */
-static int make_parent_dirs_if_need(int mntns_root, char *path)
+int make_parent_dirs_if_need(int mntns_root, char *path)
 {
 	char *p, *last_delim;
 	int err, count = 0;
@@ -1545,6 +1545,11 @@  static int make_parent_dirs_if_need(int mntns_root, char *path)
 	}
 
 	p = path;
+
+	/* when used for absolute paths we need to skip 1-st '/' */
+	if (p[0] == '/')
+		p++;
+
 	do {
 		p = strchr(p, '/');
 		if (p)
diff --git a/criu/include/files-reg.h b/criu/include/files-reg.h
index 7a22d4d82..1486a7e82 100644
--- a/criu/include/files-reg.h
+++ b/criu/include/files-reg.h
@@ -56,4 +56,7 @@  extern int strip_deleted(struct fd_link *link);
 
 extern int dead_pid_conflict(void);
 
+extern int make_parent_dirs_if_need(int mntns_root, char *path);
+extern void rm_parent_dirs(int mntns_root, char *path, int count);
+
 #endif /* __CR_FILES_REG_H__ */
diff --git a/criu/mount.c b/criu/mount.c
index 118ba623e..ec293b31c 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -2189,6 +2189,7 @@  static int do_bind_mount(struct mount_info *mi)
 	struct stat st;
 	bool umount_mnt_path = false;
 	struct mount_info *c;
+	int level = 0;
 
 	if (mi->need_plugin) {
 		if (restore_ext_mount(mi))
@@ -2274,6 +2275,10 @@  static int do_bind_mount(struct mount_info *mi)
 			goto err;
 		}
 
+		level = make_parent_dirs_if_need(-1, root);
+		if (level < 0)
+			goto err;
+
 		if (S_ISDIR(st.st_mode)) {
 			if (mkdir(root, (st.st_mode & ~S_IFMT))) {
 				pr_perror("Can't re-create deleted directory %s", root);
@@ -2332,6 +2337,9 @@  static int do_bind_mount(struct mount_info *mi)
 	mi->mounted = true;
 	exit_code = 0;
 err:
+	if(level)
+		rm_parent_dirs(-1, root, level);
+
 	if (umount_mnt_path) {
 		/*
 		 * If mnt_path was shared, a new mount may be propagated