[CRIU] [PATCH 1/3] mount: Handle deleted bindmounts for regular files

Cyrill Gorcunov gorcunov at gmail.com
Tue Sep 1 04:11:18 PDT 2015


On Tue, Sep 01, 2015 at 12:30:02PM +0300, Pavel Emelyanov wrote:
> On 08/26/2015 05:15 PM, Cyrill Gorcunov wrote:
> > Reported-by: Andrey Wagin <avagin at gmail.com>
> > Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> 
> Some comment saying why it's enough to stat() on restore time would be good.
> And one more comment inline.

Patches 1 and 3 are merged, comment updated and code fixed.
Take a look please.
-------------- next part --------------
>From 0628e7c8e8082e301685f42f73d94b55b78a8f35 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Wed, 26 Aug 2015 17:07:31 +0300
Subject: [PATCH] mount: Handle deleted bindmounts for regular files

1) Deleted bindmount for files should be restored
   by creating temp file. The kernel doesn't permit
   to mix bindmount in terms of file/dir relationship:
   either both source and target should be files or
   directories.

   Thus we can call stat on the target and figure out
   what kind of source we had.

2) Even for deleted entries better to use permissions
   from the target's stat call, this makes result close
   to how would it look if program hadn't been checkpointed.

Reported-by: Andrey Wagin <avagin at gmail.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 mount.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/mount.c b/mount.c
index 04b99d990bfe..6d44eae442ac 100644
--- a/mount.c
+++ b/mount.c
@@ -1970,6 +1970,7 @@ static int do_bind_mount(struct mount_info *mi)
 {
 	bool shared = 0;
 	bool force_private_remount = false;
+	struct stat st;
 
 	if (!mi->need_plugin) {
 		char *root, *cut_root, rpath[PATH_MAX];
@@ -1996,8 +1997,24 @@ do_bind:
 		pr_info("\tBind %s to %s\n", root, mi->mountpoint);
 
 		if (unlikely(mi->deleted)) {
-			if (mkdir(root, 0700)) {
-				pr_perror("Can't re-create deleted %s\n", root);
+			if (stat(mi->mountpoint, &st)) {
+				pr_perror("Can't fetch stat on %s", mi->mountpoint);
+				return -1;
+			}
+
+			if (S_ISDIR(st.st_mode)) {
+				if (mkdir(root, (st.st_mode & ~S_IFMT))) {
+					pr_perror("Can't re-create deleted directory %s\n", root);
+					return -1;
+				}
+			} else if (S_ISREG(st.st_mode)) {
+				if (open(root, O_WRONLY | O_CREAT | O_TRUNC, (st.st_mode & ~S_IFMT)) < 0) {
+					pr_perror("Can't re-create deleted file %s\n", root);
+					return -1;
+				}
+			} else {
+				pr_err("Unsupported st_mode 0%o deleted root %s\n",
+				       (int)st.st_mode, root);
 				return -1;
 			}
 		}
@@ -2008,9 +2025,16 @@ do_bind:
 		}
 
 		if (unlikely(mi->deleted)) {
-			if (rmdir(root)) {
-				pr_perror("Can't remove deleted %s\n", root);
-				return -1;
+			if (S_ISDIR(st.st_mode)) {
+				if (rmdir(root)) {
+					pr_perror("Can't remove deleted directory %s\n", root);
+					return -1;
+				}
+			} else if (S_ISREG(st.st_mode)) {
+				if (unlink(root)) {
+					pr_perror("Can't unlink deleted file %s\n", root);
+					return -1;
+				}
 			}
 		}
 	} else {
-- 
2.4.3



More information about the CRIU mailing list