This repository has been archived on 2025-09-06. You can view files and clone it, but cannot push or open issues or pull requests.
Files
home-assistant-yellow/overlay/usr/libexec/init-storage
Dustin C. Hatch a87a7d6f3e 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.
2023-03-29 18:44:45 -05:00

176 lines
4.3 KiB
Bash
Executable File

#!/bin/sh
# vim: set sw=4 ts=4 sts=4 et :
SUBVOLUMES='
/var
/var/log
/var/tmp
/etc
'
cleanup() {
if [ -n "${tmpdir}" ] && [ "${tmpdir}" != / ]; then
if mountpoint -q "${tmpdir}"; then
umount "${tmpdir}"
fi
rm -rf "${tmpdir}"
unset tmpdir
fi
}
copy_var() {
dev="$1"
echo 'Copying /var contents to data volume'
mount -o subvol=var "${dev}" "${tmpdir}" || exit
cp -acuv /var/. "${tmpdir}" || exit
umount "${tmpdir}"
}
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
mount "${dev}" "${tmpdir}" || exit
for vol in ${SUBVOLUMES}; do
mkdir -p "${tmpdir}${vol%/*}" || exit
btrfs subvolume create "${tmpdir}${vol}" || exit
done
relabel_all
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}" | \
setfiles \
-v \
-F \
-m \
-r "${tmpdir}" \
-s \
/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"
echo 'Initializing writable paths in /etc'
mount -o subvol=etc "${dev}" "${tmpdir}" || exit
if [ ! -f "${tmpdir}"/shadow ]; then
cp -ca /etc/shadow "${tmpdir}"/shadow || exit
fi
mount -o bind "${tmpdir}"/shadow /etc/shadow || exit
if [ -f /etc/aimee-os/writable-etc ]; then
while read type path; do
if [ ! -e "${tmpdir}/${path}" ]; then
if [ -e /etc/"${path}" ]; then
cp -ca /etc/"${path}" "${tmpdir}/${path}"
elif [ "${type}" = d ]; then
mkdir -p "${tmpdir}/${path}"
elif [ "${type}" = f ]; then
: > "${tmpdir}/${path}"
else
printf 'Invalid path type %s for %s\n' \
"${type}" \
"${path}" \
>&2
continue
fi
fi
mount -o bind "${tmpdir}/${path}" /etc/"${path}"
done < /etc/aimee-os/writable-etc
fi
umount "${tmpdir}"
}
datapart=$(findfs $(awk '$2=="/var"{print $1}' /etc/fstab))
if [ -b "${datapart}" ]; then
printf 'Found data partition: %s\n' "${datapart}"
else
echo 'Could not identify data partition' >&2
exit 1
fi
trap cleanup INT TERM QUIT EXIT
tmpdir=/run/storinit
mkdir -p "${tmpdir}"
if ! has_fs "${datapart}"; then
format_dev "${datapart}"
fi
setup_etc "${datapart}"
copy_var "${datapart}"