diff --git a/src/sysupdate/sysupdate-partition.c b/src/sysupdate/sysupdate-partition.c index fa4453d665..6f8e072277 100644 --- a/src/sysupdate/sysupdate-partition.c +++ b/src/sysupdate/sysupdate-partition.c @@ -28,6 +28,7 @@ int read_partition_info( const char *label; struct fdisk_partition *p; uint64_t start, size, flags; + unsigned long ssz; sd_id128_t ptid, id; GptPartitionType type; size_t partno; @@ -54,12 +55,13 @@ int read_partition_info( partno = fdisk_partition_get_partno(p); start = fdisk_partition_get_start(p); - assert(start <= UINT64_MAX / 512U); - start *= 512U; + ssz = fdisk_get_sector_size(c); + assert(start <= UINT64_MAX / ssz); + start *= ssz; size = fdisk_partition_get_size(p); - assert(size <= UINT64_MAX / 512U); - size *= 512U; + assert(size <= UINT64_MAX / ssz); + size *= ssz; label = fdisk_partition_get_name(p); if (!label) diff --git a/test/units/testsuite-72.sh b/test/units/testsuite-72.sh index 36c9712a09..e428e902b1 100755 --- a/test/units/testsuite-72.sh +++ b/test/units/testsuite-72.sh @@ -6,116 +6,55 @@ set -eux set -o pipefail SYSUPDATE=/lib/systemd/systemd-sysupdate +SECTOR_SIZES="512 4096" +BACKING_FILE=/var/tmp/72-joined.raw +export SYSTEMD_ESP_PATH=/var/tmp/72-esp +export SYSTEMD_XBOOTLDR_PATH=/var/tmp/72-xbootldr +export SYSTEMD_PAGER=cat +export SYSTEMD_LOG_LEVEL=debug if ! test -x "$SYSUPDATE"; then echo "no systemd-sysupdate" >/skipped exit 0 fi -export SYSTEMD_PAGER=cat -export SYSTEMD_LOG_LEVEL=debug +# Loopback devices may not be supported. They are used because sfdisk cannot +# change the sector size of a file, and we want to test both 512 and 4096 byte +# sectors. If loopback devices are not supported, we can only test one sector +# size, and the underlying device is likely to have a sector size of 512 bytes. +if ! losetup --find >/dev/null 2>&1; then + echo "No loopback device support" + SECTOR_SIZES="512" +fi -rm -f /var/tmp/72-joined.raw -truncate -s 10M /var/tmp/72-joined.raw - -sfdisk /var/tmp/72-joined.raw </var/tmp/72-defs/01-first.conf <<"EOF" -[Source] -Type=regular-file -Path=/var/tmp/72-source -MatchPattern=part1-@v.raw - -[Target] -Type=partition -Path=/var/tmp/72-joined.raw -MatchPattern=part1-@v -MatchPartitionType=root-x86-64 -EOF - -cat >/var/tmp/72-defs/02-second.conf <<"EOF" -[Source] -Type=regular-file -Path=/var/tmp/72-source -MatchPattern=part2-@v.raw.gz - -[Target] -Type=partition -Path=/var/tmp/72-joined.raw -MatchPattern=part2-@v -MatchPartitionType=root-x86-64-verity -EOF - -cat >/var/tmp/72-defs/03-third.conf <<"EOF" -[Source] -Type=directory -Path=/var/tmp/72-source -MatchPattern=dir-@v - -[Target] -Type=directory -Path=/var/tmp/72-dirs -CurrentSymlink=/var/tmp/72-dirs/current -MatchPattern=dir-@v -InstancesMax=3 -EOF - -cat >/var/tmp/72-defs/04-fourth.conf <<"EOF" -[Source] -Type=regular-file -Path=/var/tmp/72-source -MatchPattern=uki-@v.efi - -[Target] -Type=regular-file -Path=/EFI/Linux -PathRelativeTo=boot -MatchPattern=uki_@v+@l-@d.efi \ - uki_@v+@l.efi \ - uki_@v.efi -Mode=0444 -TriesLeft=3 -TriesDone=0 -InstancesMax=2 -EOF - -rm -rf /var/tmp/72-esp /var/tmp/72-xbootldr -mkdir -p /var/tmp/72-esp/EFI/Linux /var/tmp/72-xbootldr/EFI/Linux -export SYSTEMD_ESP_PATH=/var/tmp/72-esp -export SYSTEMD_XBOOTLDR_PATH=/var/tmp/72-xbootldr - -rm -rf /var/tmp/72-source -mkdir -p /var/tmp/72-source +trap cleanup ERR +cleanup() { + set +o pipefail + blockdev="$( losetup --list --output NAME,BACK-FILE | grep $BACKING_FILE | cut -d' ' -f1)" + [ -n "$blockdev" ] && losetup --detach "$blockdev" + rm -f "$BACKING_FILE" + rm -rf /var/tmp/72-{dirs,defs,source,xbootldr,esp} + rm -f /testok +} new_version() { + # Inputs: + # $1: sector size + # $2: version + # Create a pair of random partition payloads, and compress one - dd if=/dev/urandom of="/var/tmp/72-source/part1-$1.raw" bs=1024 count=1024 - dd if=/dev/urandom of="/var/tmp/72-source/part2-$1.raw" bs=1024 count=1024 - gzip -k -f "/var/tmp/72-source/part2-$1.raw" + dd if=/dev/urandom of="/var/tmp/72-source/part1-$2.raw" bs="$1" count=2048 + dd if=/dev/urandom of="/var/tmp/72-source/part2-$2.raw" bs="$1" count=2048 + gzip -k -f "/var/tmp/72-source/part2-$2.raw" # Create a random "UKI" payload - echo $RANDOM >"/var/tmp/72-source/uki-$1.efi" + echo $RANDOM >"/var/tmp/72-source/uki-$2.efi" # Create tarball of a directory - mkdir -p "/var/tmp/72-source/dir-$1" - echo $RANDOM >"/var/tmp/72-source/dir-$1/foo.txt" - echo $RANDOM >"/var/tmp/72-source/dir-$1/bar.txt" - tar --numeric-owner -C "/var/tmp/72-source/dir-$1/" -czf "/var/tmp/72-source/dir-$1.tar.gz" . + mkdir -p "/var/tmp/72-source/dir-$2" + echo $RANDOM >"/var/tmp/72-source/dir-$2/foo.txt" + echo $RANDOM >"/var/tmp/72-source/dir-$2/bar.txt" + tar --numeric-owner -C "/var/tmp/72-source/dir-$2/" -czf "/var/tmp/72-source/dir-$2.tar.gz" . ( cd /var/tmp/72-source/ && sha256sum uki* part* dir-*.tar.gz >SHA256SUMS ) } @@ -130,46 +69,153 @@ update_now() { } verify_version() { - # Expects: version ID + sector offset of both partitions to compare + # Inputs: + # $1: block device + # $2: sector size + # $3: version + # $4: partiton number of part1 + # $5: partiton number of part2 + + gpt_reserved_sectors=$(( 1024 * 1024 / $2 )) + part1_offset=$(( ( $4 - 1 ) * 2048 + gpt_reserved_sectors )) + part2_offset=$(( ( $5 - 1 ) * 2048 + gpt_reserved_sectors )) # Check the partitions - dd if=/var/tmp/72-joined.raw bs=1024 skip="$2" count=1024 | cmp "/var/tmp/72-source/part1-$1.raw" - dd if=/var/tmp/72-joined.raw bs=1024 skip="$3" count=1024 | cmp "/var/tmp/72-source/part2-$1.raw" + dd if="$1" bs="$2" skip="$part1_offset" count=2048 | cmp "/var/tmp/72-source/part1-$3.raw" + dd if="$1" bs="$2" skip="$part2_offset" count=2048 | cmp "/var/tmp/72-source/part2-$3.raw" # Check the UKI - cmp "/var/tmp/72-source/uki-$1.efi" "/var/tmp/72-xbootldr/EFI/Linux/uki_$1+3-0.efi" + cmp "/var/tmp/72-source/uki-$3.efi" "/var/tmp/72-xbootldr/EFI/Linux/uki_$3+3-0.efi" test -z "$(ls -A /var/tmp/72-esp/EFI/Linux)" # Check the directories - cmp "/var/tmp/72-source/dir-$1/foo.txt" /var/tmp/72-dirs/current/foo.txt - cmp "/var/tmp/72-source/dir-$1/bar.txt" /var/tmp/72-dirs/current/bar.txt + cmp "/var/tmp/72-source/dir-$3/foo.txt" /var/tmp/72-dirs/current/foo.txt + cmp "/var/tmp/72-source/dir-$3/bar.txt" /var/tmp/72-dirs/current/bar.txt } -# Install initial version and verify -new_version v1 -update_now -verify_version v1 1024 3072 +for sector_size in $SECTOR_SIZES ; do + # Disk size of: + # - 1MB for GPT + # - 4 partitions of 2048 sectors each + # - 1MB for backup GPT + disk_size=$(( sector_size * 2048 * 4 + 1024 * 1024 * 2 )) + rm -f "$BACKING_FILE" + truncate -s "$disk_size" "$BACKING_FILE" -# Create second version, update and verify that it is added -new_version v2 -update_now -verify_version v2 2048 4096 + if losetup --find >/dev/null 2>&1; then + # shellcheck disable=SC2086 + blockdev="$(losetup --find --show --sector-size $sector_size $BACKING_FILE)" + else + blockdev="$BACKING_FILE" + fi -# Create third version, update and verify it replaced the first version -new_version v3 -update_now -verify_version v3 1024 3072 -test ! -f "/var/tmp/72-xbootldr/EFI/Linux/uki_v1+3-0.efi" + sfdisk "$blockdev" </var/tmp/72-defs/02-second.conf <<"EOF" + rm -rf /var/tmp/72-dirs + mkdir -p /var/tmp/72-dirs + + rm -rf /var/tmp/72-defs + mkdir -p /var/tmp/72-defs + + cat >/var/tmp/72-defs/01-first.conf </var/tmp/72-defs/02-second.conf </var/tmp/72-defs/03-third.conf </var/tmp/72-defs/04-fourth.conf </var/tmp/72-defs/02-second.conf </var/tmp/72-defs/03-third.conf <<"EOF" + cat >/var/tmp/72-defs/03-third.conf <