#!/usr/bin/bash

# shellcheck disable=SC1091
. /lib/dracut-lib.sh

# this cannot contain -u option because it causes an error inside
# /lib/dracut-lib.sh
set -eo pipefail
shopt -s expand_aliases

function check_device() {
    local sysfs_path recursion_limit dm_name dm_target slave
    sysfs_path="$1"
    recursion_limit="${2:-10}"

    if [ -r "$sysfs_path/dm/name" ]; then
        dm_name=$(cat "$sysfs_path"/dm/name)
        dm_target=$(dmsetup table "$dm_name" | cut -d ' ' -f 3)
        # This also ensures that the dm table have only single entry
        if [ "$dm_target" = "crypt" ]; then
            return 0
        elif [ -n "$(ls -A "$sysfs_path"/slaves)" ] && [ "$recursion_limit" -gt 0 ]; then
            for slave in "$sysfs_path"/slaves/*; do
                if ! check_device "$slave" "$(( recursion_limit - 1 ))"; then
                    return 1
                fi
            done
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}


root_name="$(getarg root)"
if echo "$root_name" | grep -q = ; then
    root_matches=$(blkid -t "$root_name" | wc -l)
    if [ "$root_matches" -gt 1 ]; then
        die "AEM: multiple devices matching $root_name found, aborting!"
    fi
    root_dev=$(blkid -o device -t "$root_name")
else
    root_dev=$root_name
fi

root_devid=$(lsblk -dnr -o MAJ:MIN "$root_dev")

if ! check_device /sys/dev/block/"$root_devid"; then
    die "AEM: (bogus?) root device found not encrypted!"
fi

for lv in $(getarg rd.lvm.lv); do
    if [ -e /dev/"$lv" ]; then
        devid=$(lsblk -dnr -o MAJ:MIN /dev/"$lv")
        if ! check_device /sys/dev/block/"$devid"; then
            die "AEM: (bogus?) device /dev/$lv found not encrypted!"
        fi
    fi
done

exit 0
