Skip to content

Commit

Permalink
growfs: workaround sfdisk + LUKS incompatibility on 512e disks
Browse files Browse the repository at this point in the history
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:
util-linux/util-linux#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: coreos/fedora-coreos-tracker#1384
Closes: https://issues.redhat.com/browse/OCPBUGS-35410

See also: https://gitlab.com/cryptsetup/cryptsetup/-/issues/585
  • Loading branch information
jlebon committed Jun 20, 2024
1 parent 2b3e597 commit 01a99da
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ install() {
inst_multiple \
basename \
blkid \
blockdev \
cat \
dirname \
findmnt \
Expand Down
1 change: 1 addition & 0 deletions tests/kola/root-reprovision/luks/512e/config.ign
1 change: 1 addition & 0 deletions tests/kola/root-reprovision/luks/512e/data
36 changes: 36 additions & 0 deletions tests/kola/root-reprovision/luks/512e/test.sh
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 01a99da

Please sign in to comment.