diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index bff2047aa1..7ddcb93daf 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -17,9 +17,12 @@ #include "devnum-util.h" #include "dirent-util.h" #include "errno-util.h" +#include "extension-util.h" #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "macro.h" +#include "os-util.h" #include "parse-util.h" #include "path-util.h" #include "string-util.h" @@ -875,6 +878,13 @@ int blockdev_get_root(int level, dev_t *ret) { return btrfs_log_dev_root(level, r, "/usr"); if (r < 0) return log_full_errno(level, r, "Failed to determine block device of /usr/ file system: %m"); + if (r == 0) { /* Not backed by a single block device, we might be looking at a sysext overlay */ + r = extension_overlay_block("/usr", IMAGE_SYSEXT, &devno); + if (IN_SET(r, -ENOENT, -ENOTTY)) + r = 0; /* no sysext overlay metadata */ + else if (r < 0) + return log_full_errno(level, r, "Failed to determine backing device of /usr/ extension overlay: %m"); + } if (r == 0) { /* /usr/ not backed by single block device, either. */ log_debug("Neither root nor /usr/ file system are on a (single) block device."); diff --git a/src/shared/extension-util.c b/src/shared/extension-util.c index d993b47de5..e81f2a07ac 100644 --- a/src/shared/extension-util.c +++ b/src/shared/extension-util.c @@ -12,6 +12,7 @@ #include "fd-util.h" #include "fileio.h" #include "log.h" +#include "macro.h" #include "os-util.h" #include "path-util.h" #include "stat-util.h" @@ -192,6 +193,7 @@ int extension_overlay_block(const char *p, ImageClass image_class, dev_t *ret) { assert(p); assert(ret); + assert(IN_SET(image_class, IMAGE_SYSEXT, IMAGE_CONFEXT)); /* Tries to read the backing device information systemd-sysext puts in * the virtual file .systemd-sysext/.systemd-confext */ diff --git a/test/units/TEST-50-DISSECT.usr-gpt-auto-generator.sh b/test/units/TEST-50-DISSECT.usr-gpt-auto-generator.sh new file mode 100755 index 0000000000..37a85e1865 --- /dev/null +++ b/test/units/TEST-50-DISSECT.usr-gpt-auto-generator.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +GENERATOR_BIN="/usr/lib/systemd/system-generators/systemd-gpt-auto-generator" +WORK_DIR="$(mktemp --directory /var/tmp/test-gpt-auto-generator.XXXXXX)" +DEFINITIONS="$WORK_DIR/definitions" +IMAGE="$WORK_DIR/image.raw" +OUTPUT="$WORK_DIR/output" +ROOT="$WORK_DIR/root" +LOOP="" + +at_exit() { + set +e + + if [[ -n "$LOOP" ]]; then + losetup --detach "$LOOP" + fi + + rm -rf "$WORK_DIR" +} + +trap at_exit EXIT + +test -x "$GENERATOR_BIN" +mkdir -p "$DEFINITIONS" "$OUTPUT"/{normal,early,late} "$ROOT" + +cat >"$DEFINITIONS/10-usr.conf" <"$DEFINITIONS/20-home.conf" <"$1/usr/.systemd-sysext/backing" + +export container= +export SYSTEMD_IN_INITRD=0 +export SYSTEMD_PROC_CMDLINE="root=tmpfs systemd.gpt_auto=yes" +exec chroot "$1" "$5" \ + /run/generator-output/normal \ + /run/generator-output/early \ + /run/generator-output/late +EOF + +test -f "$OUTPUT/late/home.mount" +WHAT="$(sed -n 's/^What=//p' "$OUTPUT/late/home.mount")" +test "$(readlink --canonicalize "$WHAT")" = "$(readlink --canonicalize "${LOOP}p2")"