From f39857f393a31163ef13c289f03205c895fdb04b Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 22 Mar 2023 16:37:41 -0400 Subject: [PATCH 1/7] 40ignition-ostree: run ignition-ostree-growfs before sysroot mount Prep for automatic XFS reprovisioning. The only way to know for sure whether the rootfs should be reprovisioned is analyzing it after the filesystem was grown. We could do calculations beforehand, but it'd get complex having to analyze the partition table. Anyway, the partition growing and e.g. LUKS container resizing need to happen before automatic reprovisioning and ignition-ostree-growfs already knows how to do that. --- .../ignition-ostree-growfs.service | 8 ++-- .../ignition-ostree-growfs.sh | 37 ++++++++++++++++--- ...gnition-ostree-transposefs-restore.service | 2 +- .../ignition-ostree-transposefs.sh | 1 + 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service index 0599484824..da47d6660c 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service @@ -4,12 +4,12 @@ DefaultDependencies=false ConditionKernelCommandLine=ostree ConditionPathExists=!/run/ostree-live Before=initrd-root-fs.target -After=sysroot.mount ignition-ostree-mount-firstboot-sysroot.service -# This shouldn't be strictly necessary, but it's cleaner to not have OSTree muck -# around with moving mounts while we're still resizing the filesystem. -Before=ostree-prepare-root.service +Before=sysroot.mount ignition-ostree-mount-firstboot-sysroot.service +After=ignition-ostree-uuid-root.service [Service] Type=oneshot ExecStart=/usr/sbin/ignition-ostree-growfs RemainAfterExit=yes +# So we can transiently mount sysroot +MountFlags=slave \ No newline at end of file diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh index 161c91165b..ca3de25224 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh @@ -5,17 +5,42 @@ set -euo pipefail # partition, unless it determines that either the rootfs was moved or the # partition was already resized (e.g. via Ignition). +# This is copied from ignition-ostree-transposefs.sh. +# Sometimes, for some reason the by-label symlinks aren't updated. Detect these +# cases, and explicitly `udevadm trigger`. +# See: https://bugzilla.redhat.com/show_bug.cgi?id=1908780 +udev_trigger_on_label_mismatch() { + local label=$1; shift + local expected_dev=$1; shift + local actual_dev + expected_dev=$(realpath "${expected_dev}") + # We `|| :` here because sometimes /dev/disk/by-label/$label is missing. + # We've seen this on Fedora kernels with debug enabled (common in `rawhide`). + # See https://github.com/coreos/fedora-coreos-tracker/issues/1092 + actual_dev=$(realpath "/dev/disk/by-label/$label" || :) + if [ "$actual_dev" != "$expected_dev" ]; then + echo "Expected /dev/disk/by-label/$label to point to $expected_dev, but points to $actual_dev; triggering udev" + udevadm trigger --settle "$expected_dev" + fi +} + +# This is also similar to bits from transposefs.sh. +ignition_cfg=/run/ignition.json +expected_dev=$(jq -r '.storage?.filesystems? // [] | map(select(.label == "root")) | .[0].device // ""' "${ignition_cfg}") +if [ -n "${expected_dev}" ]; then + udev_trigger_on_label_mismatch root "${expected_dev}" +fi + # If root reprovisioning was triggered, this file contains state of the root # partition *before* ignition-disks. saved_partstate=/run/ignition-ostree-rootfs-partstate.sh -# We run after the rootfs is mounted at /sysroot, but before ostree-prepare-root -# moves it to /sysroot/sysroot. +# We run before the rootfs is mounted at /sysroot, but we still need to mount it +# (in a private namespace) since XFS and Btrfs can only do resizing online (EXT4 +# can do either). path=/sysroot - -# The use of tail is to avoid errors from duplicate mounts; -# this shouldn't happen for us but we're being conservative. -src=$(findmnt -nvr -o SOURCE "$path" | tail -n1) +src=/dev/disk/by-label/root +mount "${src}" "${path}" # In the IBM Secure Execution case we use Ignition to grow and reencrypt rootfs # see overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service index 4eca578934..b64858ffd7 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service @@ -4,7 +4,7 @@ DefaultDependencies=false After=ignition-disks.service # Avoid racing with UUID regeneration After=ignition-ostree-uuid-root.service -Before=ignition-ostree-growfs.service +After=ignition-ostree-growfs.service Before=ignition-ostree-mount-firstboot-sysroot.service OnFailure=emergency.target OnFailureJobMode=isolate diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh index 9ec484c88c..2ef083c4d5 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh @@ -54,6 +54,7 @@ mount_verbose() { mount -o "${mode}" "${srcdev}" "${destdir}" } +# A copy of this exists in ignition-ostree-growfs.sh. # Sometimes, for some reason the by-label symlinks aren't updated. Detect these # cases, and explicitly `udevadm trigger`. # See: https://bugzilla.redhat.com/show_bug.cgi?id=1908780 From 9b70797afd3cbfe4be8c776ceef2741959e1c843 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 22 Mar 2023 16:37:42 -0400 Subject: [PATCH 2/7] 40ignition-ostree: factor out zram-related functions No functional change. Prep for future patch. --- .../ignition-ostree-transposefs.sh | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh index 2ef083c4d5..cd563e9897 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh @@ -125,6 +125,41 @@ mount_and_save_filesystem_by_label() { fi } +ensure_zram_dev() { + if test -d "${saved_data}"; then + return 0 + fi + mem_available=$(grep MemAvailable /proc/meminfo | awk '{print $2}') + # Just error out early if we don't even have 1G to work with. This + # commonly happens if you `cosa run` but forget to add `--memory`. That + # way you get a nicer error instead of the spew of EIO errors from `cp`. + # The amount we need is really dependent on a bunch of factors, but just + # ballpark it at 3G. + if [ "${mem_available}" -lt $((1*1024*1024)) ] && [ "${wipes_root}" != 0 ]; then + echo "Root reprovisioning requires at least 3G of RAM" >&2 + exit 1 + fi + modprobe zram num_devices=0 + read dev < /sys/class/zram-control/hot_add + # disksize is set arbitrarily large, as zram is capped by mem_limit + echo 10G > /sys/block/zram"${dev}"/disksize + # Limit zram to 90% of available RAM: we want to be greedy since the + # boot breaks anyway, but we still want to leave room for everything + # else so it hits ENOSPC and doesn't invoke the OOM killer + echo $(( mem_available * 90 / 100 ))K > /sys/block/zram"${dev}"/mem_limit + mkfs.xfs -q /dev/zram"${dev}" + mkdir "${saved_data}" + mount /dev/zram"${dev}" "${saved_data}" + # save the zram device number created for when called to cleanup + echo "${dev}" > "${zram_dev}" +} + +print_zram_mm_stat() { + echo "zram usage:" + read dev < "${zram_dev}" + cat /sys/block/zram"${dev}"/mm_stat +} + # In Secure Execution case user is not allowed to modify partition table check_and_set_secex_config() { if [[ -f /run/coreos/secure-execution ]]; then @@ -163,29 +198,8 @@ case "${1:-}" in echo "Found duplicate or missing ESP, BIOS-BOOT, or PReP labels in config" >&2 exit 1 fi - mem_available=$(grep MemAvailable /proc/meminfo | awk '{print $2}') - # Just error out early if we don't even have 1G to work with. This - # commonly happens if you `cosa run` but forget to add `--memory`. That - # way you get a nicer error instead of the spew of EIO errors from `cp`. - # The amount we need is really dependent on a bunch of factors, but just - # ballpark it at 3G. - if [ "${mem_available}" -lt $((1*1024*1024)) ] && [ "${wipes_root}" != 0 ]; then - echo "Root reprovisioning requires at least 3G of RAM" >&2 - exit 1 - fi - modprobe zram num_devices=0 - read dev < /sys/class/zram-control/hot_add - # disksize is set arbitrarily large, as zram is capped by mem_limit - echo 10G > /sys/block/zram"${dev}"/disksize - # Limit zram to 90% of available RAM: we want to be greedy since the - # boot breaks anyway, but we still want to leave room for everything - # else so it hits ENOSPC and doesn't invoke the OOM killer - echo $(( mem_available * 90 / 100 ))K > /sys/block/zram"${dev}"/mem_limit - mkfs.xfs -q /dev/zram"${dev}" - mkdir "${saved_data}" - mount /dev/zram"${dev}" "${saved_data}" - # save the zram device number created for when called to cleanup - echo "${dev}" > "${zram_dev}" + + ensure_zram_dev if [ "${wipes_root}" != "0" ]; then mkdir "${saved_root}" @@ -234,9 +248,7 @@ case "${1:-}" in echo "Moving PReP partition to RAM..." cat "${prep_part}" > "${saved_prep}/partition" fi - echo "zram usage:" - read dev < "${zram_dev}" - cat /sys/block/zram"${dev}"/mm_stat + print_zram_mm_stat ;; restore) # Mounts happen in a private mount namespace since we're not "offically" mounting From 39f64dc5b3ae5b3bec9beca5d9997406e0e45abc Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 22 Mar 2023 16:37:43 -0400 Subject: [PATCH 3/7] 40ignition-ostree: skip udev hack if Ignition did not reprovision rootfs Currently, this code only executes via Ignition reprovisioning the rootfs, but we're about to add code to reprovision the rootfs outside of that path. In that case, we don't need to query the Ignition config. --- .../40ignition-ostree/ignition-ostree-transposefs.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh index cd563e9897..a7976e2c63 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh @@ -96,8 +96,12 @@ mount_and_restore_filesystem_by_label() { local mountpoint=$1; shift local saved_fs=$1; shift local new_dev - new_dev=$(jq -r "$(query_fslabel "${label}") | .[0].device" "${ignition_cfg}") - udev_trigger_on_label_mismatch "${label}" "${new_dev}" + new_dev=$(jq -r "$(query_fslabel "${label}") | .[0].device // \"\"" "${ignition_cfg}") + # in the autosave-xfs path, it's not driven by the Ignition config so we + # don't expect a new device there + if [ -n "${new_dev}" ]; then + udev_trigger_on_label_mismatch "${label}" "${new_dev}" + fi mount_verbose "/dev/disk/by-label/${label}" "${mountpoint}" rw find "${saved_fs}" -mindepth 1 -maxdepth 1 -exec mv -t "${mountpoint}" {} + } From 3107c60113555dad87a6cb6eb99847ba907fd36a Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 22 Mar 2023 16:37:44 -0400 Subject: [PATCH 4/7] 40ignition-ostree: add autosave-xfs transposefs unit Add a new transposefs unit: `autosave-xfs`. This unit runs after `ignition-disks` and `ignition-ostree-growfs,` but before the `restore` transposefs unit. If the XFS root was grown, it checks if the allocation group count (agcount) is within a reasonable amount (128 is chosen here). If it isn't, it saves the rootfs and reformats the filesystem. The `restore` unit will then restore it as usual. In the case of in-place reprovisioning like LUKS (i.e. where the partition table isn't modified by the Ignition config), the rootfs is still saved only once. Ideally, instead of adding a new transposefs unit, we would make it part of the initial `save` unit. But at that point, there's no way to tell whether we should autosave without gazing even more deeply into the Ignition config. We also don't want to unconditionally save the rootfs when we may not need it. Closes: https://github.com/coreos/fedora-coreos-tracker/issues/1183 --- .../ignition-ostree-growfs.sh | 3 +- ...on-ostree-transposefs-autosave-xfs.service | 19 +++++++++ .../ignition-ostree-transposefs.sh | 40 +++++++++++++++++++ .../40ignition-ostree/module-setup.sh | 4 +- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh index ca3de25224..862cace7d5 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh @@ -147,5 +147,6 @@ case "${ROOTFS_TYPE}" in btrfs) btrfs filesystem resize max ${path} ;; esac -# this is useful for tests +# The ignition-ostree-transposefs-xfsauto.service unit needs to know if we +# actually run. This is also useful for tests. touch /run/ignition-ostree-growfs.stamp diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service new file mode 100644 index 0000000000..b914e98c72 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service @@ -0,0 +1,19 @@ +[Unit] +Description=Ignition OSTree: Autosave XFS Rootfs Partition +DefaultDependencies=false +After=ignition-disks.service +# Avoid racing with UUID regeneration +After=ignition-ostree-uuid-root.service +After=ignition-ostree-growfs.service +Before=ignition-ostree-transposefs-restore.service +OnFailure=emergency.target +OnFailureJobMode=isolate + +ConditionKernelCommandLine=ostree +# only run if ignition-ostree-growfs ran since that's when pathological cases occur +ConditionPathExists=/run/ignition-ostree-growfs.stamp + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/libexec/ignition-ostree-transposefs autosave-xfs diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh index a7976e2c63..244a6a5bc2 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh @@ -129,6 +129,29 @@ mount_and_save_filesystem_by_label() { fi } +# This implements https://github.com/coreos/fedora-coreos-tracker/issues/1183. +should_autosave_rootfs() { + local fstype + fstype=$(lsblk -no FSTYPE "${root_part}") + if [ "$fstype" != xfs ]; then + echo "Filesystem is not XFS (found $fstype); skipping" >&2 + echo 0 + return + fi + local agcount + eval $(xfs_info "${root_part}" | grep -o 'agcount=[0-9]*') + # Semi-arbitrarily chosen: this is roughly ~64G currently (based on initial + # ag sizing at build time) which seems like a good rootfs size at which to + # discriminate between "throwaway/short-lived systems" and "long-running + # workload systems". It's not like XFS performance is way worse at 128. + if [ "$agcount" -lt 128 ]; then + echo "Filesystem agcount is $agcount; skipping" >&2 + echo 0 + return + fi + echo 1 +} + ensure_zram_dev() { if test -d "${saved_data}"; then return 0 @@ -221,6 +244,23 @@ case "${1:-}" in mkdir "${saved_prep}" fi ;; + autosave-xfs) + should_autosave=$(should_autosave_rootfs) + if [ "${should_autosave}" = "1" ]; then + wipes_root=1 + ensure_zram_dev + # in the in-place reprovisioning case, the rootfs was already saved + if [ ! -d "${saved_root}" ]; then + mkdir "${saved_root}" + echo "Moving rootfs to RAM..." + mount_and_save_filesystem_by_label root "${saved_root}" + print_zram_mm_stat + fi + mkfs.xfs "${root_part}" -L root -f + # for tests + touch /run/ignition-ostree-autosaved-xfs.stamp + fi + ;; save) # Mounts happen in a private mount namespace since we're not "offically" mounting if [ -d "${saved_root}" ]; then diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh index d0a4c89a9b..f8450b38c0 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh @@ -28,6 +28,8 @@ install() { systemd-sysusers \ systemd-tmpfiles \ sort \ + xfs_info \ + xfs_spaceman \ uniq if [[ $(uname -m) = s390x ]]; then @@ -81,7 +83,7 @@ install() { inst_multiple jq chattr inst_script "$moddir/ignition-ostree-transposefs.sh" "/usr/libexec/ignition-ostree-transposefs" - for x in detect save restore; do + for x in detect save autosave-xfs restore; do install_ignition_unit ignition-ostree-transposefs-${x}.service done From 298a03e6d982ab21dba09f533b0310c873656eda Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 22 Mar 2023 16:37:45 -0400 Subject: [PATCH 5/7] tests/kola: add non-exclusive check for growfs We weren't checking anywhere in the non-reprovisioning case that we grow the root filesystem on first boot. Add a trivial test for this. --- tests/kola/disks/growfs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 tests/kola/disks/growfs diff --git a/tests/kola/disks/growfs b/tests/kola/disks/growfs new file mode 100755 index 0000000000..a2b421a2ef --- /dev/null +++ b/tests/kola/disks/growfs @@ -0,0 +1,15 @@ +#!/bin/bash +## kola: +## exclusive: false + +# This test verifies that the rootfs is automatically grown on first boot in the +# default case. + +set -xeuo pipefail + +. $KOLA_EXT_DATA/commonlib.sh + +if [ ! -f /run/ignition-ostree-growfs.stamp ]; then + fatal "rootfs was not grown on first boot" +fi +ok "rootfs grown on first boot" From 5a5edfeec529efdd83e5dcd0a1b328f4e4fb0c7c Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 22 Mar 2023 16:37:46 -0400 Subject: [PATCH 6/7] tests/kola: move LUKS checks to shared file Prep for adding another LUKS where we want the same checks. --- .../root-reprovision/luks/data/luks-test.sh | 59 +++++++++++++++++++ tests/kola/root-reprovision/luks/test.sh | 56 +----------------- 2 files changed, 61 insertions(+), 54 deletions(-) create mode 100755 tests/kola/root-reprovision/luks/data/luks-test.sh diff --git a/tests/kola/root-reprovision/luks/data/luks-test.sh b/tests/kola/root-reprovision/luks/data/luks-test.sh new file mode 100755 index 0000000000..fe4b0dc3fe --- /dev/null +++ b/tests/kola/root-reprovision/luks/data/luks-test.sh @@ -0,0 +1,59 @@ +# This file is sourced by both `ext.config.root-reprovision.luks` +# and `ext.config.root-reprovision.luks.autosave-xfs`. + +. $KOLA_EXT_DATA/commonlib.sh + +srcdev=$(findmnt -nvr / -o SOURCE) +[[ ${srcdev} == /dev/mapper/myluksdev ]] + +blktype=$(lsblk -o TYPE "${srcdev}" --noheadings) +[[ ${blktype} == crypt ]] + +fstype=$(findmnt -nvr / -o FSTYPE) +[[ ${fstype} == xfs ]] +ok "source is XFS on LUKS device" + +rootflags=$(findmnt /sysroot -no OPTIONS) +if ! grep prjquota <<< "${rootflags}"; then + fatal "missing prjquota in root mount flags: ${rootflags}" +fi +ok "root mounted with prjquota" + +table=$(dmsetup table myluksdev) +if ! grep -q allow_discards <<< "${table}"; then + fatal "missing allow_discards in root DM table: ${table}" +fi +if ! grep -q no_read_workqueue <<< "${table}"; then + fatal "missing no_read_workqueue in root DM table: ${table}" +fi +ok "discard and custom option enabled for root LUKS" + +# 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 + if [ ! -e /run/ignition-ostree-growfs.stamp ]; then + fatal "ignition-ostree-growfs did not run" + fi + + # reboot once to sanity-check we can find root on second boot + /tmp/autopkgtest-reboot rebooted + ;; + + rebooted) + 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 diff --git a/tests/kola/root-reprovision/luks/test.sh b/tests/kola/root-reprovision/luks/test.sh index 8ec72f6bb8..ff3d283fa1 100755 --- a/tests/kola/root-reprovision/luks/test.sh +++ b/tests/kola/root-reprovision/luks/test.sh @@ -14,57 +14,5 @@ set -xeuo pipefail . $KOLA_EXT_DATA/commonlib.sh -srcdev=$(findmnt -nvr / -o SOURCE) -[[ ${srcdev} == /dev/mapper/myluksdev ]] - -blktype=$(lsblk -o TYPE "${srcdev}" --noheadings) -[[ ${blktype} == crypt ]] - -fstype=$(findmnt -nvr / -o FSTYPE) -[[ ${fstype} == xfs ]] -ok "source is XFS on LUKS device" - -rootflags=$(findmnt /sysroot -no OPTIONS) -if ! grep prjquota <<< "${rootflags}"; then - fatal "missing prjquota in root mount flags: ${rootflags}" -fi -ok "root mounted with prjquota" - -table=$(dmsetup table myluksdev) -if ! grep -q allow_discards <<< "${table}"; then - fatal "missing allow_discards in root DM table: ${table}" -fi -if ! grep -q no_read_workqueue <<< "${table}"; then - fatal "missing no_read_workqueue in root DM table: ${table}" -fi -ok "discard and custom option enabled for root LUKS" - -# 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 - if [ ! -e /run/ignition-ostree-growfs.stamp ]; then - fatal "ignition-ostree-growfs did not run" - fi - - # reboot once to sanity-check we can find root on second boot - /tmp/autopkgtest-reboot rebooted - ;; - - rebooted) - 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 +# run the tests +. $KOLA_EXT_DATA/luks-test.sh From 2a3c4aaf27d3902b7924209d81238184aab36947 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 22 Mar 2023 16:37:48 -0400 Subject: [PATCH 7/7] tests/kola: add autosave-xfs tests Add a new `ext.config.root-reprovision.autosave-xfs` test that checks that the logic kicks in on a large enough disk. Add a similar `ext.config.root-reprovision.luks.autosave-xfs` for the LUKS version of this. Sanity-check in other reprovisioning tests that autosave-xfs didn't kick in. --- tests/kola/disks/growfs | 7 +++- .../autosave-xfs/data/commonlib.sh | 1 + .../root-reprovision/autosave-xfs/test.sh | 26 ++++++++++++++ tests/kola/root-reprovision/linear/test.sh | 5 +++ .../luks/autosave-xfs/config.ign | 1 + .../root-reprovision/luks/autosave-xfs/data | 1 + .../luks/autosave-xfs/test.sh | 34 +++++++++++++++++++ tests/kola/root-reprovision/luks/test.sh | 10 +++++- tests/kola/root-reprovision/raid1/test.sh | 5 +++ 9 files changed, 88 insertions(+), 2 deletions(-) create mode 120000 tests/kola/root-reprovision/autosave-xfs/data/commonlib.sh create mode 100755 tests/kola/root-reprovision/autosave-xfs/test.sh create mode 120000 tests/kola/root-reprovision/luks/autosave-xfs/config.ign create mode 120000 tests/kola/root-reprovision/luks/autosave-xfs/data create mode 100755 tests/kola/root-reprovision/luks/autosave-xfs/test.sh diff --git a/tests/kola/disks/growfs b/tests/kola/disks/growfs index a2b421a2ef..a423837112 100755 --- a/tests/kola/disks/growfs +++ b/tests/kola/disks/growfs @@ -3,7 +3,7 @@ ## exclusive: false # This test verifies that the rootfs is automatically grown on first boot in the -# default case. +# default case and that the autosave-xfs logic didn't kick in. set -xeuo pipefail @@ -13,3 +13,8 @@ if [ ! -f /run/ignition-ostree-growfs.stamp ]; then fatal "rootfs was not grown on first boot" fi ok "rootfs grown on first boot" + +if [ -f /run/ignition-ostree-autosaved-xfs.stamp ]; then + fatal "unexpected autosaved XFS" +fi +ok "rootfs wasn't automatically reprovisioned" diff --git a/tests/kola/root-reprovision/autosave-xfs/data/commonlib.sh b/tests/kola/root-reprovision/autosave-xfs/data/commonlib.sh new file mode 120000 index 0000000000..b8dcbdca1a --- /dev/null +++ b/tests/kola/root-reprovision/autosave-xfs/data/commonlib.sh @@ -0,0 +1 @@ +../../../data/commonlib.sh \ No newline at end of file diff --git a/tests/kola/root-reprovision/autosave-xfs/test.sh b/tests/kola/root-reprovision/autosave-xfs/test.sh new file mode 100755 index 0000000000..b50ca2f0a1 --- /dev/null +++ b/tests/kola/root-reprovision/autosave-xfs/test.sh @@ -0,0 +1,26 @@ +#!/bin/bash +## kola: +## # This test reprovisions the rootfs automatically. +## tags: "platform-independent reprovision" +## # Trigger automatic XFS reprovisioning +## minDisk: 64 +## # Root reprovisioning requires at least 4GiB of memory. +## minMemory: 4096 +## # This test includes a lot of disk I/O and needs a higher +## # timeout value than the default. +## timeoutMin: 15 + +set -xeuo pipefail + +. $KOLA_EXT_DATA/commonlib.sh + +if [ ! -f /run/ignition-ostree-autosaved-xfs.stamp ]; then + fatal "expected autosaved XFS" +fi +ok "autosaved XFS on large disk" + +eval $(xfs_info / | grep -o 'agcount=[0-9]*') +if [ "$agcount" -gt 4 ]; then + fatal "expected agcount of at most 4, got ${agcount}" +fi +ok "low agcount on large disk" diff --git a/tests/kola/root-reprovision/linear/test.sh b/tests/kola/root-reprovision/linear/test.sh index 3aaa6c865b..83bad0d232 100755 --- a/tests/kola/root-reprovision/linear/test.sh +++ b/tests/kola/root-reprovision/linear/test.sh @@ -39,6 +39,11 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in fatal "ignition-ostree-growfs ran" fi + # check that autosave-xfs didn't run + if [ -e /run/ignition-ostree-autosaved-xfs.stamp ]; then + fatal "unexpected autosaved XFS" + fi + # reboot once to sanity-check we can find root on second boot /tmp/autopkgtest-reboot rebooted ;; diff --git a/tests/kola/root-reprovision/luks/autosave-xfs/config.ign b/tests/kola/root-reprovision/luks/autosave-xfs/config.ign new file mode 120000 index 0000000000..f72ce41f73 --- /dev/null +++ b/tests/kola/root-reprovision/luks/autosave-xfs/config.ign @@ -0,0 +1 @@ +../config.ign \ No newline at end of file diff --git a/tests/kola/root-reprovision/luks/autosave-xfs/data b/tests/kola/root-reprovision/luks/autosave-xfs/data new file mode 120000 index 0000000000..4909e06efb --- /dev/null +++ b/tests/kola/root-reprovision/luks/autosave-xfs/data @@ -0,0 +1 @@ +../data \ No newline at end of file diff --git a/tests/kola/root-reprovision/luks/autosave-xfs/test.sh b/tests/kola/root-reprovision/luks/autosave-xfs/test.sh new file mode 100755 index 0000000000..6625fad734 --- /dev/null +++ b/tests/kola/root-reprovision/luks/autosave-xfs/test.sh @@ -0,0 +1,34 @@ +#!/bin/bash +## kola: +## # This test reprovisions the rootfs. +## tags: "platform-independent reprovision" +## # Root reprovisioning requires at least 4GiB of memory. +## minMemory: 4096 +## # A TPM backend device is not available on s390x to suport TPM. +## architectures: "!s390x" +## # This test includes a lot of disk I/O and needs a higher +## # timeout value than the default. +## timeoutMin: 15 +## # Trigger automatic XFS reprovisioning +## minDisk: 64 + +set -xeuo pipefail + +. $KOLA_EXT_DATA/commonlib.sh + +# check that we ran automatic XFS reprovisioning +if [ -z "${AUTOPKGTEST_REBOOT_MARK:-}" ]; then + if [ ! -f /run/ignition-ostree-autosaved-xfs.stamp ]; then + fatal "expected autosaved XFS" + fi + ok "autosaved XFS on large disk" + + eval $(xfs_info / | grep -o 'agcount=[0-9]*') + if [ "$agcount" -gt 4 ]; then + fatal "expected agcount of at most 4, got ${agcount}" + fi + ok "low agcount on large disk" +fi + +# run the rest of the tests +. $KOLA_EXT_DATA/luks-test.sh diff --git a/tests/kola/root-reprovision/luks/test.sh b/tests/kola/root-reprovision/luks/test.sh index ff3d283fa1..58fd00ba7d 100755 --- a/tests/kola/root-reprovision/luks/test.sh +++ b/tests/kola/root-reprovision/luks/test.sh @@ -14,5 +14,13 @@ set -xeuo pipefail . $KOLA_EXT_DATA/commonlib.sh -# run the tests +# check that we didn't run automatic XFS reprovisioning +if [ -z "${AUTOPKGTEST_REBOOT_MARK:-}" ]; then + if [ -f /run/ignition-ostree-autosaved-xfs.stamp ]; then + fatal "unexpected autosaved XFS" + fi + ok "no autosaved XFS on large disk" +fi + +# run the rest of the tests . $KOLA_EXT_DATA/luks-test.sh diff --git a/tests/kola/root-reprovision/raid1/test.sh b/tests/kola/root-reprovision/raid1/test.sh index 15c15b3ca1..607c9877b0 100755 --- a/tests/kola/root-reprovision/raid1/test.sh +++ b/tests/kola/root-reprovision/raid1/test.sh @@ -39,6 +39,11 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in fatal "ignition-ostree-growfs ran" fi + # check that autosave-xfs didn't run + if [ -e /run/ignition-ostree-autosaved-xfs.stamp ]; then + fatal "unexpected autosaved XFS" + fi + # reboot once to sanity-check we can find root on second boot /tmp/autopkgtest-reboot rebooted ;;