#!/bin/sh

msg='Starting udevd...'

run() {
	# Save the environment, to use it inside udev filters.
	showenv -q > /dev/.initramfs/env

	mkdir -p /dev/.udev/db/
	udevd --daemon --resolve-names=never

	udevadm control --property=STARTUP=1
	udevadm trigger

	# Load user-defined modules
	load_modules postudev

	local name eventgroup handler fail=

	# 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))

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

		# Stop queue to avoid race
		udevadm control --stop-exec-queue

		# Our main goal is mounting root.
		if [ -e "$rootmnt/$INIT" ]; then
			udevadm control --start-exec-queue
			break
		fi

		mkdir -p -- "$handler_eventdir"

		for eventgroup in "$udev_eventdir"/*; do
			[ ! -d "$eventgroup" ] ||
				mv "$eventgroup" "$handler_eventdir"
		done

		# Some handler uses udev, so we have to start it before
		# start queue handlers.
		udevadm control --start-exec-queue

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

			[ -x "$handler" ] &&
				dir_not_empty "$handler_eventdir/$name" ||
				continue

			verbose "Running $name handler ..."
			if ! "$handler"; then
				fail="$name"
				break 2
			fi
		done

		# Remove processed files.
		rm -rf -- "$handler_eventdir"

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

	if [ -n "$fail" ]; then
		error "event handler failed: $fail"
		return 1
	fi

	if [ ! -e "$rootmnt/$INIT" ]; then
		error "Unable to mount root"
		return 1
	fi
}
