From a87a7d6f3e962452c34dc415a2e02552ea217730 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Sun, 26 Mar 2023 11:58:23 -0500 Subject: [PATCH] init-storage: Resize data partition If the data volume is a partition (rather than a whole disk device), the `init-storage` script will now attempt to resize it to use all unallocated space on the disk. This only works if it is the last partition on the disk. This situation is common when writing the `sdcard.img` file directly to a disk that is larger than 4 GiB. --- overlay/usr/libexec/init-storage | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/overlay/usr/libexec/init-storage b/overlay/usr/libexec/init-storage index c4685dc..eb87e4f 100755 --- a/overlay/usr/libexec/init-storage +++ b/overlay/usr/libexec/init-storage @@ -29,6 +29,22 @@ copy_var() { format_dev() { dev="$1" + partno=$(partition_number "${dev}") + if [ -n "${partno}" ]; then + disk="$(get_disk "${dev}")" + if [ -n "${disk}" ]; then + printf 'Resizing partition %d on disk %s\n' \ + "${partno}" \ + "${disk}" \ + >&2 + resize_partition "${disk}" "${partno}" + else + printf 'Could not find disk for device %s\n' \ + "${dev}" \ + >&2 + fi + fi + printf 'Creating BTRFS filesystem on %s\n' "${dev}" mkfs.btrfs "${dev}" || exit @@ -41,12 +57,37 @@ format_dev() { umount "${dev}" || exit } +get_disk() { + _syspath=/sys/class/block/${1##*/} + [ -d "${_syspath}" ] || return 1 + if [ ! -f "${_syspath}"/partition ]; then + readlink -f "${1}" + return $? + fi + _disk=$(readlink -f "${_syspath}"/..) + if [ -n "${_disk}" ]; then + printf '/dev/%s\n' "${_disk##*/}" + return 0 + fi + return 1 +} + has_fs() { dev="$1" fstype=$(blkid -o value -s TYPE "${dev}") [ -n "${fstype}" ] } +last_partition() { + cat /sys/class/block/"${1##*/}"/*/partition \ + | sort -n \ + | tail -n1 +} + +partition_number() { + cat /sys/class/block/${1##*/}/partition +} + relabel_all() { selinuxtype=$(. /etc/selinux/config && echo ${SELINUXTYPE}) find "${tmpdir}" | \ @@ -59,6 +100,29 @@ relabel_all() { /etc/selinux/${selinuxtype}/contexts/files/file_contexts } +resize_partition() { + _disk="${1}" + _part="${2}" + _lastpart=$(last_partition "${_disk}") + if [ "${_part}" -ne "${_lastpart}" ]; then + printf 'Cannot resize %s, it is not the last partition on the disk\n' \ + "${_dev}" \ + >&2 + return 1 + fi + _uuid=$(sfdisk --part-uuid "${_disk}" "${_part}") || return $? + _type=$(sfdisk --part-type "${_disk}" "${_part}") || return $? + _label=$(sfdisk --part-label "${_disk}" "${_part}") || return $? + sfdisk --delete "${_disk}" "${_part}" || return $? + printf 'type=%s, uuid=%s, name="%s"\n' \ + "${_type}" \ + "${_uuid}" \ + "${_label}" \ + | sfdisk -N "${_part}" "${_disk}" --force \ + || return $? + partx -u "${_disk}" +} + setup_etc() { dev="$1"