From 287491b9292dd979daebb64a87b0551031bcf607 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Fri, 25 Oct 2024 12:29:39 -0700 Subject: [PATCH] setup: support out of order partitions Ubuntu apparently supplies disk images where the partition order in the partition table is different than the order on disk (e.g. the root partition might be partition 1 in the partition table, but the last one on the disk). These changes support that, as long as the root partition is the last partition on the disk. --- setup/generic/install.sh | 6 ++-- setup/pi/create-backingfiles-partition.sh | 7 ++-- tests/create-backingfiles-partition-test.sh | 37 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/setup/generic/install.sh b/setup/generic/install.sh index 08be974c..7a5f717c 100644 --- a/setup/generic/install.sh +++ b/setup/generic/install.sh @@ -40,7 +40,7 @@ rootdev="/dev/${rootname}" marker="/root/RESIZE_ATTEMPTED" # Check that the root partition is the last one. -lastpart=$(sfdisk -l "$rootdev" | tail -1 | awk '{print $1}') +lastpart=$(sfdisk -q -l "$rootdev" | tail +2 | sort -n -k 2 | tail -1 | awk '{print $1}') # Check if there is sufficient unpartitioned space after the last # partition to create the backingfiles and mutable partitions. @@ -64,7 +64,7 @@ then devsectorsize=$(cat "/sys/block/${rootname}/queue/hw_sector_size") read -r fsblockcount fsblocksize < <(tune2fs -l "${rootpart}" | grep "Block count:\|Block size:" | awk ' {print $2}' FS=: | tr -d ' ' | tr '\n' ' ' | (cat; echo)) fsnumsectors=$((fsblockcount * fsblocksize / devsectorsize)) - partnumsectors=$(sfdisk -l -o Sectors "${rootdev}" | tail -1) + partnumsectors=$(sfdisk -q -l -o Sectors "${rootdev}" | tail +2 | sort -n | tail -1) partnumsectors=$((partnumsectors - 1)); if [ "$partnumsectors" -le "$fsnumsectors" ] then @@ -122,7 +122,7 @@ then # shrink root partition to match root file system size echo "shrinking root partition to match root fs, $fsnumsectors sectors" sleep 3 - rootpartstartsector=$(sfdisk -l -o Start "${rootdev}" | tail -1) + rootpartstartsector=$(sfdisk -q -l -o Start "${rootdev}" | tail +2 | sort -n | tail -1) partnum=${rootpart:0-1} echo "${rootpartstartsector},${fsnumsectors}" | sfdisk --force "${rootdev}" -N "${partnum}" diff --git a/setup/pi/create-backingfiles-partition.sh b/setup/pi/create-backingfiles-partition.sh index d22855af..5df11167 100755 --- a/setup/pi/create-backingfiles-partition.sh +++ b/setup/pi/create-backingfiles-partition.sh @@ -82,7 +82,7 @@ else echo "DATA_DRIVE not set. Proceeding to SD card setup" fi -readonly LAST_PARTITION_DEVICE=$(sfdisk -l "$BOOT_DISK" | tail -1 | awk '{print $1}') +readonly LAST_PARTITION_DEVICE=$(sfdisk -q -l "$BOOT_DISK" | tail -1 | awk '{print $1}') readonly LAST_PART_NUM=${LAST_PARTITION_DEVICE:0-1} readonly SECOND_TO_LAST_PART_NUM=$((LAST_PART_NUM - 1)) readonly SECOND_TO_LAST_PARTITION_DEVICE=${LAST_PARTITION_DEVICE:0:-1}${SECOND_TO_LAST_PART_NUM} @@ -159,13 +159,10 @@ LAST_DISK_SECTOR=$((DISK_SECTORS - 1)) # mutable partition is 100MB at the end of the disk, calculate its start sector FIRST_MUTABLE_SECTOR=$((LAST_DISK_SECTOR-204800+1)) # backingfiles partition sits between the last and mutable partition, calculate its start sector and size -LAST_PART_SECTOR=$(sfdisk -l "${BOOT_DISK}" | grep "${LAST_PARTITION_DEVICE}" | awk '{print $3}') +LAST_PART_SECTOR=$(sfdisk -q -l "${BOOT_DISK}" | tail +2 | sort -n -k 2 | tail -1 | awk '{print $3}') FIRST_BACKINGFILES_SECTOR=$((LAST_PART_SECTOR + 1)) BACKINGFILES_NUM_SECTORS=$((FIRST_MUTABLE_SECTOR - FIRST_BACKINGFILES_SECTOR)) -echo firstbackingfilesmutable $FIRST_BACKINGFILES_SECTOR -echo first mutable $FIRST_MUTABLE_SECTOR - # As a rule of thumb, one gigabyte of /backingfiles space can hold about 36 # recording files. We need enough inodes in /mutable to create symlinks to # the recordings. Leaving enough headroom to account for short recordings, diff --git a/tests/create-backingfiles-partition-test.sh b/tests/create-backingfiles-partition-test.sh index 457c929c..4784c75a 100755 --- a/tests/create-backingfiles-partition-test.sh +++ b/tests/create-backingfiles-partition-test.sh @@ -130,9 +130,40 @@ EOF echo "BOOT_DISK: $BOOT_DISK" } +# image with gpt partition layout and three partitions +# on it already, but with the on-disk order not matching +# the partition table order. +function makeubuntulikeimage { + local img="$1" + truncate -s $((64*1024*1024*1024)) "$img" + + sfdisk -X gpt "$img" << EOF +2560M,3G +12M,500M +512M,2G +EOF + + fdisk -l "$img" + + LOOP=$(sudo losetup --find --partscan --show "$img") + + mkfs.ext4 "${LOOP}p1" &>> "$LOG" + mkfs.vfat "${LOOP}p2" &>> "$LOG" + mkfs.ext4 "${LOOP}p3" &>> "$LOG" + + export BOOT_DISK="$LOOP" + export DATA_DRIVE="" + export CMDLINE_PATH="/dev/null" + export BOOT_DEVICE_PARTITION_PREFIX="${LOOP}p" + + echo "BOOT_DISK: $BOOT_DISK" +} + + SUCCESS=true function checksuccess { + printf 'Starting "%s"\n' "$1" cp /etc/fstab /etc/fstab.org if ../setup/pi/create-backingfiles-partition.sh /backingfiles /mutable && checknewpartitions then @@ -147,6 +178,7 @@ function checksuccess { } function checkfailure { + printf 'Starting "%s"\n' "$1" if ! ../setup/pi/create-backingfiles-partition.sh then printf '%-45s %s\n' "$1" OK @@ -217,6 +249,11 @@ checkenv checksuccess "one partition repeat" deleteimage + makeubuntulikeimage "$ROOT_IMAGE" + checksuccess "out of order partitions" + checksuccess "out of order partitions repeat" + deleteimage + maketriplepartdosimage "$ROOT_IMAGE" checkfailure "three partitions dos" checkfailure "three partitions dos repeat"