176 lines
4.1 KiB
Bash
Executable File
176 lines
4.1 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_vol() {
|
|
dev="$1"
|
|
vol=$2
|
|
|
|
printf 'Copying %s contents to data volume\n' "${vol}" >&2
|
|
mount -o subvol="${vol#/}" "${dev}" "${tmpdir}" || exit
|
|
cp -au${VERBOSE+v} /sysroot/${vol#/}/. "${tmpdir}" || exit
|
|
umount "${tmpdir}"
|
|
}
|
|
|
|
find_part() {
|
|
_i=0
|
|
while [ $_i -lt 5 ]; do
|
|
findfs "$1" 2>/dev/null && return
|
|
_i=$((_i + 1))
|
|
sleep 1
|
|
done
|
|
findfs "$1"
|
|
}
|
|
|
|
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}" >&2
|
|
mkfs.btrfs --quiet "${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() {
|
|
if [ ! -d /sys/fs/selinux ] || [ ! -f /etc/selinux/config ]; then
|
|
return
|
|
fi
|
|
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}" --quiet --force \
|
|
|| return $?
|
|
partx -u "${_disk}"
|
|
}
|
|
|
|
setup_etc() {
|
|
dev="$1"
|
|
|
|
echo 'Initializing /etc overlay' >&2
|
|
mkdir -p /run/aimeeos/etc || return
|
|
mount -o subvol=etc "${dev}" /run/aimeeos/etc || return
|
|
mkdir -p /run/aimeeos/etc/rw /run/aimeeos/etc/work || return
|
|
mount -t overlay \
|
|
-o lowerdir=/sysroot/etc,upperdir=/run/aimeeos/etc/rw,workdir=/run/aimeeos/etc/work \
|
|
overlay \
|
|
/sysroot/etc
|
|
}
|
|
|
|
rootdev=$(find_part "$1")
|
|
datapart=$(find_part "${2:-PARTLABEL=aimeeos-data}")
|
|
if [ -b "${datapart}" ]; then
|
|
printf 'Found data partition: %s\n' "${datapart}" >&2
|
|
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
|
|
|
|
mkdir -p /sysroot
|
|
mount -o ro "${rootdev}" /sysroot || exit
|
|
|
|
setup_etc "${datapart}"
|
|
copy_vol "${datapart}" /var
|
|
exit 0
|