#!/bin/bash # # start_udev # # script to initialize /dev by using udev. # # Copyright (C) 2004 Greg Kroah-Hartman # # Released under the GPL v2 only. # # This needs to be run at the earliest possible point in the boot # process. # # Based on the udev init.d script # # Thanks go out to the Gentoo developers for proving # that this is possible to do. # # Yes, it's very verbose, feel free to turn off all of the echo calls, # they were there to make me feel better that everything was working # properly during development... # # don't use udev if sysfs is not mounted. sysfs_dir=/sys export TZ=/etc/localtime [ -d $sysfs_dir/class ] || exit 1 [ -r /proc/mounts ] || exit 1 [ -x /sbin/udevd ] || exit 1 [ -f /etc/udev/udev.conf ] && . /etc/udev/udev.conf udev_root=${udev_root-/dev} if [ -f /dev/.in_sysinit ]; then exec >/dev/console 2>/dev/console "$md5file" fi . "$md5file" >$udev_root/null 2>&1 else ( sed -e 's,#.*,,g' "$i" | \ xargs_simple -n 100 $MAKEDEV -x ) fi fi done fi for devdir in /etc/udev/devices /lib/udev/devices; do [ -d "$devdir" ] || continue pushd $devdir &> "$udev_root/null" set * if [ "$1" != "*" ]; then #echo "Warning: $devdir is deprecated. Please use /etc/udev/makedev.d/." cp -ar "$@" $udev_root/ pushd "$udev_root" &> "$udev_root/null" [ -x /sbin/restorecon ] && /sbin/restorecon "$@" popd &> "$udev_root/null" fi popd &> "$udev_root/null" done } kill_udevd() { if [ -x /sbin/pidof ]; then pid=`/sbin/pidof -x udevd` [ -n "$pid" ] && kill $pid fi } findalias () { local n for n in "$1"/* ; do [ -h "$n" ] && continue [ -d "$n" ] && { findalias "$n" ; continue; } [ "${n##*/}" == "modalias" ] && echo $(cat $n) done } # returns OK if $1 contains $2 strstr() { [ "${1#*$2*}" = "$1" ] && return 1 return 0 } getval() { what=$1 shift for arg; do if strstr "$arg" "$what="; then val=${arg#${what}=*} echo $val return 0 fi done return 1 } wait_for_queue() { local timeout=${1:-0} local ret=0 modprobe scsi_wait_scan &>/dev/null && rmmod scsi_wait_scan if [ $timeout -gt 0 ]; then /sbin/udevadm settle --timeout=$timeout else # by default wait indefinitely /sbin/udevadm settle modprobe scsi_wait_scan &>/dev/null && rmmod scsi_wait_scan while ! /sbin/udevadm settle --timeout=0; do echo echo -n "udev still not settled. Waiting." /sbin/udevadm settle modprobe scsi_wait_scan &>/dev/null && rmmod scsi_wait_scan done fi ret=$? if [ $ret -ne 0 ]; then echo -n "Wait timeout. Will continue in the background." fi return $ret; } export ACTION=add prog=udev ret=0 STRING=$"Starting $prog: " # propagate $udev_root from /sys echo -n "$STRING" # mount the tmpfs on ${udev_root%/}, if not already done LANG=C awk "\$2 == \"${udev_root%/}\" && ( \$3 == \"devtmpfs\" || \$3 == \"tmpfs\" ) { exit 1 }" /proc/mounts && { if LANG=C fgrep -q "none ${udev_root%/}/pts " /proc/mounts; then PTSDIR=$(mktemp -d) mount --move $udev_root/pts "$PTSDIR" fi if LANG=C fgrep -q "none ${udev_root%/}/shm " /proc/mounts; then SHMDIR=$(mktemp -d) mount --move $udev_root/shm "$SHMDIR" fi # First try to mount a devtmpfs on $udev_root mount -n -o mode=0755 -t devtmpfs none "$udev_root" 2>/dev/null \ || mount -n -o mode=0755 -t tmpfs none "$udev_root" mkdir -m 0755 $udev_root/pts mkdir -m 0755 $udev_root/shm if [ -n "$PTSDIR" ]; then mount --move "$PTSDIR" $udev_root/pts rmdir "$PTSDIR" fi if [ -n "$SHMDIR" ]; then mount --move "$SHMDIR" $udev_root/shm rmdir "$SHMDIR" fi ret=$[$ret + $?] } make_extra_nodes cmdline=$(cat /proc/cmdline) kill_udevd > "$udev_root/null" 2>&1 [ -d $udev_root/.udev ] || mkdir -p $udev_root/.udev > "$udev_root/null" 2>&1 UDEV_OPTS="" if [ -f "/sys/class/tty/console/uevent" ]; then # trigger the sorted events echo -e '\000\000\000\000' > /proc/sys/kernel/hotplug if strstr "$cmdline" udevtrace; then UDEV_OPTS="$UDEV_OPTS --debug-trace" fi if strstr "$cmdline" udevlog; then echo 'WARNING: udevlog is active!' >&2 echo "$udev_root/.udev/udev.log can grow big very quick and resides in RAM" >&2 echo 'Turn off udev logging as soon as you booted!' >&2 /sbin/udevd -d -s $UDEV_OPTS 0<>$udev_root/.udev/udev.log 1<>$udev_root/.udev/udev.log 2<>$udev_root/.udev/udev.log else /sbin/udevd -d $UDEV_OPTS fi wait ret=$[$ret + $?] udevtimeout=$(getval udevtimeout $cmdline) if strstr "$cmdline" udevdebug; then /sbin/udevadm control --log-priority=debug fi if strstr "$cmdline" udevinfo; then /sbin/udevadm control --log-priority=info fi if strstr "$cmdline" udevchilds; then /sbin/udevadm control --max-childs=$(getval udevchilds $cmdline) fi if strstr "$cmdline" noiswmd; then /sbin/udevadm control --env=rd_NO_MDIMSM=1 fi . /etc/sysconfig/network if [ "$BIOSDEVNAME" = "yes" ]; then /sbin/udevadm control --property=UDEV_BIOSDEVNAME=1 fi if [ "$BIOSDEVNAME" = "no" ]; then /sbin/udevadm control --property=UDEV_BIOSDEVNAME=0 fi /sbin/udevadm control --env=STARTUP=1 if strstr "$cmdline" modprobedebug; then /sbin/udevadm control --env=MODPROBE_OPTIONS="-s -v -q" echo findalias /sys | while read modules ; do if [ -n "$modules" ]; then echo "Loading modules for $modules in 5 seconds" sleep 5 /sbin/modprobe -a -v -q $modules wait_for_queue $udevtimeout fi done echo "Triggering Rest" fi /sbin/udevadm trigger --type=subsystems --action=add /sbin/udevadm trigger --type=devices --action=add ret=$[$ret + $?] wait_for_queue $udevtimeout ret=$[$ret + $?] wait /sbin/udevadm control --env=STARTUP= else echo -n " kernel too old for this udev version " /sbin/udevd -d $UDEV_OPTS ret=10 fi ret=$[$ret + $?] [ $ret -eq 0 ] && success $"$STRING" || failure $"$STRING" echo exit 0