#!/bin/sh

# initramfs local-top script: encrypt the root partition in place
# before it is mounted. The mounted root can never be shrunk for the
# LUKS header, so this is the only point in a boot where the
# conversion can run. cryptsetup's LUKS2 re-encryption is resumable,
# so a power loss mid-way continues on the next boot. Present in the
# initramfs only while a re-encryption is staged (see the hook);
# `eydos-installer firstboot` rebuilds the initramfs without it once
# the root is on the mapper.

PREREQ="udev"
prereqs() { echo "$PREREQ"; }
case "$1" in
	prereqs) prereqs; exit 0;;
esac

[ -f /etc/eydos-reencrypt/key ] || exit 0

. /scripts/functions

PARTUUID="$(cat /etc/eydos-reencrypt/device)"
DEV="/dev/disk/by-partuuid/${PARTUUID}"

modprobe dm_crypt 2>/dev/null || true
wait_for_udev 10
i=0
while [ ! -e "${DEV}" ] && [ $i -lt 30 ]
do
	sleep 1
	i=$((i + 1))
done
if [ ! -e "${DEV}" ]
then
	log_failure_msg "eydos-reencrypt: ${DEV} not found"
	exit 0
fi

if cryptsetup isLuks "${DEV}"
then
	# Interrupted run: resume it; a finished device resumes as a no-op.
	cryptsetup reencrypt --resume-only --batch-mode \
		--key-file /etc/eydos-reencrypt/key "${DEV}" || true
	cryptsetup open --key-file /etc/eydos-reencrypt/key "${DEV}" eydos_crypt || \
		log_failure_msg "eydos-reencrypt: could not open ${DEV}"
	exit 0
fi

log_begin_msg "Encrypting ${DEV} — this takes several minutes, do not power off"
e2fsck -fy "${DEV}" > /dev/null 2>&1 || true
SIZE_K=$(( $(blockdev --getsize64 "${DEV}") / 1024 - 32768 ))
if ! resize2fs "${DEV}" "${SIZE_K}K"
then
	log_failure_msg "eydos-reencrypt: filesystem shrink failed, leaving ${DEV} untouched"
	exit 0
fi
if cryptsetup reencrypt --encrypt --batch-mode --reduce-device-size 32M \
	--key-file /etc/eydos-reencrypt/key "${DEV}"
then
	cryptsetup open --key-file /etc/eydos-reencrypt/key "${DEV}" eydos_crypt || \
		log_failure_msg "eydos-reencrypt: could not open ${DEV}"
else
	log_failure_msg "eydos-reencrypt: cryptsetup reencrypt failed"
fi
log_end_msg

exit 0
