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.
176 lines
4.3 KiB
Bash
Executable File
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}"
|