From 777e70cce595da628e0c2b9870e5ecd6efe4e106 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Fri, 21 Jun 2024 15:00:41 -0400 Subject: [PATCH] growfs: workaround sfdisk + LUKS incompatibility on 512e disks On 512e disks, `sfdisk` (which is used by `growpart`) will end up growing the rootfs to a size not aligned to a 4K boundary. This is mostly fine because, well, the drive claims to be 512b-compatible. Issues arise however if one wants to also put LUKS on top: cryptsetup, trying to optimize performance, wants to set the sector size of the LUKS device to that of the physical value, which is 4K. But if the partition range itself isn't 4K-aligned, it will choke. Ideally, this should be fixed in sfdisk: https://github.com/util-linux/util-linux/issues/2140 (Though cryptsetup could also learn to align the mapped area itself). Anyway, for now work aorund this by manually checking if the size of the partition is a multiple of 4k. If not, and the physical sector size is 4k, then trim off the edge of the partition to make it so. Note the partition start is always going to be aligned (they're 1M-aligned). Closes: https://github.com/coreos/fedora-coreos-tracker/issues/1384 Closes: https://issues.redhat.com/browse/OCPBUGS-35410 See also: https://gitlab.com/cryptsetup/cryptsetup/-/issues/585 (cherry picked from commit 067e1f767de6f308d08b5ed0b3560f2c185e6c91) --- .../ignition-ostree-growfs.sh | 12 +++++++ .../40ignition-ostree/module-setup.sh | 1 + .../root-reprovision/luks/512e/config.ign | 1 + tests/kola/root-reprovision/luks/512e/data | 1 + tests/kola/root-reprovision/luks/512e/test.sh | 36 +++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 120000 tests/kola/root-reprovision/luks/512e/config.ign create mode 120000 tests/kola/root-reprovision/luks/512e/data create mode 100755 tests/kola/root-reprovision/luks/512e/test.sh 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 4a302ff607..638785449a 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 @@ -111,6 +111,18 @@ while true; do # XXX: ideally this'd be idempotent and we wouldn't `|| :` growpart "${PKNAME}" "${partnum}" || : fi + # If this is a 512e disk, then ensure the partition end is 4K + # aligned to be compatible with LUKS. If it's a 4Kn disk, `size` + # necessarily must be 4K aligned (note the sysfs value is always + # reported in 512b sizes). We should be able to drop this once + # https://github.com/util-linux/util-linux/issues/2140 is fixed. + size=$(cat "/sys/dev/block/${MAJMIN}/size") + phy_sec=$(blockdev --getpbsz "${PKNAME}") + if [ "$((size % 8))" != 0 ] && [ "${phy_sec:-}" = 4096 ]; then + size=$(((size >> 3) << 3)) # round down to nearest 4K boundary + echo ", ${size}" | sfdisk --no-reread --force -N "${partnum}" "${PKNAME}" + partx --update --nr "${partnum}" "${PKNAME}" + fi ;; crypt) # XXX: yuck... we need to expose this sanely in clevis 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 d7fd9b650d..b73f977939 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 @@ -42,6 +42,7 @@ install() { inst_multiple \ basename \ blkid \ + blockdev \ cat \ dirname \ findmnt \ diff --git a/tests/kola/root-reprovision/luks/512e/config.ign b/tests/kola/root-reprovision/luks/512e/config.ign new file mode 120000 index 0000000000..f72ce41f73 --- /dev/null +++ b/tests/kola/root-reprovision/luks/512e/config.ign @@ -0,0 +1 @@ +../config.ign \ No newline at end of file diff --git a/tests/kola/root-reprovision/luks/512e/data b/tests/kola/root-reprovision/luks/512e/data new file mode 120000 index 0000000000..4909e06efb --- /dev/null +++ b/tests/kola/root-reprovision/luks/512e/data @@ -0,0 +1 @@ +../data \ No newline at end of file diff --git a/tests/kola/root-reprovision/luks/512e/test.sh b/tests/kola/root-reprovision/luks/512e/test.sh new file mode 100755 index 0000000000..54e9b9a077 --- /dev/null +++ b/tests/kola/root-reprovision/luks/512e/test.sh @@ -0,0 +1,36 @@ +#!/bin/bash +## kola: +## # This test reprovisions the rootfs. +## tags: "reprovision" +## # This uses additionalDisks, which is QEMU only +## platforms: qemu +## # 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 +## description: Verify that LUKS on a 512e disks works. +## primaryDisk: ":512e" + +set -xeuo pipefail + +# shellcheck disable=SC1091 +. "$KOLA_EXT_DATA/commonlib.sh" + +# sanity-check that it's a 512e disk +phy_sec=$(blockdev --getpbsz /dev/disk/by-id/virtio-primary-disk) +log_sec=$(blockdev --getss /dev/disk/by-id/virtio-primary-disk) +if [ "${phy_sec}" != 4096 ] || [ "${log_sec}" != 512 ]; then + fatal "root device isn't 512e" +fi + +# sanity-check that LUKS chose a 4096 sector size +luks_sec=$(blockdev --getss /dev/mapper/myluksdev) +if [ "${luks_sec}" != 4096 ]; then + fatal "root LUKS device isn't 4k" +fi + +# run the rest of the tests +. $KOLA_EXT_DATA/luks-test.sh