#!/usr/bin/env bash # SPDX-License-Identifier: LGPL-2.1-or-later # shellcheck disable=SC2317 set -eux set -o pipefail # shellcheck source=test/units/util.sh . "$(dirname "$0")"/util.sh if ! command -v systemd-repart >/dev/null; then echo "no systemd-repart" >/skipped exit 77 fi # shellcheck source=test/units/test-control.sh . "$(dirname "$0")"/test-control.sh # shellcheck source=test/units/util.sh . "$(dirname "$0")"/util.sh export SYSTEMD_LOG_LEVEL=debug export PAGER=cat # Disable use of special glyphs such as → export SYSTEMD_UTF8=0 seed=750b6cd5c4ae4012a15e7be3c29e6a47 if ! systemd-detect-virt --quiet --container; then udevadm control --log-level debug fi esp_guid=C12A7328-F81F-11D2-BA4B-00A0C93EC93B xbootldr_guid=BC13C2FF-59E6-4262-A352-B275FD6F7172 machine="$(uname -m)" if [ "${machine}" = "x86_64" ]; then root_guid=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709 root_uuid=60F33797-1D71-4DCB-AA6F-20564F036CD0 root_uuid2=73A4CCD2-EAF5-44DA-A366-F99188210FDC usr_guid=8484680C-9521-48C6-9C11-B0720656F69E usr_uuid=7E3369DD-D653-4513-ADF5-B993A9F20C16 architecture="x86-64" elif [ "${machine}" = "i386" ] || [ "${machine}" = "i686" ] || [ "${machine}" = "x86" ]; then root_guid=44479540-F297-41B2-9AF7-D131D5F0458A root_uuid=02B4253F-29A4-404E-8972-1669D3B03C87 root_uuid2=268E0FD3-B468-4806-A823-E533FE9BB9CC usr_guid=75250D76-8CC6-458E-BD66-BD47CC81A812 usr_uuid=7B42FFB0-B0E1-4395-B20B-C78F4A571648 architecture="x86" elif [ "${machine}" = "aarch64" ] || [ "${machine}" = "aarch64_be" ] || [ "${machine}" = "armv8b" ] || [ "${machine}" = "armv8l" ]; then root_guid=B921B045-1DF0-41C3-AF44-4C6F280D3FAE root_uuid=055D0227-53A6-4033-85C3-9A5973EFF483 root_uuid2=F7DBBE48-8FD0-4833-8411-AA34E7C8E60A usr_guid=B0E01050-EE5F-4390-949A-9101B17104E9 usr_uuid=FCE3C75E-D6A4-44C0-87F0-4C105183FB1F architecture="arm64" elif [ "${machine}" = "arm" ]; then root_guid=69DAD710-2CE4-4E3C-B16C-21A1D49ABED3 root_uuid=567DA89E-8DE2-4499-8D10-18F212DFF034 root_uuid2=813ECFE5-4C89-4193-8A52-437493F2F96E usr_guid=7D0359A3-02B3-4F0A-865C-654403E70625 usr_uuid=71E93DC2-5073-42CB-8A84-A354E64D8966 architecture="arm" elif [ "${machine}" = "loongarch64" ]; then root_guid=77055800-792C-4F94-B39A-98C91B762BB6 root_uuid=D8EFC2D2-0133-41E4-BDCB-3B9F4CFDDDE8 root_uuid2=36499F9E-0688-40C1-A746-EA8FD9543C56 usr_guid=E611C702-575C-4CBE-9A46-434FA0BF7E3F usr_uuid=031FFA75-00BB-49B6-A70D-911D2D82A5B7 architecture="loongarch64" elif [ "${machine}" = "ia64" ]; then root_guid=993D8D3D-F80E-4225-855A-9DAF8ED7EA97 root_uuid=DCF33449-0896-4EA9-BC24-7D58AEEF522D root_uuid2=C2A6CAB7-ABEA-4FBA-8C48-CB4C52E6CA38 usr_guid=4301D2A6-4E3B-4B2A-BB94-9E0B2C4225EA usr_uuid=BC2BCCE7-80D6-449A-85CC-637424CE5241 architecture="ia64" elif [ "${machine}" = "s390x" ]; then root_guid=5EEAD9A9-FE09-4A1E-A1D7-520D00531306 root_uuid=7EBE0C85-E27E-48EC-B164-F4807606232E root_uuid2=2A074E1C-2A19-4094-A0C2-24B1A5D52FCB usr_guid=8A4F5770-50AA-4ED3-874A-99B710DB6FEA usr_uuid=51171D30-35CF-4A49-B8B5-9478B9B796A5 architecture="s390x" elif [ "${machine}" = "ppc64le" ]; then root_guid=C31C45E6-3F39-412E-80FB-4809C4980599 root_uuid=061E67A1-092F-482F-8150-B525D50D6654 root_uuid2=A6687CEF-4E4F-44E7-90B3-CDA52EA81739 usr_guid=15BB03AF-77E7-4D4A-B12B-C0D084F7491C usr_uuid=C0D0823B-8040-4C7C-A629-026248E297FB architecture="ppc64-le" else echo "Unexpected uname -m: ${machine} in TEST-58-REPART.sh, please fix me" exit 1 fi testcase_basic() { local defs imgs output local loop volume defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")" imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")" # shellcheck disable=SC2064 trap "rm -rf '$defs' '$imgs'" RETURN chmod 0755 "$defs" echo "*** 1. create an empty image ***" systemd-repart --offline="$OFFLINE" \ --empty=create \ --size=1G \ --seed="$seed" \ "$imgs/zzz" output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$') assert_eq "$output" "label: gpt label-id: 1D2CE291-7CCE-4F7D-BC83-FDB49AD74EBD device: $imgs/zzz unit: sectors first-lba: 2048 last-lba: 2097118" echo "*** 2. Testing with root, root2, home, and swap ***" tee "$defs/root.conf" <>"$defs/home.conf" echo "UUID=b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" >>"$defs/home.conf" systemd-repart --offline="$OFFLINE" \ --definitions="$defs" \ --dry-run=no \ --seed="$seed" \ "$imgs/zzz" output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$') assert_eq "$output" "label: gpt label-id: 1D2CE291-7CCE-4F7D-BC83-FDB49AD74EBD device: $imgs/zzz unit: sectors first-lba: 2048 last-lba: 2097118 $imgs/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\" $imgs/zzz2 : start= 593904, size= 591856, type=${root_guid}, uuid=${root_uuid}, name=\"root-${architecture}\", attrs=\"GUID:59\" $imgs/zzz3 : start= 1185760, size= 591864, type=${root_guid}, uuid=${root_uuid2}, name=\"root-${architecture}-2\", attrs=\"GUID:59\" $imgs/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\" $imgs/zzz5 : start= 1908696, size= 188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name=\"custom_label\"" echo "*** 4. Resizing to 2G ***" systemd-repart --offline="$OFFLINE" \ --definitions="$defs" \ --size=2G \ --dry-run=no \ --seed="$seed" \ "$imgs/zzz" output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$') assert_eq "$output" "label: gpt label-id: 1D2CE291-7CCE-4F7D-BC83-FDB49AD74EBD device: $imgs/zzz unit: sectors first-lba: 2048 last-lba: 4194270 $imgs/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\" $imgs/zzz2 : start= 593904, size= 591856, type=${root_guid}, uuid=${root_uuid}, name=\"root-${architecture}\", attrs=\"GUID:59\" $imgs/zzz3 : start= 1185760, size= 591864, type=${root_guid}, uuid=${root_uuid2}, name=\"root-${architecture}-2\", attrs=\"GUID:59\" $imgs/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\" $imgs/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name=\"custom_label\"" echo "*** 5. Testing with root, root2, home, swap, another partition, and partition copy ***" dd if=/dev/urandom of="$imgs/block-copy" bs=4096 count=10240 tee "$defs/extra2.conf" </dev/null umount "$imgs/mount" } testcase_dropin() { local defs imgs output defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")" imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")" # shellcheck disable=SC2064 trap "rm -rf '$defs' '$imgs'" RETURN chmod 0755 "$defs" tee "$defs/root.conf" < 32M", "old_padding" : 0, "raw_padding" : 0, "padding" : "-> 0B", "activity" : "create", "drop-in_files" : [ "$defs/root.conf.d/override1.conf", "$defs/root.conf.d/override2.conf" ] } ] EOF } testcase_multiple_definitions() { local defs imgs output defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")" imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")" # shellcheck disable=SC2064 trap "rm -rf '$defs' '$imgs'" RETURN chmod 0755 "$defs" mkdir -p "$defs/1" tee "$defs/1/root1.conf" < 32M", "old_padding" : 0, "raw_padding" : 0, "padding" : "-> 0B", "activity" : "create" }, { "type" : "swap", "label" : "label2", "uuid" : "837c3d67-21b3-478e-be82-7e7f83bf96d3", "partno" : 1, "file" : "$defs/2/root2.conf", "node" : "$imgs/zzz2", "offset" : 34603008, "old_size" : 0, "raw_size" : 33554432, "size" : "-> 32M", "old_padding" : 0, "raw_padding" : 0, "padding" : "-> 0B", "activity" : "create" } ] EOF } testcase_copy_blocks() { local defs imgs output defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")" imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")" # shellcheck disable=SC2064 trap "rm -rf '$defs' '$imgs'" RETURN chmod 0755 "$defs" echo "*** First, create a disk image and verify its in order ***" tee "$defs/esp.conf" <"$defs/verity.openssl.cnf" </dev/null; then continue fi tee "$defs/root-$format.conf" </dev/null; then tee "$defs/root-squashfs.conf" </dev/null; then echo "Skipping free area calculation test without squashfs." return fi defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")" imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")" # shellcheck disable=SC2064 trap "rm -rf '$defs' '$imgs'" RETURN chmod 0755 "$defs" # https://github.com/systemd/systemd/issues/28225 echo "*** free area calculation ***" tee "$defs/00-ESP.conf" <"$defs/10-part1.conf" echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=1\n" >"$defs/11-dropped-first.conf" echo -ne "[Partition]\nType=root\n" >"$defs/12-part2.conf" echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=2\n" >"$defs/13-dropped-second.conf" systemd-repart --empty=allow --pretty=yes --dry-run=no --definitions="$defs" "$image" sfdisk -q -l "$image" [[ "$(sfdisk -q -l "$image" | grep -c "$image")" -eq 2 ]] } testcase_urandom() { local workdir image defs workdir="$(mktemp --directory "/tmp/test-repart.urandom.XXXXXXXXXX")" # shellcheck disable=SC2064 trap "rm -rf '${workdir:?}'" RETURN image="$workdir/image.img" truncate -s 32M "$image" defs="$workdir/defs" mkdir "$defs" echo -ne "[Partition]\nType=swap\nCopyBlocks=/dev/urandom\n" >"$defs/10-urandom.conf" systemd-repart --empty=force --pretty=yes --dry-run=no --definitions="$defs" "$image" sfdisk -q -l "$image" [[ "$(sfdisk -q -l "$image" | grep -c "$image")" -eq 1 ]] } testcase_list_devices() { systemd-repart --list-devices } testcase_compression() { local workdir image defs workdir="$(mktemp --directory "/tmp/test-repart.compression.XXXXXXXXXX")" # shellcheck disable=SC2064 trap "rm -rf '${workdir:?}'" RETURN image="$workdir/image.img" defs="$workdir/defs" mkdir "$defs" # TODO: add btrfs once btrfs-progs v6.11 is available in distributions. for format in squashfs erofs; do case "$format" in squashfs) command -v mksquashfs >/dev/null || continue ;; *) command -v "mkfs.$format" || continue ;; esac [[ "$format" == "squashfs" ]] && compression=zstd [[ "$format" == "erofs" ]] && compression=lz4hc tee "$defs/10-root.conf" < big ESP should be created systemd-repart --empty=create --size=auto --dry-run=no --definitions="$defs" "$image" output=$(sfdisk -d "$image") assert_in "${image}1 : start= 2048, size= 204800, type=${esp_guid}" "$output" assert_not_in "${image}2" "$output" # Disk with small ESP => ESP grows sfdisk "$image" < XBOOTLDR created truncate -s 150M "$image" sfdisk "$image" < XBOOTLDR grows, small ESP created sfdisk "$image" <= 512 and <= PAGE_SIZE, and # must be powers of 2. Which leaves exactly four different ones to test on # typical hardware test_sector 512 test_sector 1024 test_sector 2048 test_sector 4096 touch /testok