A script that syncs EFI volume data to mountpoints with numbered suffixes '.N' 
and adds boot entries via efibootmgr
#!/bin/sh

if [ "$1" = "--write" ]
then
	COMMAND_PREFIX=''
	RSYNC_N=''
elif [ "$1" = "--dry-run" ]
then
	COMMAND_PREFIX='echo will run:'
	RSYNC_N='n'
else
	echo "Usage: $(basename "$0") [--dry-run|--write|--help]"
	exit 0
fi

EFI_MNT=/boot/efi
NEWLINE='
'

BOOT_CONFIG=$(
	efibootmgr -v
)

# get primary debian boot entry
PRIMARY_BOOT=$(
	echo "${BOOT_CONFIG}" | grep -E '^Boot[0-9]+\*?[[:space:]]+debian[[:space:]]+'
)

BOOT_ORDER=$(
	echo "${BOOT_CONFIG}" | grep -E '^BootOrder:[[:space:]]*' | grep -oE '[0-9]+(,[0-9]+)*' | sed -r 's/(0*?)([0-9]+(,|$))/\2/g'
)

[ -n "${PRIMARY_BOOT}" ] || { echo "Could not determine primary boot entry" >&2 ; exit 1 ; }

# get primary efi path
PRIMARY_BOOT_PATH=$(
	echo "${PRIMARY_BOOT}" | grep -Eo 'File\([^)]+\)'
)
PRIMARY_BOOT_PATH="${PRIMARY_BOOT_PATH%)}"
PRIMARY_BOOT_PATH="${PRIMARY_BOOT_PATH#File(}"

echo "${PRIMARY_BOOT_PATH}" | grep -qE '\\[a-zA-Z0-9\\._-]+\.(efi|EFI)$' || { echo "Could not determine primary boot entry efi path" >&2 ; exit 1 ; }

# get primary boot entry number
PRIMARY_BOOT_NUM=$(
	echo "${PRIMARY_BOOT}" | grep -Eo '^Boot[0-9]+' | sed -r 's/^(Boot)(0*?)([0-9]+$)/\3/'
)

echo "${PRIMARY_BOOT_NUM}" | grep -qE '^[0-9]+$' || { echo "Could not determine primary boot entry number, got: ${PRIMARY_BOOT_NUM}" >&2 ; exit 1 ; }

OCCUPIED_BOOTS=$(
	echo "${BOOT_CONFIG}" | grep -E '^Boot[0-9]+' | grep -vE '^Boot[0-9]+\*?[[:space:]]+debian(\.([0-9]|bak)+)?[[:space:]]+'
)

DUPLICATE_BOOTS=$(
	echo "${BOOT_CONFIG}" | grep -E '^Boot[0-9]+' | grep -E '^Boot[0-9]+\*?[[:space:]]+debian\.([0-9]|bak)+[[:space:]]+'
)

echo "Primary boot entry: #${PRIMARY_BOOT_NUM}: ${PRIMARY_BOOT_PATH}"
echo
echo "Duplicate boot entries:
${DUPLICATE_BOOTS}"
echo
echo "Occupied boot entries:
${OCCUPIED_BOOTS}"

EFI_DUP_MNTS=$(
	find "$(dirname "${EFI_MNT}")" -xdev -mindepth 1 -maxdepth 1 -type d -regex "${EFI_MNT}\.[0-9]+"
)

BOOT_NUM=$(( ${PRIMARY_BOOT_NUM} + 1 ))
DUPLICATE_BOOT_NUMS=''
OIFS=$IFS
for MOUNT in ${EFI_DUP_MNTS}
do
	IFS=$OIFS
	BLOCKDEV_PART=$(
		findmnt -no SOURCE "${MOUNT}"
	)
	[ ! -b "${BLOCKDEV_PART}" ] && { echo "${BLOCKDEV_PART} is not a block device" >&2 ; exit 1 ; }
	BLOCKDEV_PART_NUM=$(
		echo "${BLOCKDEV_PART}" | grep -oE '[0-9]+$'
	)
	echo "${BLOCKDEV_PART_NUM}" | grep -qE '^[0-9]+$' || { echo "Could not determine number of partition ${BLOCKDEV_PART}" >&2 ; exit 1 ; }
	BLOCKDEV=$(
		lsblk -ndo PKNAME "${BLOCKDEV_PART}"
	)
	BLOCKDEV="/dev/${BLOCKDEV}"
	[ ! -b "${BLOCKDEV}" ] && { echo "${BLOCKDEV} is not a block device" >&2 ; exit 1 ; }

	echo
	echo "Duplicate ${MOUNT}: partition ${BLOCKDEV_PART} on device ${BLOCKDEV}"
	while echo "${OCCUPIED_BOOTS}" | grep -qE "^Boot0*${BOOT_NUM}\*?[[:space:]]"
	do
		BOOT_NUM=$(( $BOOT_NUM + 1 ))
	done
	INDEX=$(echo "${MOUNT}" | grep -oE '\.[0-9]+$')
	[ -n "$COMMAND_PREFIX" ] && $COMMAND_PREFIX rsync -acAX --modify-window=1 "${EFI_MNT%/}/" "${MOUNT%/}/"
	rsync -acAX${RSYNC_N} --modify-window=1 "${EFI_MNT%/}/" "${MOUNT%/}/"
	if echo "${DUPLICATE_BOOTS}" | grep -q "^Boot0*${BOOT_NUM}"
	then
		echo "Removing existing duplicate boot entry ${BOOT_NUM}"
		$COMMAND_PREFIX efibootmgr -q -b ${BOOT_NUM} -B
		DUPLICATE_BOOTS=$(
			echo "${DUPLICATE_BOOTS}" | grep -v "^Boot0*${BOOT_NUM}"
		)
	fi
	echo "Placing duplicate boot entry ${BOOT_NUM} for debian${INDEX}"
	$COMMAND_PREFIX efibootmgr -q -c -d "${BLOCKDEV}" -p ${BLOCKDEV_PART_NUM} -L debian${INDEX} -b ${BOOT_NUM} -l "${PRIMARY_BOOT_PATH}"
	DUPLICATE_BOOT_NUMS="${DUPLICATE_BOOT_NUMS}${DUPLICATE_BOOT_NUMS:+,}${BOOT_NUM}"
done
IFS=$OIFS

[ -n "${DUPLICATE_BOOTS}" ] && echo
IFS=''
for BOOT_NUM in $(
	echo "${DUPLICATE_BOOTS}" | grep -Eo '^Boot0*[0-9]+' | sed -r 's/^(Boot)(0*?)([0-9]+$)/\3/'
)
do
	IFS=$OIFS
	echo "Removing leftover duplicate entry ${BOOT_NUM}"
	$COMMAND_PREFIX efibootmgr -q -b ${BOOT_NUM} -B
done
IFS=$OIFS

FINAL_BOOT_ORDER=$(
	echo "${PRIMARY_BOOT_NUM},${DUPLICATE_BOOT_NUMS},${BOOT_ORDER}" \
	| tr -d '\n\t ' | tr -s ','
)

echo
echo "Putting primary and duplicates to the front of boot order"
$COMMAND_PREFIX efibootmgr -q -o ${FINAL_BOOT_ORDER}
echo
echo "Removing duplicates in boot order"
$COMMAND_PREFIX efibootmgr -D -v

Reply via email to