Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Tikhomirov <ptikhomirov@virtuozzo.com>2022-05-18 18:25:43 +0300
committerAndrei Vagin <avagin@gmail.com>2022-06-22 20:20:33 +0300
commit229c5df5cefa4be44305ca08ae20befbb3d0f91d (patch)
treef7fc4de6e005de2429dab38e7975bf48d74770b8
parentf8c9e07e4f21685e31a91430da7f1fc55ad36bbb (diff)
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>
-rw-r--r--criu/mount-v2.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/criu/mount-v2.c b/criu/mount-v2.c
index 1d188114f..5d53e9a22 100644
--- a/criu/mount-v2.c
+++ b/criu/mount-v2.c
@@ -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;
+ }
}
}