#!/bin/sh
# Btrfs boot probe — detect boot configuration on btrfs subvolumes.
# Called directly by linux-boot-prober as: probe-btrfs UUID=<> subvol=<>
set -e

. /usr/share/os-prober/common.sh

require_tmpdir

# Validate arguments
ERR="n"

if [ -z "$1" ]; then
	ERR=y
elif [ -z "$2" ]; then
	ERR=y
else
	echo "$1" | grep -q "^UUID=" || ERR=y
	echo "$2" | grep -q "^subvol=" || ERR=y
fi

if [ "x$ERR" != xn ]; then
	echo "usage: probe-btrfs UUID=<> subvol=<>" >&2
	exit 1
fi

export "$1"
export "$2"

partition=$(blkid -o device -t UUID="$UUID" 2>/dev/null | head -n1)
debug "btrfs: partition=$partition, UUID=$UUID, subvol=$subvol"

tmpmnt=/var/lib/os-prober/mount

bootmnt=
bootsv=
bootuuid=

btrfs_mounted=
do_unmount() {
	umount "$tmpmnt/boot" 2>/dev/null || true
	if [ "$btrfs_mounted" ]; then
		umount "$tmpmnt" 2>/dev/null || true
	fi
	btrfs_mounted=
	rmdir "$tmpmnt" 2>/dev/null || true
}
trap 'do_unmount; cleanup' EXIT HUP INT QUIT TERM

if [ ! -d "$tmpmnt" ]; then
	mkdir "$tmpmnt"
fi

if [ ! -e "/proc/self/mountinfo" ]; then
	warn "/proc/self/mountinfo does not exist, exiting"
	do_unmount
	exit 1
fi
mpoint=$(grep "btrfs" /proc/self/mountinfo | grep " /$subvol " | grep " $partition " | cut -d ' ' -f 5) || true
if [ "$mpoint" = "/" ]; then
	warn "specifying active root not valid, exiting"
	do_unmount
	exit 1
fi
if [ "$mpoint" = "$tmpmnt" ]; then
	warn "btrfs subvol=$subvol, UUID=$UUID, already mounted on $tmpmnt **ERROR**"
	do_unmount
	exit 1
fi
if [ -z "$mpoint" ]; then
	# mount the btrfs root
	if ! mount -o subvol=$subvol -t btrfs -U $UUID "$tmpmnt" 2>/dev/null; then
		warn "error mounting btrfs subvol=$subvol UUID=$UUID"
		do_unmount
		exit 1
	fi
	btrfs_mounted=1
else
	# bind-mount
	if ! mount -o bind "$mpoint" "$tmpmnt" 2>/dev/null; then
		warn "error mounting btrfs bindfrom=$mpoint subvol=$subvol UUID=$UUID"
		do_unmount
		exit 1
	fi
	btrfs_mounted=1
fi
debug "mounted btrfs $partition, subvol=$subvol on $tmpmnt"
if [ ! -e "$tmpmnt/etc/fstab" ]; then
	warn "btrfs subvol=$subvol not root"
	do_unmount
	exit 1
fi
bootmnt=$(parsefstab < "$tmpmnt/etc/fstab" | grep " /boot ") || true
if [ -z "$bootmnt" ]; then
	# /boot is part of the root
	bootpart="$partition"
	bootsv="$subvol"
elif echo "$bootmnt" | cut -d ' ' -f 3 | grep -q "btrfs"; then
	# separate btrfs /boot subvolume
	bootsv=$(echo "$bootmnt" | cut -d ' ' -f 4 | tr ',' '\n' | grep "^subvol=" | sed "s/subvol=//" )
	bootuuid=$(echo "$bootmnt" | cut -d ' ' -f 1 | grep "^UUID=" | sed "s/UUID=//" )
	debug "mounting btrfs $tmpmnt/boot UUID=$bootuuid subvol=$bootsv"
	bindfrom=$(check_btrfs_mounted $bootsv $bootuuid)
	if [ -n "$bindfrom" ]; then
		# already mounted some place
		if ! mount -o bind $bindfrom "$tmpmnt/boot" 2>/dev/null; then
			warn "error bind mounting btrfs boot subvol=$bootsv, from=$bindfrom"
			do_unmount
			exit 1
		fi
	elif ! mount -o subvol=$bootsv -t btrfs -U $bootuuid "$tmpmnt/boot" 2>/dev/null; then
		warn "error mounting btrfs boot partition subvol=$bootsv, UUID=$bootuuid"
		do_unmount
		exit 1
	fi
	bootpart=$(blkid -o device -t UUID="$bootuuid" 2>/dev/null | head -n1)
else
	# non-btrfs partition or logical volume
	linux_mount_boot $partition $tmpmnt
	bootpart="${mountboot%% *}"
	bootsv=
fi

test="/usr/lib/linux-boot-probes/mounted/40grub2"
if [ -f $test ] && [ -x $test ]; then
	debug "running $test $partition $bootpart $tmpmnt btrfs $subvol $bootsv"
	if $test "$partition" "$bootpart" "$tmpmnt" "btrfs" "$subvol" "$bootsv"; then
		debug "$test succeeded"
	fi
fi
do_unmount

exit 0
