[CRIU] [PATCH RFC] bind mounts: handle non-root bind mounts

Andrew Vagin avagin at parallels.com
Wed Jun 25 03:18:54 PDT 2014


On Tue, Jun 24, 2014 at 06:34:03PM -0500, Serge Hallyn wrote:
> As a non-random example, if /dev/pts is a devpts mount and /dev/pts/ptmx
> is bind-mounted onto /dev/ptmx, then mark /dev/ptmx as coming from the
> /dev/pts mount, and make sure /dev/pts is mounted before we try to
> bind-mount /dev/ptmx.

Unfortunately we already have code to handle non-root bind mounts.
Here is a small bug. When devpts is dumped, its options can be modified
to add "newinstance", but it's done only for the "root" mount.

... root: "/ptmx" mountpoint: "/dev/pts/ptmx" source: "pts" options: "mode=666,ptmxmode=666"
... root: "/" mountpoint: "/dev/pts" source: "pts" options: "mode=666,ptmxmode=666,newinstance"

so criu doesn't detect these bind-mounts on restore (look at mounts_equal(a,b,true)).

Thanks,
Andrew

> 
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
> ---
>  mount.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/mount.c b/mount.c
> index 917159c..22e1fda 100644
> --- a/mount.c
> +++ b/mount.c
> @@ -1319,9 +1319,20 @@ static int restore_ext_mount(struct mount_info *mi)
>  	return ret;
>  }
>  
> +static int do_mount_one(struct mount_info *mi);
> +
>  static int do_bind_mount(struct mount_info *mi)
>  {
>  	bool shared = mi->shared_id && mi->shared_id == mi->bind->shared_id;
> +	int ret;
> +
> +	if (mi->bind && !mi->bind->mounted) {
> +		ret = do_mount_one(mi->bind);
> +		if (ret)  {
> +			pr_debug("Failed to mount bind source");
> +			return ret;
> +		}
> +	}
>  
>  	if (!mi->need_plugin) {
>  		char *root, rpath[PATH_MAX];
> @@ -1612,6 +1623,33 @@ static int rst_collect_local_mntns(void)
>  	return 0;
>  }
>  
> +static struct mount_info *find_bind_src_dev(struct mount_info *pms, unsigned int dev)
> +{
> +	struct mount_info *t;
> +	for (t = pms; t; t = t->next) {
> +		if (t->s_dev != dev)
> +			continue;
> +		if (strcmp(t->root, "/") == 0)
> +			return t;
> +	}
> +	return NULL;
> +}
> +
> +static void collate_bind_mounts(struct mount_info *pms)
> +{
> +	struct mount_info *pm, *pm2;
> +
> +	for (pm = pms;  pm;  pm = pm->next) {
> +		if (strcmp(pm->root, "/")) {
> +			pm2 = find_bind_src_dev(pms, pm->s_dev);
> +			if (pm2) {
> +				list_add_tail(&pm->mnt_bind, &pm2->mnt_bind);
> +				pm->bind = pm2;
> +			}
> +		}
> +	}
> +}
> +
>  static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid)
>  {
>  	MntEntry *me = NULL;
> @@ -1710,6 +1748,8 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid)
>  		pr_debug("\tRead %d mp @ %s\n", pm->mnt_id, pm->mountpoint);
>  	}
>  
> +	collate_bind_mounts(*pms);
> +
>  	if (me)
>  		mnt_entry__free_unpacked(me, NULL);
>  
> -- 
> 2.0.0
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list