diff --git a/overlay.d/05core/usr/lib/coreos/generator-lib.sh b/overlay.d/05core/usr/lib/coreos/generator-lib.sh index b133e5ac67..dd19ad813d 100644 --- a/overlay.d/05core/usr/lib/coreos/generator-lib.sh +++ b/overlay.d/05core/usr/lib/coreos/generator-lib.sh @@ -17,3 +17,14 @@ have_karg() { done return 1 } + +karg() { + local name="$1" value="${2:-}" + local cmdline=( $(&2 + exit 1 + fi + rdcore kargs --boot-mount ${bootmnt} --append boot=UUID=${UUID} + # but also put it in /run for the first boot real root mount + mkdir -p /run/coreos + echo "${UUID}" > /run/coreos/bootfs_uuid fi diff --git a/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator index a742ff7751..5724fdcb26 100755 --- a/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator +++ b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator @@ -61,15 +61,50 @@ EOF add_wants "${unit_name}" } +# Copied from +# https://github.com/dracutdevs/dracut/blob/9491e599282d0d6bb12063eddbd192c0d2ce8acf/modules.d/99base/dracut-lib.sh#L586 +# rather than sourcing it. +label_uuid_to_dev() { + local _dev + _dev="${1#block:}" + case "$_dev" in + LABEL=*) + echo "/dev/disk/by-label/$(echo "${_dev#LABEL=}" | sed 's,/,\\x2f,g;s, ,\\x20,g')" + ;; + PARTLABEL=*) + echo "/dev/disk/by-partlabel/$(echo "${_dev#PARTLABEL=}" | sed 's,/,\\x2f,g;s, ,\\x20,g')" + ;; + UUID=*) + echo "/dev/disk/by-uuid/$(echo "${_dev#UUID=}" | tr "[:upper:]" "[:lower:]")" + ;; + PARTUUID=*) + echo "/dev/disk/by-partuuid/$(echo "${_dev#PARTUUID=}" | tr "[:upper:]" "[:lower:]")" + ;; + esac +} + # If the root device is multipath, hook up /boot to use that too, # based on our custom udev rules in 90-coreos-device-mapper.rules # that creates "label found on mpath" links. # Otherwise, use the usual by-label symlink. # See discussion in https://github.com/coreos/fedora-coreos-config/pull/1022 bootdev=/dev/disk/by-label/boot -# TODO add equivalent of getargbool() so we handle rd.multipath=0 -if have_karg rd.multipath; then +bootkarg=$(karg boot) +mpath=$(karg rd.multipath) +if [ -n "${mpath}" ] && [ "${mpath}" != 0 ]; then bootdev=/dev/disk/by-label/dm-mpath-boot +# Newer nodes inject boot=UUID=..., but we support a larger subset of the dracut/fips API +elif [ -n "${bootkarg}" ]; then + # Adapted from https://github.com/dracutdevs/dracut/blob/9491e599282d0d6bb12063eddbd192c0d2ce8acf/modules.d/01fips/fips.sh#L17 + case "$bootkarg" in + LABEL=* | UUID=* | PARTUUID=* | PARTLABEL=*) + bootdev="$(label_uuid_to_dev "$bootkarg")";; + /dev/*) bootdev=$bootkarg;; + *) echo "Unknown boot karg '${bootkarg}'; falling back to ${bootdev}";; + esac +# This is used for the first boot only +elif [ -f /run/coreos/bootfs_uuid ]; then + bootdev=/dev/disk/by-uuid/$(cat /run/coreos/bootfs_uuid) fi # We mount read-only by default mostly to protect diff --git a/tests/kola/reboot/test.sh b/tests/kola/reboot/test.sh new file mode 100755 index 0000000000..06d3e12c03 --- /dev/null +++ b/tests/kola/reboot/test.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -xeuo pipefail +# kola: {"platforms": "qemu"} + +# These are read-only not-necessarily-related checks that verify default system +# configuration both on first and subsequent boots. + +ok() { + echo "ok" "$@" +} + +fatal() { + echo "$@" >&2 + exit 1 +} + +# /var +varsrc=$(findmnt -nvr /var -o SOURCE) +rootsrc=$(findmnt -nvr / -o SOURCE) +[[ $(realpath "$varsrc") == $(realpath "$rootsrc") ]] +ok "/var is backed by rootfs" + +# sanity-check that boot is mounted by UUID +if ! systemctl cat boot.mount | grep -q What=/dev/disk/by-uuid; then + systemctl cat boot.mount + fatal "boot mounted not by UUID" +fi +ok "boot mounted by UUID" + +case "${AUTOPKGTEST_REBOOT_MARK:-}" in + "") + ok "first boot" + /tmp/autopkgtest-reboot rebooted + ;; + + rebooted) + # check for expected default kargs + grep root=UUID= /proc/cmdline + ok "found root karg" + + grep boot=UUID= /proc/cmdline + ok "found boot karg" + + ok "second boot" + ;; + *) fatal "unexpected mark: ${AUTOPKGTEST_REBOOT_MARK}";; +esac diff --git a/tests/kola/root-reprovision/luks/test.sh b/tests/kola/root-reprovision/luks/test.sh index 656b6feee6..86f9622d16 100755 --- a/tests/kola/root-reprovision/luks/test.sh +++ b/tests/kola/root-reprovision/luks/test.sh @@ -27,6 +27,13 @@ if ! grep prjquota <<< "${rootflags}"; then fi ok "root mounted with prjquota" +# while we're here, sanity-check that boot is mounted by UUID +if ! systemctl cat boot.mount | grep -q What=/dev/disk/by-uuid; then + systemctl cat boot.mount + fatal "boot mounted not by UUID" +fi +ok "boot mounted by UUID" + case "${AUTOPKGTEST_REBOOT_MARK:-}" in "") # check that ignition-ostree-growfs ran @@ -42,6 +49,10 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in grep root=UUID= /proc/cmdline grep rd.luks.name= /proc/cmdline ok "found root kargs" + + # while we're here, sanity-check that we have a boot=UUID karg too + grep boot=UUID= /proc/cmdline + ok "found boot karg" ;; *) fatal "unexpected mark: ${AUTOPKGTEST_REBOOT_MARK}";; esac