[CRIU] [PATCH 1/2] mount: temporary create needed ancestor directories for deleted root
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Fri Feb 15 18:58:13 MSK 2019
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 at virtuozzo.com>
---
criu/files-reg.c | 9 +++++++--
criu/include/files-reg.h | 3 +++
criu/mount.c | 8 ++++++++
3 files changed, 18 insertions(+), 2 deletions(-)
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
--
2.20.1
More information about the CRIU
mailing list