mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
mount-v2: workaround for multiple external bindmounts with no common root
It's a problem when while restoring sharing group we need to copy sharing between two mounts with non-intersecting roots, because kernel does not allow it. We have a case https://github.com/opencontainers/runc/pull/3442, where runc adds different devtmpfs file-bindmounts to container and there is no fsroot mount in container for this devtmpfs, thus mount-v2 faces the above problem. Luckily for the case of external mounts which are in one sharing group and which have non-intersecting roots, these mounts likely only have external master with no sharing, so we can just copy sharing from external source and make it slave as a workaround. https://github.com/checkpoint-restore/criu/issues/1886 Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
parent
f8c9e07e4f
commit
229c5df5ce
1 changed files with 29 additions and 3 deletions
|
|
@ -996,9 +996,35 @@ static int restore_one_sharing_group(struct sharing_group *sg)
|
|||
if (other == first)
|
||||
continue;
|
||||
|
||||
if (move_mount_set_group(first->mnt_fd_id, NULL, other->mnt_fd_id)) {
|
||||
pr_err("Failed to copy sharing from %d to %d\n", first->mnt_id, other->mnt_id);
|
||||
return -1;
|
||||
if (is_sub_path(other->root, first->root)) {
|
||||
if (move_mount_set_group(first->mnt_fd_id, NULL, other->mnt_fd_id)) {
|
||||
pr_err("Failed to copy sharing from %d to %d\n", first->mnt_id, other->mnt_id);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Case where mounts of this sharing group don't have common root.
|
||||
* For instance we can create two sub-directories .a and .b in some
|
||||
* shared mount, bindmount them separately somethere and umount the
|
||||
* original mount. Now we have both bindmounts shared between each
|
||||
* other. Kernel only allows to copy sharing between mounts when
|
||||
* source root contains destination root, which is not true for
|
||||
* these two, so we can't just copy from first to other.
|
||||
*
|
||||
* For external sharing (!sg->parent) with only master_id (shared_id
|
||||
* == 0) we can workaround this by copying from their external source
|
||||
* instead (same as we did for a first mount).
|
||||
*
|
||||
* This is a w/a runc usecase, see https://github.com/opencontainers/runc/pull/3442
|
||||
*/
|
||||
if (!sg->parent && !sg->shared_id) {
|
||||
if (restore_one_sharing(sg, other))
|
||||
return -1;
|
||||
} else {
|
||||
pr_err("Can't copy sharing from %d[%s] to %d[%s]\n", first->mnt_id, first->root,
|
||||
other->mnt_id, other->root);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue