#!/bin/sh

msg='Processing kernel events...'
check() {
	local f
	for f in "/lib/initrd/$1"/*; do
		"$f" ${2-} || return 1
		[ -n "${2-}" ] || debug "Check '${f##*/}' success!"
	done
}

run() {
	local handler

	# It is not currently limit since the execution of programs
        # takes time, which is not counted. But we do not want to use
        # additional utilities to calculate the time limit.
	local sec=$((${ROOTDELAY:-180}*10))
	local force=$(($sec-${RAIDDELAY:-$(($sec/30))}*10))

	while [ "$sec" -gt 0 ]; do
		# Wait udev event queue
		udevadm settle --timeout=5

		! check success -q ||
			break

		# Run hooks to repair non-fatal boot-blocking problems once
		if [ "$sec" = "$force" -a -d /lib/initrd/trouble ]; then
			verbose "Taking too long, forcing ..."
			for handler in /lib/initrd/trouble/*; do
				name="${handler##*/}"
				if ! "$handler"; then
					error "trouble with handler: ${name#*-}"
					return 1
				fi
			done
		fi

		local ev_udev= ev_hdlr=

		! glob -q "$udev_eventdir"/*    || ev_udev=1
		! glob -q "$handler_eventdir"/* || ev_hdlr=1

		if [ -z "$ev_udev$ev_hdlr" ]; then
			sleep 0.1
			sec=$(($sec-1))
			continue
		fi

		[ -z "$ev_udev" ] ||
			mv -- "$udev_eventdir"/* "$handler_eventdir"

		# Run udev handlers
		for handler in /lib/initrd/handlers/*; do
			name="${handler##*/}"
			name="${name#*-}"

			glob -q "$handler_eventdir/$name"* ||
				continue

			verbose "Running $name handler ..."
			if ! "$handler"; then
				error "event handler failed: $name"
				return 1
			fi
		done
		remove_done_events "$handler_eventdir"

		sleep 0.1
		sec=$(($sec-1))
	done

	check success ||
		return 1
}
