[CRIU] [PATCH] mount: fix regression where open_mountpoint failed on readonly fs
Andrew Vagin
avagin at virtuozzo.com
Thu Jul 12 20:51:41 MSK 2018
Applied, thanks!
On Wed, Jul 11, 2018 at 01:43:33PM +0300, Pavel Tikhomirov wrote:
> If we fail to create temporary directory for doing a clean mount we can
> make mount clean reusing the code which enters new mountns to umount
> overmounts. As when last process exits mntns all mounts are implicitly
> cleaned from children, see in kernel source - sys_exit->do_exit
> ->exit_task_namespaces->switch_task_namespaces->free_nsproxy
> ->put_mnt_ns->umount_tree->drop_collected_mounts->umount_tree:
>
> /* Hide the mounts from mnt_mounts */
> list_for_each_entry(p, &tmp_list, mnt_list) {
> list_del_init(&p->mnt_child);
> }
>
> Fixes commit b6cfb1ce2948 ("mount: make open_mountpoint handle overmouts
> properly")
>
> https://github.com/checkpoint-restore/criu/issues/520
> Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
> criu/mount.c | 28 ++++++++++++++++++++--------
> 1 file changed, 20 insertions(+), 8 deletions(-)
>
> diff --git a/criu/mount.c b/criu/mount.c
> index 0a8406c80..8689cecdd 100644
> --- a/criu/mount.c
> +++ b/criu/mount.c
> @@ -1298,10 +1298,18 @@ int ns_open_mountpoint(void *arg)
> if (umount_overmounts(mi))
> goto err;
>
> - /* Save fd which we opened for parent due to CLONE_FILES flag */
> - *fd = get_clean_fd(mi);
> - if (*fd < 0)
> + /*
> + * Save fd which we opened for parent due to CLONE_FILES flag
> + *
> + * Mount can still have children in it, but we don't need to clean it
> + * explicitly as when last process exits mntns all mounts in it are
> + * cleaned from their children, and we are exactly the last process.
> + */
> + *fd = open(mi->mountpoint, O_DIRECTORY|O_RDONLY);
> + if (*fd < 0) {
> + pr_perror("Unable to open %s", mi->mountpoint);
> goto err;
> + }
>
> return 0;
> err:
> @@ -1340,18 +1348,22 @@ int open_mountpoint(struct mount_info *pm)
>
> if (!mnt_is_overmounted(pm)) {
> pr_info("\tmount has children %s\n", pm->mountpoint);
> -
> fd = get_clean_fd(pm);
> - if (fd < 0)
> - goto err;
> - } else {
> + }
> +
> + /*
> + * Mount is overmounted or probably we can't create a temporary
> + * direcotry for a cleaned mount
> + */
> + if (fd < 0) {
> int pid, status;
> struct clone_arg ca = {
> .mi = pm,
> .fd = &fd
> };
>
> - pr_info("\tmount is overmounted %s\n", pm->mountpoint);
> + pr_info("\tmount is overmounted or has children %s\n",
> + pm->mountpoint);
>
> /*
> * We are overmounted - not accessible in a regular way. We
> --
> 2.17.0
>
More information about the CRIU
mailing list