core: deduplicate identical dm-verity ExtensionImages=

It turns out OverlayFS doesn't handle gracefully when the same source is
specified multiple times in lowerdir= and it fails with ELOOP:

Failed to mount overlay (type overlay) on /run/systemd/mount-rootfs/opt (MS_RDONLY "lowerdir=/run/systemd/unit-extensions/1/opt:/run/systemd/unit-extensions/0/opt:/run/systemd/mount-rootfs/opt"): Too many levels of symbolic links

This happens even if we mount each image in a different internal mount
path, as OverlayFS will resolve it and look for the backing device, which
will be the same device mapper entity, and return a hard error.
This error does not appear if dm-verity is not used, so it is very
confusing for users, and unnecessary.

When mounting ExtensionImages, check if an image is dm-veritied,
and drop duplicates if the root hashes match, to avoid this user-unfriendly
hard error.
This commit is contained in:
Luca Boccassi
2024-06-28 14:37:58 +01:00
parent b268a71069
commit a1a40297db
6 changed files with 85 additions and 14 deletions
+1
View File
@@ -37,6 +37,7 @@ test_append_files() {
inst_binary mksquashfs
inst_binary unsquashfs
inst_binary pkcheck
inst_binary veritysetup
install_verity_minimal
}
+16
View File
@@ -389,6 +389,22 @@ systemd-run -P \
--property RootImage="$MINIMAL_IMAGE.raw" \
"${BIND_LOG_SOCKETS[@]}" \
cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123"
# Check that two identical verity images at different paths do not fail with -ELOOP from OverlayFS
mkdir -p /tmp/loop
cp /tmp/app0.raw /tmp/loop/app0.raw
veritysetup format /tmp/loop/app0.raw /tmp/loop/app0.verity --root-hash-file /tmp/loop/app0.roothash
cp /tmp/loop/app0.raw /tmp/loop/app0_copy.raw
cp /tmp/loop/app0.verity /tmp/loop/app0_copy.verity
cp /tmp/loop/app0.roothash /tmp/loop/app0_copy.roothash
systemd-run -P \
--property ExtensionImages=/tmp/loop/app0.raw \
--property ExtensionImages=/tmp/loop/app0_copy.raw \
--property RootImage="$MINIMAL_IMAGE.raw" \
"${BIND_LOG_SOCKETS[@]}" \
cat /opt/script0.sh | grep -q -F "extension-release.app0"
rm -rf /tmp/loop/
# Check that using a symlink to NAME-VERSION.raw works as long as the symlink has the correct name NAME.raw
mkdir -p /tmp/symlink-test/
cp /tmp/app-nodistro.raw /tmp/symlink-test/app-nodistro-v1.raw