mirror of
https://github.com/systemd/systemd.git
synced 2025-02-03 17:47:28 +03:00
Merge pull request #30321 from yuwata/find-esp
find-esp: gracefully handle btrfs RAID
This commit is contained in:
commit
a19e7f3101
@ -27,9 +27,29 @@
|
||||
typedef enum VerifyESPFlags {
|
||||
VERIFY_ESP_SEARCHING = 1 << 0, /* Downgrade various "not found" logs to debug level */
|
||||
VERIFY_ESP_UNPRIVILEGED_MODE = 1 << 1, /* Call into udev rather than blkid */
|
||||
VERIFY_ESP_RELAX_CHECKS = 1 << 2, /* Do not validate ESP partition */
|
||||
VERIFY_ESP_SKIP_FSTYPE_CHECK = 1 << 2, /* Skip filesystem check */
|
||||
VERIFY_ESP_SKIP_DEVICE_CHECK = 1 << 3, /* Skip device node check */
|
||||
} VerifyESPFlags;
|
||||
|
||||
static VerifyESPFlags verify_esp_flags_init(int unprivileged_mode, const char *env_name_for_relaxing) {
|
||||
VerifyESPFlags flags = 0;
|
||||
|
||||
assert(env_name_for_relaxing);
|
||||
|
||||
if (unprivileged_mode < 0)
|
||||
unprivileged_mode = geteuid() != 0;
|
||||
if (unprivileged_mode)
|
||||
flags |= VERIFY_ESP_UNPRIVILEGED_MODE;
|
||||
|
||||
if (getenv_bool(env_name_for_relaxing) > 0)
|
||||
flags |= VERIFY_ESP_SKIP_FSTYPE_CHECK | VERIFY_ESP_SKIP_DEVICE_CHECK;
|
||||
|
||||
if (detect_container() > 0)
|
||||
flags |= VERIFY_ESP_SKIP_DEVICE_CHECK;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int verify_esp_blkid(
|
||||
dev_t devid,
|
||||
VerifyESPFlags flags,
|
||||
@ -326,7 +346,7 @@ static int verify_esp(
|
||||
dev_t *ret_devid,
|
||||
VerifyESPFlags flags) {
|
||||
|
||||
bool relax_checks, searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
|
||||
bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
|
||||
unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE);
|
||||
_cleanup_free_ char *p = NULL;
|
||||
_cleanup_close_ int pfd = -EBADF;
|
||||
@ -343,10 +363,6 @@ static int verify_esp(
|
||||
* -EACESS → if 'unprivileged_mode' is set, and we have trouble accessing the thing
|
||||
*/
|
||||
|
||||
relax_checks =
|
||||
getenv_bool("SYSTEMD_RELAX_ESP_CHECKS") > 0 ||
|
||||
FLAGS_SET(flags, VERIFY_ESP_RELAX_CHECKS);
|
||||
|
||||
/* Non-root user can only check the status, so if an error occurred in the following, it does not cause any
|
||||
* issues. Let's also, silence the error messages. */
|
||||
|
||||
@ -356,7 +372,7 @@ static int verify_esp(
|
||||
(unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR,
|
||||
r, "Failed to open parent directory of \"%s\": %m", path);
|
||||
|
||||
if (!relax_checks) {
|
||||
if (!FLAGS_SET(flags, VERIFY_ESP_SKIP_FSTYPE_CHECK)) {
|
||||
_cleanup_free_ char *f = NULL;
|
||||
struct statfs sfs;
|
||||
|
||||
@ -383,19 +399,20 @@ static int verify_esp(
|
||||
"File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p);
|
||||
}
|
||||
|
||||
relax_checks =
|
||||
relax_checks ||
|
||||
detect_container() > 0;
|
||||
|
||||
r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid);
|
||||
r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* In a container we don't have access to block devices, skip this part of the verification, we trust
|
||||
* the container manager set everything up correctly on its own. */
|
||||
if (relax_checks)
|
||||
if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK))
|
||||
goto finish;
|
||||
|
||||
if (devnum_is_zero(devid))
|
||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||
"Could not determine backing block device of directory \"%s\" (btrfs RAID?).", p);
|
||||
|
||||
/* If we are unprivileged we ask udev for the metadata about the partition. If we are privileged we
|
||||
* use blkid instead. Why? Because this code is called from 'bootctl' which is pretty much an
|
||||
* emergency recovery tool that should also work when udev isn't up (i.e. from the emergency shell),
|
||||
@ -454,15 +471,7 @@ int find_esp_and_warn_at(
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
|
||||
if (unprivileged_mode < 0)
|
||||
unprivileged_mode = geteuid() != 0;
|
||||
flags = unprivileged_mode > 0 ? VERIFY_ESP_UNPRIVILEGED_MODE : 0;
|
||||
|
||||
r = dir_fd_is_root_or_cwd(rfd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if directory file descriptor is root: %m");
|
||||
if (r == 0)
|
||||
flags |= VERIFY_ESP_RELAX_CHECKS;
|
||||
flags = verify_esp_flags_init(unprivileged_mode, "SYSTEMD_RELAX_ESP_CHECKS");
|
||||
|
||||
if (path)
|
||||
return verify_esp(rfd, path, ret_path, ret_part, ret_pstart, ret_psize, ret_uuid, ret_devid, flags);
|
||||
@ -742,8 +751,7 @@ static int verify_xbootldr(
|
||||
_cleanup_free_ char *p = NULL;
|
||||
_cleanup_close_ int pfd = -EBADF;
|
||||
bool searching = FLAGS_SET(flags, VERIFY_ESP_SEARCHING),
|
||||
unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE),
|
||||
relax_checks;
|
||||
unprivileged_mode = FLAGS_SET(flags, VERIFY_ESP_UNPRIVILEGED_MODE);
|
||||
dev_t devid = 0;
|
||||
int r;
|
||||
|
||||
@ -756,17 +764,22 @@ static int verify_xbootldr(
|
||||
(unprivileged_mode && ERRNO_IS_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR,
|
||||
r, "Failed to open parent directory of \"%s\": %m", path);
|
||||
|
||||
relax_checks =
|
||||
getenv_bool("SYSTEMD_RELAX_XBOOTLDR_CHECKS") > 0 ||
|
||||
detect_container() > 0;
|
||||
|
||||
r = verify_fsroot_dir(pfd, p, flags, relax_checks ? NULL : &devid);
|
||||
r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (relax_checks)
|
||||
if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK))
|
||||
goto finish;
|
||||
|
||||
if (devnum_is_zero(devid))
|
||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||
"Could not determine backing block device of directory \"%s\" (btrfs RAID?).%s",
|
||||
p,
|
||||
searching ? "" :
|
||||
"\nHint: set $SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes environment variable "
|
||||
"to bypass this and further verifications for the directory.");
|
||||
|
||||
if (unprivileged_mode)
|
||||
r = verify_xbootldr_udev(devid, flags, ret_uuid);
|
||||
else
|
||||
@ -800,17 +813,14 @@ int find_xbootldr_and_warn_at(
|
||||
sd_id128_t *ret_uuid,
|
||||
dev_t *ret_devid) {
|
||||
|
||||
VerifyESPFlags flags = 0;
|
||||
VerifyESPFlags flags;
|
||||
int r;
|
||||
|
||||
/* Similar to find_esp_and_warn(), but finds the XBOOTLDR partition. Returns the same errors. */
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
|
||||
if (unprivileged_mode < 0)
|
||||
unprivileged_mode = geteuid() != 0;
|
||||
if (unprivileged_mode)
|
||||
flags |= VERIFY_ESP_UNPRIVILEGED_MODE;
|
||||
flags = verify_esp_flags_init(unprivileged_mode, "SYSTEMD_RELAX_XBOOTLDR_CHECKS");
|
||||
|
||||
if (path)
|
||||
return verify_xbootldr(rfd, path, flags, ret_path, ret_uuid, ret_devid);
|
||||
|
@ -27,7 +27,7 @@ check_result_qemu() {
|
||||
|
||||
mount_initdir
|
||||
|
||||
cryptsetup luksOpen "${LOOPDEV:?}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile"
|
||||
cryptsetup luksOpen "${LOOPDEV:?}p4" "${DM_NAME:?}" <"$TESTDIR/keyfile"
|
||||
mount "/dev/mapper/$DM_NAME" "$initdir/var"
|
||||
|
||||
check_result_common "${initdir:?}" && ret=0 || ret=$?
|
||||
@ -43,8 +43,8 @@ test_create_image() {
|
||||
create_empty_image_rootdir
|
||||
|
||||
echo -n test >"${TESTDIR:?}/keyfile"
|
||||
cryptsetup -q luksFormat --uuid="$PART_UUID" --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p2" "$TESTDIR/keyfile"
|
||||
cryptsetup luksOpen "${LOOPDEV}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile"
|
||||
cryptsetup -q luksFormat --uuid="$PART_UUID" --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p4" "$TESTDIR/keyfile"
|
||||
cryptsetup luksOpen "${LOOPDEV}p4" "${DM_NAME:?}" <"$TESTDIR/keyfile"
|
||||
mkfs.ext4 -L var "/dev/mapper/$DM_NAME"
|
||||
mkdir -p "${initdir:?}/var"
|
||||
mount "/dev/mapper/$DM_NAME" "$initdir/var"
|
||||
|
@ -24,7 +24,7 @@ _host_has_feature() {(
|
||||
|
||||
case "${1:?}" in
|
||||
btrfs)
|
||||
modprobe -nv btrfs && command -v mkfs.btrfs && command -v btrfs || return $?
|
||||
host_has_btrfs
|
||||
;;
|
||||
iscsi)
|
||||
# Client/initiator (Open-iSCSI)
|
||||
@ -36,7 +36,7 @@ _host_has_feature() {(
|
||||
command -v lvm || return $?
|
||||
;;
|
||||
mdadm)
|
||||
command -v mdadm || return $?
|
||||
host_has_mdadm
|
||||
;;
|
||||
multipath)
|
||||
command -v multipath && command -v multipathd || return $?
|
||||
|
@ -16,6 +16,12 @@ test_append_files() {
|
||||
# the QEMU test, as nspawn refuses the invalid machine ID with -EUCLEAN
|
||||
printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >"$workspace/etc/machine-id"
|
||||
fi
|
||||
|
||||
if host_has_btrfs && host_has_mdadm; then
|
||||
install_btrfs
|
||||
install_mdadm
|
||||
generate_module_dependencies
|
||||
fi
|
||||
}
|
||||
|
||||
do_test "$@"
|
||||
|
@ -1198,6 +1198,11 @@ install_lvm() {
|
||||
mkdir -p "${initdir:?}/etc/lvm"
|
||||
}
|
||||
|
||||
host_has_btrfs() (
|
||||
set -e
|
||||
modprobe -nv btrfs && command -v mkfs.btrfs && command -v btrfs || return $?
|
||||
)
|
||||
|
||||
install_btrfs() {
|
||||
instmods btrfs
|
||||
# Not all utilities provided by btrfs-progs are listed here; extend the list
|
||||
@ -1265,6 +1270,11 @@ install_iscsi() {
|
||||
fi
|
||||
}
|
||||
|
||||
host_has_mdadm() (
|
||||
set -e
|
||||
command -v mdadm || return $?
|
||||
)
|
||||
|
||||
install_mdadm() {
|
||||
local unit
|
||||
local mdadm_units=(
|
||||
@ -1278,6 +1288,7 @@ install_mdadm() {
|
||||
system-shutdown/mdadm.shutdown
|
||||
)
|
||||
|
||||
instmods "=md"
|
||||
image_install mdadm mdmon
|
||||
inst_rules 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules 69-md-clustered-confirm-device.rules
|
||||
# Fedora/CentOS/RHEL ships this rule file
|
||||
@ -1286,6 +1297,10 @@ install_mdadm() {
|
||||
for unit in "${mdadm_units[@]}"; do
|
||||
image_install "${ROOTLIBDIR:?}/$unit"
|
||||
done
|
||||
|
||||
# Disable the mdmonitor service, since it fails if there's no valid email address
|
||||
# configured in /etc/mdadm.conf, which just unnecessarily pollutes the logs
|
||||
"${SYSTEMCTL:?}" mask --root "${initdir:?}" mdmonitor.service || :
|
||||
}
|
||||
|
||||
install_compiled_systemd() {
|
||||
@ -1597,6 +1612,9 @@ create_empty_image() {
|
||||
# Partition sizes are in MiBs
|
||||
local root_size=768
|
||||
local data_size=100
|
||||
local esp_size=128
|
||||
local boot_size=128
|
||||
local total=
|
||||
if ! get_bool "$NO_BUILD"; then
|
||||
if meson configure "${BUILD_DIR:?}" | grep 'static-lib\|standalone-binaries' | awk '{ print $2 }' | grep -q 'true'; then
|
||||
root_size=$((root_size + 200))
|
||||
@ -1619,28 +1637,44 @@ create_empty_image() {
|
||||
data_size=$((data_size + IMAGE_ADDITIONAL_DATA_SIZE))
|
||||
fi
|
||||
|
||||
echo "Setting up ${IMAGE_PUBLIC:?} (${root_size} MB)"
|
||||
total=$((root_size + data_size + esp_size + boot_size))
|
||||
|
||||
echo "Setting up ${IMAGE_PUBLIC:?} (${total} MB)"
|
||||
rm -f "${IMAGE_PRIVATE:?}" "$IMAGE_PUBLIC"
|
||||
|
||||
# Create the blank file to use as a root filesystem
|
||||
truncate -s "${root_size}M" "$IMAGE_PUBLIC"
|
||||
truncate -s "${total}M" "$IMAGE_PUBLIC"
|
||||
|
||||
LOOPDEV="$(losetup --show -P -f "$IMAGE_PUBLIC")"
|
||||
[[ -b "$LOOPDEV" ]] || return 1
|
||||
# Create two partitions - a root one and a data one (utilized by some tests)
|
||||
sfdisk "$LOOPDEV" <<EOF
|
||||
label: gpt
|
||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 name=root size=$((root_size - data_size))M bootable
|
||||
type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B name=esp size=${esp_size}M
|
||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 name=root size=${root_size}M bootable
|
||||
type=BC13C2FF-59E6-4262-A352-B275FD6F7172 name=boot size=${boot_size}M
|
||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 name=data
|
||||
EOF
|
||||
|
||||
udevadm settle
|
||||
|
||||
if ! mkfs -t vfat "${LOOPDEV}p1"; then
|
||||
dfatal "Failed to mkfs -t vfat ${LOOPDEV}p1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local label=(-L systemd_boot)
|
||||
# mkfs.reiserfs doesn't know -L. so, use --label instead
|
||||
[[ "$FSTYPE" == "reiserfs" ]] && label=(--label systemd_boot)
|
||||
if ! mkfs -t "${FSTYPE}" "${label[@]}" "${LOOPDEV}p1" -q; then
|
||||
dfatal "Failed to mkfs -t ${FSTYPE}"
|
||||
if ! mkfs -t "${FSTYPE}" "${label[@]}" "${LOOPDEV}p2" -q; then
|
||||
dfatal "Failed to mkfs -t ${FSTYPE} ${label[*]} ${LOOPDEV}p2 -q"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local label=(-L xbootldr)
|
||||
[[ "$FSTYPE" == "reiserfs" ]] && label=(--label xbootldr)
|
||||
if ! mkfs -t "${FSTYPE}" "${label[@]}" "${LOOPDEV}p3" -q; then
|
||||
dfatal "Failed to mkfs -t ${FSTYPE} ${label[*]} ${LOOPDEV}p3 -q"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
@ -1656,7 +1690,7 @@ mount_initdir() {
|
||||
|
||||
if ! mountpoint -q "${initdir:?}"; then
|
||||
mkdir -p "$initdir"
|
||||
mount "${LOOPDEV}p1" "$initdir"
|
||||
mount "${LOOPDEV}p2" "$initdir"
|
||||
TEST_SETUP_CLEANUP_ROOTDIR=1
|
||||
fi
|
||||
}
|
||||
|
@ -1159,10 +1159,6 @@ testcase_mdadm_lvm() {
|
||||
helper_check_device_units
|
||||
}
|
||||
|
||||
# Disable the mdmonitor service, since it fails if there's no valid email address
|
||||
# configured in /etc/mdadm.conf, which just unnecessarily pollutes the logs
|
||||
systemctl list-unit-files mdmonitor.service >/dev/null && systemctl mask --runtime mdmonitor.service
|
||||
|
||||
udevadm settle
|
||||
udevadm control --log-level debug
|
||||
lsblk -a
|
||||
|
261
test/units/testsuite-74.bootctl.sh
Executable file
261
test/units/testsuite-74.bootctl.sh
Executable file
@ -0,0 +1,261 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
if systemd-detect-virt --quiet --container; then
|
||||
echo "running on container, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v bootctl >/dev/null; then
|
||||
echo "bootctl not found, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# shellcheck source=test/units/util.sh
|
||||
. "$(dirname "$0")"/util.sh
|
||||
|
||||
# shellcheck source=test/units/test-control.sh
|
||||
. "$(dirname "$0")"/test-control.sh
|
||||
|
||||
basic_tests() {
|
||||
bootctl "$@" --help
|
||||
bootctl "$@" --version
|
||||
|
||||
bootctl "$@" install --make-entry-directory=yes
|
||||
bootctl "$@" remove --make-entry-directory=yes
|
||||
|
||||
bootctl "$@" install --all-architectures
|
||||
bootctl "$@" remove --all-architectures
|
||||
|
||||
bootctl "$@" install --make-entry-directory=yes --all-architectures
|
||||
bootctl "$@" remove --make-entry-directory=yes --all-architectures
|
||||
|
||||
bootctl "$@" install
|
||||
(! bootctl "$@" update)
|
||||
bootctl "$@" update --graceful
|
||||
|
||||
bootctl "$@" is-installed
|
||||
bootctl "$@" is-installed --graceful
|
||||
bootctl "$@" random-seed
|
||||
|
||||
bootctl "$@"
|
||||
bootctl "$@" status
|
||||
bootctl "$@" status --quiet
|
||||
bootctl "$@" list
|
||||
bootctl "$@" list --quiet
|
||||
bootctl "$@" list --json=short
|
||||
bootctl "$@" list --json=pretty
|
||||
|
||||
bootctl "$@" remove
|
||||
(! bootctl "$@" is-installed)
|
||||
(! bootctl "$@" is-installed --graceful)
|
||||
}
|
||||
|
||||
testcase_bootctl_basic() {
|
||||
assert_eq "$(bootctl --print-esp-path)" "/efi"
|
||||
assert_eq "$(bootctl --print-boot-path)" "/boot"
|
||||
bootctl --print-root-device
|
||||
|
||||
basic_tests
|
||||
}
|
||||
|
||||
cleanup_image() (
|
||||
set +e
|
||||
|
||||
if [[ -z "${IMAGE_DIR:-}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
umount "${IMAGE_DIR}/root"
|
||||
|
||||
if [[ -n "${LOOPDEV:-}" ]]; then
|
||||
losetup -d "${LOOPDEV}"
|
||||
unset LOOPDEV
|
||||
fi
|
||||
|
||||
udevadm settle
|
||||
|
||||
rm -rf "${IMAGE_DIR}"
|
||||
unset IMAGE_DIR
|
||||
|
||||
return 0
|
||||
)
|
||||
|
||||
testcase_bootctl_image() {
|
||||
IMAGE_DIR="$(mktemp --directory /tmp/test-bootctl.XXXXXXXXXX)"
|
||||
trap cleanup_image RETURN
|
||||
|
||||
truncate -s 256m "${IMAGE_DIR}/image"
|
||||
|
||||
cat >"${IMAGE_DIR}/partscript" <<EOF
|
||||
label: gpt
|
||||
type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B name=esp size=64M
|
||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 name=root size=64M bootable
|
||||
type=BC13C2FF-59E6-4262-A352-B275FD6F7172 name=boot
|
||||
EOF
|
||||
|
||||
LOOPDEV="$(losetup --show -P -f "${IMAGE_DIR}/image")"
|
||||
sfdisk "$LOOPDEV" <"${IMAGE_DIR}/partscript"
|
||||
|
||||
udevadm settle
|
||||
|
||||
mkfs.vfat -n esp "${LOOPDEV}p1"
|
||||
mkfs.ext4 -L root "${LOOPDEV}p2"
|
||||
mkfs.ext4 -L boot "${LOOPDEV}p3"
|
||||
|
||||
mkdir -p "${IMAGE_DIR}/root"
|
||||
mount -t ext4 "${LOOPDEV}p2" "${IMAGE_DIR}/root"
|
||||
|
||||
mkdir -p "${IMAGE_DIR}/root/efi"
|
||||
mkdir -p "${IMAGE_DIR}/root/boot"
|
||||
mkdir -p "${IMAGE_DIR}/root/etc"
|
||||
mkdir -p "${IMAGE_DIR}/root/usr/lib"
|
||||
if [[ -f /usr/lib/os-release ]]; then
|
||||
cp /usr/lib/os-release "${IMAGE_DIR}/root/usr/lib/."
|
||||
ln -s ../usr/lib/os-release "${IMAGE_DIR}/root/etc/os-release"
|
||||
else
|
||||
cp -a /etc/os-release "${IMAGE_DIR}/root/etc/."
|
||||
fi
|
||||
|
||||
umount "${IMAGE_DIR}/root"
|
||||
|
||||
assert_eq "$(bootctl --image "${IMAGE_DIR}/image" --print-esp-path)" "/run/systemd/mount-rootfs/efi"
|
||||
assert_eq "$(bootctl --image "${IMAGE_DIR}/image" --print-esp-path --esp-path=/efi)" "/run/systemd/mount-rootfs/efi"
|
||||
assert_eq "$(bootctl --image "${IMAGE_DIR}/image" --print-boot-path)" "/run/systemd/mount-rootfs/boot"
|
||||
assert_eq "$(bootctl --image "${IMAGE_DIR}/image" --print-boot-path --boot-path=/boot)" "/run/systemd/mount-rootfs/boot"
|
||||
|
||||
# FIXME: This provides spurious result.
|
||||
bootctl --image "${IMAGE_DIR}/image" --print-root-device || :
|
||||
|
||||
basic_tests --image "${IMAGE_DIR}/image"
|
||||
}
|
||||
|
||||
cleanup_raid() (
|
||||
set +e
|
||||
|
||||
if [[ -z "${IMAGE_DIR:-}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
systemd-umount "${IMAGE_DIR}/root/efi"
|
||||
systemd-umount "${IMAGE_DIR}/root/boot"
|
||||
systemd-umount "${IMAGE_DIR}/root"
|
||||
|
||||
mdadm --misc --stop /dev/md/raid-esp
|
||||
mdadm --misc --stop /dev/md/raid-root
|
||||
|
||||
if [[ -n "${LOOPDEV1:-}" ]]; then
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV1}p1"
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV1}p2"
|
||||
fi
|
||||
|
||||
if [[ -n "${LOOPDEV2:-}" ]]; then
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV2}p1"
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV2}p2"
|
||||
fi
|
||||
|
||||
udevadm settle
|
||||
|
||||
if [[ -n "${LOOPDEV1:-}" ]]; then
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV1}p1"
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV1}p2"
|
||||
losetup -d "${LOOPDEV1}"
|
||||
unset LOOPDEV1
|
||||
fi
|
||||
|
||||
if [[ -n "${LOOPDEV2:-}" ]]; then
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV2}p1"
|
||||
mdadm --misc --force --zero-superblock "${LOOPDEV2}p2"
|
||||
losetup -d "${LOOPDEV2}"
|
||||
unset LOOPDEV2
|
||||
fi
|
||||
|
||||
udevadm settle
|
||||
|
||||
rm -rf "${IMAGE_DIR}"
|
||||
|
||||
return 0
|
||||
)
|
||||
|
||||
testcase_bootctl_raid() {
|
||||
if ! command -v mdadm >/dev/null; then
|
||||
echo "mdadm not found, skipping."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! command -v mkfs.btrfs >/dev/null; then
|
||||
echo "mkfs.btrfs not found, skipping."
|
||||
return 0
|
||||
fi
|
||||
|
||||
IMAGE_DIR="$(mktemp --directory /tmp/test-bootctl.XXXXXXXXXX)"
|
||||
trap cleanup_raid RETURN
|
||||
|
||||
truncate -s 256m "${IMAGE_DIR}/image1"
|
||||
truncate -s 256m "${IMAGE_DIR}/image2"
|
||||
|
||||
cat >"${IMAGE_DIR}/partscript" <<EOF
|
||||
label: gpt
|
||||
type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B name=esp size=64M
|
||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 name=root size=64M bootable
|
||||
type=BC13C2FF-59E6-4262-A352-B275FD6F7172 name=boot
|
||||
EOF
|
||||
|
||||
LOOPDEV1="$(losetup --show -P -f "${IMAGE_DIR}/image1")"
|
||||
LOOPDEV2="$(losetup --show -P -f "${IMAGE_DIR}/image2")"
|
||||
sfdisk "$LOOPDEV1" <"${IMAGE_DIR}/partscript"
|
||||
sfdisk "$LOOPDEV2" <"${IMAGE_DIR}/partscript"
|
||||
|
||||
udevadm settle
|
||||
|
||||
echo y | mdadm --create /dev/md/raid-esp --name "raid-esp" "${LOOPDEV1}p1" "${LOOPDEV2}p1" -v -f --level=1 --raid-devices=2
|
||||
mkfs.vfat /dev/md/raid-esp
|
||||
echo y | mdadm --create /dev/md/raid-root --name "raid-root" "${LOOPDEV1}p2" "${LOOPDEV2}p2" -v -f --level=1 --raid-devices=2
|
||||
mkfs.ext4 /dev/md/raid-root
|
||||
mkfs.btrfs -f -M -d raid1 -m raid1 -L "raid-boot" "${LOOPDEV1}p3" "${LOOPDEV2}p3"
|
||||
|
||||
mkdir -p "${IMAGE_DIR}/root"
|
||||
mount -t ext4 /dev/md/raid-root "${IMAGE_DIR}/root"
|
||||
mkdir -p "${IMAGE_DIR}/root/efi"
|
||||
mount -t vfat /dev/md/raid-esp "${IMAGE_DIR}/root/efi"
|
||||
mkdir -p "${IMAGE_DIR}/root/boot"
|
||||
mount -t btrfs "${LOOPDEV1}p3" "${IMAGE_DIR}/root/boot"
|
||||
|
||||
mkdir -p "${IMAGE_DIR}/root/etc"
|
||||
mkdir -p "${IMAGE_DIR}/root/usr/lib"
|
||||
if [[ -f /usr/lib/os-release ]]; then
|
||||
cp /usr/lib/os-release "${IMAGE_DIR}/root/usr/lib/."
|
||||
ln -s ../usr/lib/os-release "${IMAGE_DIR}/root/etc/os-release"
|
||||
else
|
||||
cp -a /etc/os-release "${IMAGE_DIR}/root/etc/."
|
||||
fi
|
||||
|
||||
# find_esp() does not support md RAID partition.
|
||||
(! bootctl --root "${IMAGE_DIR}/root" --print-esp-path)
|
||||
(! bootctl --root "${IMAGE_DIR}/root" --print-esp-path --esp-path=/efi)
|
||||
|
||||
# If the verification is relaxed, it accepts md RAID partition.
|
||||
assert_eq "$(SYSTEMD_RELAX_ESP_CHECKS=yes bootctl --root "${IMAGE_DIR}/root" --print-esp-path)" "${IMAGE_DIR}/root/efi"
|
||||
assert_eq "$(SYSTEMD_RELAX_ESP_CHECKS=yes bootctl --root "${IMAGE_DIR}/root" --print-esp-path --esp-path=/efi)" "${IMAGE_DIR}/root/efi"
|
||||
|
||||
# find_xbootldr() does not support btrfs RAID, and bootctl tries to fall back to use ESP.
|
||||
# (but as in the above, the ESP verification is also failed in this case).
|
||||
(! bootctl --root "${IMAGE_DIR}/root" --print-boot-path)
|
||||
(! bootctl --root "${IMAGE_DIR}/root" --print-boot-path --boot-path=/boot)
|
||||
|
||||
# If the verification for ESP is relaxed, bootctl falls back to use ESP.
|
||||
assert_eq "$(SYSTEMD_RELAX_ESP_CHECKS=yes bootctl --root "${IMAGE_DIR}/root" --print-boot-path)" "${IMAGE_DIR}/root/efi"
|
||||
|
||||
# If the verification is relaxed, it accepts the xbootldr partition.
|
||||
assert_eq "$(SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes bootctl --root "${IMAGE_DIR}/root" --print-boot-path)" "${IMAGE_DIR}/root/boot"
|
||||
assert_eq "$(SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes bootctl --root "${IMAGE_DIR}/root" --print-boot-path --boot-path=/boot)" "${IMAGE_DIR}/root/boot"
|
||||
|
||||
# FIXME: This provides spurious result.
|
||||
bootctl --root "${IMAGE_DIR}/root" --print-root-device || :
|
||||
|
||||
SYSTEMD_RELAX_ESP_CHECKS=yes SYSTEMD_RELAX_XBOOTLDR_CHECKS=yes basic_tests --root "${IMAGE_DIR}/root"
|
||||
}
|
||||
|
||||
run_testcases
|
Loading…
x
Reference in New Issue
Block a user