Skip to content

Commit 27034e7

Browse files
Snorchavagin
authored andcommitted
mount: fix regression where open_mountpoint failed on readonly fs
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 b6cfb1c ("mount: make open_mountpoint handle overmouts properly") #520 Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Acked-by: Adrian Reber <areber@redhat.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
1 parent 594c3a4 commit 27034e7

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

criu/mount.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,10 +1325,18 @@ int ns_open_mountpoint(void *arg)
13251325
if (umount_overmounts(mi))
13261326
goto err;
13271327

1328-
/* Save fd which we opened for parent due to CLONE_FILES flag */
1329-
*fd = get_clean_fd(mi);
1330-
if (*fd < 0)
1328+
/*
1329+
* Save fd which we opened for parent due to CLONE_FILES flag
1330+
*
1331+
* Mount can still have children in it, but we don't need to clean it
1332+
* explicitly as when last process exits mntns all mounts in it are
1333+
* cleaned from their children, and we are exactly the last process.
1334+
*/
1335+
*fd = open(mi->mountpoint, O_DIRECTORY|O_RDONLY);
1336+
if (*fd < 0) {
1337+
pr_perror("Unable to open %s", mi->mountpoint);
13311338
goto err;
1339+
}
13321340

13331341
return 0;
13341342
err:
@@ -1367,18 +1375,22 @@ int open_mountpoint(struct mount_info *pm)
13671375

13681376
if (!mnt_is_overmounted(pm)) {
13691377
pr_info("\tmount has children %s\n", pm->mountpoint);
1370-
13711378
fd = get_clean_fd(pm);
1372-
if (fd < 0)
1373-
goto err;
1374-
} else {
1379+
}
1380+
1381+
/*
1382+
* Mount is overmounted or probably we can't create a temporary
1383+
* direcotry for a cleaned mount
1384+
*/
1385+
if (fd < 0) {
13751386
int pid, status;
13761387
struct clone_arg ca = {
13771388
.mi = pm,
13781389
.fd = &fd
13791390
};
13801391

1381-
pr_info("\tmount is overmounted %s\n", pm->mountpoint);
1392+
pr_info("\tmount is overmounted or has children %s\n",
1393+
pm->mountpoint);
13821394

13831395
/*
13841396
* We are overmounted - not accessible in a regular way. We

0 commit comments

Comments
 (0)