[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