X-Git-Url: http://git.pld-linux.org/?a=blobdiff_plain;f=start_udev;h=bf64dc55b3135c427e04ba82fc25514a97f844f9;hb=refs%2Fheads%2Fsystemd-218;hp=a21a18aa380b12e8eaedf023d1b56021eb2b9c2a;hpb=d95b8af36e0ee2cd90a4affab177925cb6cc3463;p=packages%2Fsystemd.git diff --git a/start_udev b/start_udev old mode 100644 new mode 100755 index a21a18a..bf64dc5 --- a/start_udev +++ b/start_udev @@ -8,12 +8,12 @@ # # Released under the GPL v2 only. # -# This needs to be run at the earliest possible point in the boot +# 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 +# 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, @@ -21,139 +21,155 @@ # properly during development... # default value, if no config present. -udev_root="/dev/" +udev_root="/dev" sysfs_dir="/sys" udevd_timeout=8 # don't use udev if sysfs is not mounted. [ -d $sysfs_dir/class ] || exit 1 [ -r /proc/mounts ] || exit 1 -[ -x /sbin/udev ] || exit 1 [ -f /etc/udev/udev.conf ] && . /etc/udev/udev.conf . /etc/rc.d/init.d/functions prog=udev bin=/sbin/udev -udevd=/sbin/udevd +udevd=/lib/udev/udevd +# trim traling slash, code expects it not to be there +udev_root=${udev_root%/} + +create_static_nodes() { + /sbin/kmod static-nodes --format=tmpfiles | \ + while read type file mode uid gid age dev ; do + case $type in + d|D) + mkdir -p --mode=$mode $file + ;; + *) + oldIFS=$IFS + IFS=":" + set -- $dev + maj=$1 + min=$2 + IFS=$oldIFS + mknod --mode=$mode $file $type $maj $min + ;; + esac + [ $uid = "-" ] || chown $uid $file + [ $gid = "-" ] || chgrp $gid $file + done +} -make_extra_nodes () { +make_extra_nodes() { grep '^[^#]' /etc/udev/links.conf | \ while read type name arg1; do - [ "$type" -a "$name" -a ! -e "$udev_root/$name" -a ! -L "/dev/$name" ] ||continue - case "$type" in - L) ln -s $arg1 $udev_root/$name ;; - D) mkdir -p $udev_root/$name ;; - *) echo "links.conf: unparseable line ($type $name $arg1)" ;; - esac + [ "$type" -a "$name" -a ! -e "$udev_root/$name" -a ! -L "/dev/$name" ] ||continue + case "$type" in + L) ln -s $arg1 $udev_root/$name ;; + D) mkdir -p $udev_root/$name ;; + M) mknod -m 600 /dev/$name $arg1 ;; + *) echo "links.conf: unparseable line ($type $name $arg1)" ;; + esac done - cp -a /lib/udev/devices/* /dev/ >/dev/null 2>&1 || : + [ -d /lib/udev/devices ] && cp -a /lib/udev/devices/* /dev/ >/dev/null 2>&1 || : + [ -d /lib64/udev/devices ] && cp -a /lib64/udev/devices/* /dev/ >/dev/null 2>&1 || : } kill_udevd() { if [ -x /sbin/pidof ]; then - pid=`/sbin/pidof -x udevd` + pid=$(/sbin/pidof -x udevd) [ -n "$pid" ] && kill $pid fi } -supported_kernel() { - if [ -f "/sys/class/tty/console/uevent" ]; then - 2.[012345].*) return 1 ;; - esac - return 0 +set_hotplug_handler() { + echo "" > /proc/sys/kernel/hotplug } -set_hotplug_handler() { - echo "" > /proc/sys/kernel/hotplug +# find subdirs mounted under $udev_root +get_dev_mounts() { + awk -vudev_root="$udev_root/" ' + BEGIN { + len = length(udev_root); + } + + substr($2, 1, len) == udev_root { + print substr($2, len + 1) + }' /proc/mounts } - return 0 + +show "Starting udev"; busy + export ACTION=add prog=udev ret=0 -show "Starting udev" -busy -if ! supported_kernel; then - fail -fi -# mount the tmpfs on ${udev_root%/}, if not already done -LANG=C awk "\$2 == \"${udev_root%/}\" && \$3 == \"tmpfs\" { exit 1 }" /proc/mounts && { - if LANG=C fgrep -q "none ${udev_root%/}/pts " /proc/mounts; then - PTSDIR=$(mktemp -d ${TMPDIR:-/tmp}/tmpXXXXXX) - mount --move $udev_root/pts "$PTSDIR" - fi - if LANG=C fgrep -q "none ${udev_root%/}/shm " /proc/mounts; then - SHMDIR=$(mktemp -d ${TMPDIR:-/tmp}/tmpXXXXXX) - mount --move $udev_root/shm "$SHMDIR" - fi - 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" +# mount the devtmpfs on $udev_root, if not already done +awk "\$2 == \"$udev_root\" && \$3 == \"devtmpfs\" { exit 1 }" /proc/mounts && { + submounts=$(get_dev_mounts) + + if [ "$submounts" ]; then + # mount to temporary location to be able to move submounts + # this needs writable TMPDIR:-/tmp, so it won't work in early boot + # but fix is simple: use initramfs instead of romfs + devdir=$(mktemp -d ${TMPDIR:-/tmp}/tmpXXXXXX) + else + devdir=$udev_root fi - if [ -n "$SHMDIR" ]; then - mount --move "$SHMDIR" $udev_root/shm - rmdir "$SHMDIR" - fi - + mount -n -o mode=0755 -t devtmpfs devtmpfs "$devdir" ret=$(( $ret + $? )) + + # relocate submounts + for dir in $submounts; do + mount -n --move $udev_root/$dir $devdir/$dir + ret=$(( $ret + $? )) + done + + if [ "$submounts" ]; then + mount -n --move $devdir $udev_root + rmdir $devdir + fi } kill_udevd > "$udev_root/null" 2>&1 -if [ -f "/sys/class/tty/console/uevent" ]; then - # Start udevd daemon - udevd --daemon - - # Making extra nodes - make_extra_nodes - - # Setting default hotplug handler +# Create required static device nodes for the current kernel +create_static_nodes + +# Start udevd daemon +$udevd --daemon; rc=$? +test $rc -eq 0 && ok || fail +ret=$(( $ret + $rc )) + +# Making extra nodes +show "Setup extra nodes"; busy +make_extra_nodes; rc=$? +test $rc -eq 0 && ok || fail +ret=$(( $ret + $rc )) + +if [ -f /sys/class/tty/console/uevent ]; then + # Setting default hotplug handler set_hotplug_handler - - # retrigger all events - mkdir -p /dev/.udev/queue - list=$(echo /sys/bus/*/devices/*/uevent) - list="$list $(echo /sys/class/*/*/uevent)" - list="$list $(echo /sys/block/*/uevent /sys/block/*/*/uevent)" - for i in $list; do - case "$i" in - */device/uevent|*\**) - continue - ;; - */class/mem/*|*/class/tty/*) - first="$first $i" - ;; - */block/md*) - last="$last $i" - ;; - */*) - default="$default $i" - ;; - esac - done + ret=$(( $ret + $? )) - # trigger the sorted events - for i in $first $default $last; do - echo "add" > "$i" - done + # retrigger all events + show "Retrigger subsystems events"; busy + /sbin/udevadm trigger --type=subsystems --action=add; rc=$? + test $rc -eq 0 && ok || fail + ret=$(( $ret + $rc )) + show "Retrigger devices events"; busy + /sbin/udevadm trigger --type=devices --action=add; rc=$? + test $rc -eq 0 && ok || fail + ret=$(( $ret + $rc )) # wait for the events to finish - loop=300 - while test -d /dev/.udev/queue; do - sleep 0.1; - test "$loop" -gt 0 || break - loop=$(($loop - 1)) - done + show "udevadm settle"; busy + /sbin/udevadm settle; rc=$? + test $rc -eq 0 && ok || fail + ret=$(( $ret + $rc )) else - echo "udev requires a kernel >= 2.6.15, not started." - exit 0 + echo "Kernel too old for this udev version" fi -ret=$(( $ret + $? )) -[ $ret -eq 0 ] && ok || fail -exit 0 +exit $ret