blob: 904eed06289b3466f470683312eab02b7ac6c0f9 [file] [log] [blame]
#!/bin/bash
GBMC_IMAGE=@GBMC_IMAGE@
if [ "${GBMC_IMAGE}" == "true" ]; then
echo "Getting activation half" >&2
source /usr/lib/payload-lib.sh || exit 1
payload_status || exit 1
else
echo "vendor image, using fixed location"
active_half=0
fi
MACHINE=@MACHINE@
img="emmc-image-${MACHINE}.squashfs-xz.verity"
emmcdir="/mnt/luks-mmcblk0_fs/emmc-image/${active_half}"
hashfile="/usr/share/emmc-image-verity/${img}.env"
mountdir="/run/emmc-image"
mutableconfdir=/var/lib/extensions.mutable
clear_mount_ref() {
local mergetime=$(systemctl show emmc-image-setup | grep ExecMainStartTimestampMonotonic | cut -d'=' -f 2)
local service
for service in $(systemctl list-units | grep service | grep running | cut -d" " -f 3); do
local starttime=$(systemctl show $service | grep ExecMainStartTimestampMonotonic | cut -d'=' -f 2)
(( starttime > mergetime )) && systemctl restart "${service}"
done
}
if [ $1 == "start" ]; then
if [[ -f "/run/emmc-image-runtime/VERSION" ]]; then
echo "already have a running eMMC image, probably in netboot" >&2
exit 0
fi
if ! source "${hashfile}"; then
echo "${emmcimg}: hash file not found" >&2
exit 1
fi
if [[ ! -f "${emmcdir}/VERSION" ]]; then
echo "${emmcimg}: VERSION file not found" >&2
exit 1
fi
mkdir -p "${mountdir}/${img}"
mkdir -p /run/extensions/
mkdir -p /run/confexts/
echo "Loading image ${emmcdir}/${img}" >&2
veritysetup --data-block-size=$DATA_BLOCK_SIZE --hash=$HASH_ALGORITHM --hash-block-size=$HASH_BLOCK_SIZE --hash-offset=$DATA_SIZE open "${emmcdir}/${img}" "${img}" "${emmcdir}/${img}" $ROOT_HASH
echo "Mounting image links for ${img}" >&2
mount /dev/mapper/${img} "${mountdir}/${img}" || exit
echo "Setting sysext links for ${img}" >&2
rm -f /run/extensions/${img} && ln -s "${mountdir}/${img}" "/run/extensions/${img}"
rm -f /run/confexts/${img} && ln -s "${mountdir}/${img}" "/run/confexts/${img}"
echo "Finished setup runtime image ${img}" >&2
# make the overlay mutable after merge
mkdir -p ${mutableconfdir} && rm -f ${mutableconfdir}/*
ln -s /run/initramfs/rw/cow/etc ${mutableconfdir}/etc
ln -s /run/initramfs/rw/cow/usr ${mutableconfdir}/usr
echo "Merging sysext ..." >&2
systemd-sysext merge --force --mutable=auto || exit
echo "Merging confext ..." >&2
systemd-confext merge --force --mutable=auto --noexec=false || exit
echo "Starting all services"
systemctl daemon-reload
systemctl start emmc-image.target
cp ${emmcdir}/VERSION ${mountdir}/VERSION
echo "Loaded emmc images" >&2
elif [ $1 == "stop" ]; then
# In regular cases, eMMC image will stay alive until reboot/powercycle.
# Clean up could happen in maintenance mode for emmc erase
# skip process when reboot
systemctl is-active -q reboot.target && exit 0
# skip clean up if eMMC does not exist
[[ -f "${emmcdir}/VERSION" ]] || exit 0
echo "clearing emmc image configurations in best effort" >&2
echo "This should be an operation only during maintenance" >&2
rm -rf "${mountdir}/VERSION"
# no need to unmerge and reload if no extension config at all.
if [[ -d ${mutableconfdir} ]]; then
systemctl stop emmc-image.target
systemd-confext unmerge
systemd-sysext unmerge
systemctl daemon-reload
rm -rf ${mutableconfdir}
# services running after merge is possibly still using the mount.
# stop them here
clear_mount_ref
fi
rm -rf /run/extensions /run/confexts
umount -l /dev/mapper/${img}
rm -rf "${mountdir}/${img}"
# deferred close, it won't close until this clean up process quit itself.
veritysetup close --deferred "${img}"
# waiting for periodic oneshot process to clean up, most of the process can finish within 60s.
sleep 120
fi