[v2] mount: dump a file system only if a mount point isn't overmounted

Submitted by Andrei Vagin on May 10, 2016, 2:37 a.m.

Details

Message ID 1462847849-2175-1-git-send-email-avagin@openvz.org
State Rejected
Series "mount: dump a file system only if a mount point isn't overmounted"
Headers show

Commit Message

Andrei Vagin May 10, 2016, 2:37 a.m.
From: Andrew Vagin <avagin@virtuozzo.com>

Something else may be mounted into the same folder and in this case
we can't get access to the required file system.

$ cat /proc/61693/root/etc/redhat-release
Fedora release 23 (Twenty Three)

$ cat /proc/61692/mountinfo  | grep '\s/tmp'
234 199 0:57 / /tmp rw shared:97 master:76 - tmpfs tmpfs rw,size=131072k,nr_inodes=32768
235 234 0:57 /systemd-private-dd74de99e1104383aa7cd6e27d3d0b8a-httpd.service-uFqNHk/tmp /tmp rw,relatime shared:98 master:76 - tmpfs tmpfs rw,size=131072k,nr_inodes=32768

v2: return an error if we can't dump a file system
Signed-off-by: Andrew Vagin <avagin@virtuozzo.com>
---
 criu/mount.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 48 insertions(+), 9 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/mount.c b/criu/mount.c
index fc584bf..13d1b3e 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -1864,6 +1864,52 @@  uns:
 	return &fstypes[0];
 }
 
+static bool can_dump_fs(struct mount_info *pm)
+{
+	struct mount_info *c;
+	bool overmounted = false;
+
+	if (!fsroot_mounted(pm))
+		return false;
+
+	list_for_each_entry(c, &pm->children, siblings)
+		if (strcmp(pm->mountpoint, c->mountpoint) == 0)
+			overmounted = true;
+
+	if (overmounted)
+		return false;
+
+	return true;
+}
+
+static int dump_one_fs(struct mount_info *mi)
+{
+	struct mount_info *pm = mi;
+	struct mount_info *t;
+
+	if (!mi->parent || mi->need_plugin || mi->external || !mi->fstype->dump)
+		return 0;
+
+	if (can_dump_fs(mi))
+		goto dump;
+
+	list_for_each_entry(pm, &mi->mnt_bind, mnt_bind)
+		if (can_dump_fs(pm))
+			goto dump;
+
+	pr_err("Unable to dumpe a file system for %d:%s\n",
+				mi->mnt_id, mi->mountpoint);
+	return -1;
+
+dump:
+	if (pm->fstype->dump(pm))
+		return -1;
+
+	list_for_each_entry(t, &pm->mnt_bind, mnt_bind)
+		t->dumped = true;
+	return 0;
+}
+
 static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img)
 {
 	MntEntry me = MNT_ENTRY__INIT;
@@ -1876,16 +1922,9 @@  static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img)
 	if (me.fstype == FSTYPE__AUTO)
 		me.fsname = pm->fsname;
 
-	if (pm->parent && !pm->dumped && !pm->need_plugin && !pm->external &&
-	    pm->fstype->dump && fsroot_mounted(pm)) {
-		struct mount_info *t;
 
-		if (pm->fstype->dump(pm))
-			return -1;
-
-		list_for_each_entry(t, &pm->mnt_bind, mnt_bind)
-			t->dumped = true;
-	}
+	if (!pm->dumped && dump_one_fs(pm))
+		return -1;
 
 	me.mnt_id		= pm->mnt_id;
 	me.root_dev		= pm->s_dev;

Comments

Andrey Vagin May 10, 2016, 4:57 p.m.
Pls, ignore this patch. It doesn't work for autofs, which can be
overmounted, but we don't need to access it to dump it.

On Tue, May 10, 2016 at 05:37:29AM +0300, Andrey Vagin wrote:
> From: Andrew Vagin <avagin@virtuozzo.com>
> 
> Something else may be mounted into the same folder and in this case
> we can't get access to the required file system.
> 
> $ cat /proc/61693/root/etc/redhat-release
> Fedora release 23 (Twenty Three)
> 
> $ cat /proc/61692/mountinfo  | grep '\s/tmp'
> 234 199 0:57 / /tmp rw shared:97 master:76 - tmpfs tmpfs rw,size=131072k,nr_inodes=32768
> 235 234 0:57 /systemd-private-dd74de99e1104383aa7cd6e27d3d0b8a-httpd.service-uFqNHk/tmp /tmp rw,relatime shared:98 master:76 - tmpfs tmpfs rw,size=131072k,nr_inodes=32768
> 
> v2: return an error if we can't dump a file system
> Signed-off-by: Andrew Vagin <avagin@virtuozzo.com>
> ---
>  criu/mount.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 48 insertions(+), 9 deletions(-)
> 
> diff --git a/criu/mount.c b/criu/mount.c
> index fc584bf..13d1b3e 100644
> --- a/criu/mount.c
> +++ b/criu/mount.c
> @@ -1864,6 +1864,52 @@ uns:
>  	return &fstypes[0];
>  }
>  
> +static bool can_dump_fs(struct mount_info *pm)
> +{
> +	struct mount_info *c;
> +	bool overmounted = false;
> +
> +	if (!fsroot_mounted(pm))
> +		return false;
> +
> +	list_for_each_entry(c, &pm->children, siblings)
> +		if (strcmp(pm->mountpoint, c->mountpoint) == 0)
> +			overmounted = true;
> +
> +	if (overmounted)
> +		return false;
> +
> +	return true;
> +}
> +
> +static int dump_one_fs(struct mount_info *mi)
> +{
> +	struct mount_info *pm = mi;
> +	struct mount_info *t;
> +
> +	if (!mi->parent || mi->need_plugin || mi->external || !mi->fstype->dump)
> +		return 0;
> +
> +	if (can_dump_fs(mi))
> +		goto dump;
> +
> +	list_for_each_entry(pm, &mi->mnt_bind, mnt_bind)
> +		if (can_dump_fs(pm))
> +			goto dump;
> +
> +	pr_err("Unable to dumpe a file system for %d:%s\n",
> +				mi->mnt_id, mi->mountpoint);
> +	return -1;
> +
> +dump:
> +	if (pm->fstype->dump(pm))
> +		return -1;
> +
> +	list_for_each_entry(t, &pm->mnt_bind, mnt_bind)
> +		t->dumped = true;
> +	return 0;
> +}
> +
>  static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img)
>  {
>  	MntEntry me = MNT_ENTRY__INIT;
> @@ -1876,16 +1922,9 @@ static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img)
>  	if (me.fstype == FSTYPE__AUTO)
>  		me.fsname = pm->fsname;
>  
> -	if (pm->parent && !pm->dumped && !pm->need_plugin && !pm->external &&
> -	    pm->fstype->dump && fsroot_mounted(pm)) {
> -		struct mount_info *t;
>  
> -		if (pm->fstype->dump(pm))
> -			return -1;
> -
> -		list_for_each_entry(t, &pm->mnt_bind, mnt_bind)
> -			t->dumped = true;
> -	}
> +	if (!pm->dumped && dump_one_fs(pm))
> +		return -1;
>  
>  	me.mnt_id		= pm->mnt_id;
>  	me.root_dev		= pm->s_dev;
> -- 
> 2.7.4
>