#!/bin/sh
# geninitrd mod: udev
USE_UDEV=${USE_UDEV:-yes}

#
# TODO:
# - make udev start before insmods
# - make proper use of USE_UDEV - don't copy rules if USE_UDEV is off no!

inst_rules() {
	local _rule _found d

	inst_d "/lib/udev/rules.d"
	for _rule in "$@"; do
		for d in /lib/udev/rules.d /etc/udev/rules.d /lib/geninitrd/udev-rules; do
			if [ -f $d/$_rule ]; then
				inst $d/$_rule /lib/udev/rules.d/$_rule
			fi
		done
	done

}

# setup geninitrd module
# @access	public
setup_mod_udev() {
	udevd=$(find_tool $initrd_dir/udevd /sbin/initrd-udevd)
	udevadm=$(find_tool $initrd_dir/udevadm /sbin/initrd-udevadm)

	if [ "$kernel_version" -lt "002006" ] || [ ! -x "$udevd" -o ! -x "$udevadm" -o ! -f /etc/udev/udev.conf ]; then
		USE_UDEV=no
	fi

	if is_yes "$USE_UDEV"; then
		. /etc/udev/udev.conf
	fi
}

# generate initrd fragment
# @access	public
initrd_gen_udev() {
	verbose "Setting up udev..."

	inst_d /sbin /etc/udev /lib/udev
	inst_exec $udevd /sbin/udevd
	inst_exec $udevadm /sbin/udevadm
	inst /etc/udev/udev.conf /etc/udev/udev.conf
	# standard udev rules
	inst_rules 50-udev-default.rules 60-persistent-storage.rules 61-persistent-storage-edd.rules 80-drivers.rules 95-udev-late.rules \
		60-pcmcia.rules 50-firmware.rules 10-dm.rules 11-dm-lvm.rules 13-dm-disk.rules 95-dm-notify.rules
	# initrd dedicated rules
	inst_rules 01-ignore.rules 59-persistent-storage.rules 61-persistent-storage.rules 11-dm.rules

	local e
	for e in ata_id cdrom_id collect firmware scsi_id v4l_id; do
		if [ -e "$initrd_dir/udev/$e" ]; then
			inst_exec $initrd_dir/udev/$e /lib/udev/$e
		elif [ -e "/lib/udev/$e" ]; then
			inst_exec /lib/udev/$e /lib/udev/$e
		fi
	done

	# basic group file
	local _lib
	inst /etc/nsswitch.conf /etc/nsswitch.conf
	for _lib in $(get_libdir LIBDIR); do
		if (ls /$_lib/libnss_files*.so* > /dev/null 2>&1); then
			inst_exec /$_lib/libnss_files*.so* /$_lib/
		fi
	done
	awk -F: ' { if ($3 < 1000) { print $1":"$2":"$3":" } } ' /etc/group > $DESTDIR/etc/group

	# blkid installed by mod-blkid
	if ! is_yes "$USE_BLKID"; then
		warn "BLKID support missing"
	fi

	local dir dmsetup
	for dir in $initrd_dir /sbin; do
		if [ -x "$dir/dmsetup" ] &&
			[ "$($dir/dmsetup udevcookies 2>&1 | grep -c 'Command not supported')" -eq 0 ]; then
			dmsetup=$dir/dmsetup
			break
		fi
	done
	if [ -z "$dmsetup" ]; then
		warn "Can't find dmsetup with udev support"
	else
		inst_exec $dmsetup /sbin/dmsetup
	fi

	mount_dev
	mount_sys
	mount_run
	add_linuxrc <<-'EOF'
		: 'Starting udev'
		mkdir /run/udev
		/sbin/udevd --daemon
		/sbin/udevadm trigger --type=subsystems --action=add
		/sbin/udevadm trigger --type=devices --action=add
		/sbin/udevadm settle
	EOF
}

initrd_gen_stop_udevd() {
	if ! is_yes "$USE_UDEV"; then
		return
	fi
	add_linuxrc	<<-'EOF'
		/sbin/udevadm control --exit
		/sbin/udevadm info --cleanup-db
	EOF
}

# generate initrd fragment
# @access	public
initrd_gen_mdev() {
	debug "Setting up mdev..."

	busybox_applet mdev uevent
	ln -s busybox $DESTDIR/bin/mdev
	ln -s busybox $DESTDIR/bin/uevent

	cat > $DESTDIR/etc/mdev.conf	<<-'EOF'
# Provide user, group, and mode information for devices.  If a regex matches
# the device name provided by sysfs, use the appropriate user:group and mode
# instead of the default 0:0 660.
#
# Syntax:
# %s %d:%d %s
# devicename_regex user:group mode

null		0:0 666
zero		0:0 666
random		0:0 666
urandom		0:0 666

kmsg		0:0 644
kmem		0:9 000
mem		0:9 640
port		0:9 640

snapshot	0:0 600

console		0:5 600
ptmx		0:5 666
tty[0-9]*	0:5 600

ttyS[0-9]*	0:16 660

fd[0-9]*	0:19 660

sd[a-z]*	0:6 660
hd[a-z]*	0:6 660
	EOF

	mount_dev
	mount_sys
	mount_run
	add_linuxrc	<<-'EOF'
		# \n needed in mdev.seq
		echo > /dev/mdev.seq
		uevent mdev &
		mdev -s
	EOF
}

initrd_gen_stop_mdev() {
	add_linuxrc     <<-'EOF'
		killall uevent > /dev/null 2>&1
	EOF
}
