#!/bin/bash -eu
# SPDX-License-Identifier: GPL-3.0-or-later

. sh-functions

DIR="$ROOTDIR"

if [ "${1-}" = dirs ]; then
	mkdir ${verbose2-} -p -- "$DIR/etc/initrd/md"
fi

if [ -z "${GENERATE_UDEV_RULES_FOR_MD_DEVICE-}" ]; then
	verbose2 "No preferred RAID devices. Generating rules for all raid devices..."

	GENERATE_UDEV_RULES_FOR_MD_DEVICE=

	# If the variable is not specified, we generate rules for all
	# raid devices.
	for path in /dev/dev/block/*/md; do
		if [ -d "$path" ]; then
			majmin="${path%/md}"
			majmin="${majmin##*/}"
			GENERATE_UDEV_RULES_FOR_MD_DEVICE="$GENERATE_UDEV_RULES_FOR_MD_DEVICE $majmin"
		fi
	done
fi

for majmin in ${GENERATE_UDEV_RULES_FOR_MD_DEVICE-}; do
	verbose2 "Processing MD device $majmin..."

	DEVNAME="$(sed -n -e 's,^DEVNAME=,,p' "$SYSFS_PATH/dev/block/$majmin/uevent")"

	[ -n "${DEVNAME-}" ] ||
		fatal "unable to find device name in \`$SYSFS_PATH/dev/block/$majmin/uevent'"

	MD_UUID=
	MD_CONTAINER=

	# shellcheck disable=SC2046
	eval "$(mdadm --detail --export "/dev/$DEVNAME")"

	[ -z "$MD_CONTAINER" ] || eval "$(mdadm --detail --export "$MD_CONTAINER")"

	[ -n "$MD_UUID" ] ||
		fatal "UUID not found for /dev/$DEVNAME"

	uuid="${MD_UUID//:}"

	if [ "${1-}" = dirs ]; then
		verbose2 "Creating: /etc/initrd/md/$uuid"
		:> "$DIR/etc/initrd/md/$uuid"
		continue
	fi

	rules="$TEMPDIR/64-md-raid-assembly-$uuid.rules"

	cat > "$rules" <<EOF
SUBSYSTEM!="block", GOTO="md_inc_end"
ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc"

IMPORT{cmdline}="noiswmd"
IMPORT{cmdline}="nodmraid"

ENV{nodmraid}=="?*", GOTO="md_inc_end"
ENV{ID_FS_TYPE}=="ddf_raid_member", GOTO="md_inc"
ENV{noiswmd}=="?*", GOTO="md_inc_end"
ENV{ID_FS_TYPE}=="isw_raid_member", GOTO="md_inc"
GOTO="md_inc_end"

LABEL="md_inc"

ENV{ID_FS_UUID}=="${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}", GOTO="md_uuid_ok"
IMPORT{program}="/sbin/mdadm --examine --export \$devnode"
ENV{MD_UUID}=="$MD_UUID", GOTO="md_uuid_ok"
GOTO="md_inc_end"

LABEL="md_uuid_ok"

ACTION=="add|change", IMPORT{program}="/sbin/mdadm --incremental --export \$devnode --offroot \$env{DEVLINKS}"
ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="/sbin/mdadm -If \$name --path \$env{ID_PATH}"
ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="/sbin/mdadm -If \$name"

LABEL="md_inc_end"
EOF
	verbose2 "Adding udev rules: $rules"
	printf '%s\n' "$rules"
done
