diff --git a/package/base/rockinitrd/init b/package/base/rockinitrd/init index f249b62eb..c51813b92 100644 --- a/package/base/rockinitrd/init +++ b/package/base/rockinitrd/init @@ -35,6 +35,17 @@ initrd_mount() { # {{{ return ${?} } # }}} +emit_udev_events() { # {{{ + while read uevent; do + echo 1 > $uevent + done < <( find /sys -name uevent ) + udevwait=0 + while [ -d /dev/.udev/queue -a $udevwait -lt 300 ] ; do + sleep 1 + (( udevwait++ )) + done +} # }}} + PATH="/sbin:/usr/sbin:/bin/:/usr/bin" rootfs="" @@ -63,14 +74,7 @@ echo "loading kernel modules" . /etc/conf/kernel # create nodes for devices already in kernel -while read uevent; do - echo 1 > $uevent -done < <( find /sys -name uevent ) -udevwait=0 -while [ -d /dev/.udev/queue -a $udevwait -lt 300 ] ; do - sleep 1 - (( udevwait++ )) -done +emit_udev_events for x in /etc/conf/* ; do [ "${x}" == "/etc/conf/kernel" ] && continue @@ -99,5 +103,8 @@ mount -n --move /dev /root/dev # re-start real-system udevd, so group/permission settings get honored killall udevd /sbin/udevd --daemon +# re-emit events so permissions get corrected and rules which need +# additional programs can be applied (like persistent storage, et alas) +emit_udev_events exec chroot . $real_init "${@}" < /dev/console > /dev/console 2>&1 diff --git a/package/base/udev/rules/05-early-udev.rules b/package/base/udev/rules/05-early-udev.rules new file mode 100644 index 000000000..ef2cec35f --- /dev/null +++ b/package/base/udev/rules/05-early-udev.rules @@ -0,0 +1,8 @@ +# ignore these until someone needs them +SUBSYSTEM=="drivers", OPTIONS="ignore_device" +SUBSYSTEM=="module", OPTIONS="ignore_device" + +# sysfs is populated after the event is sent +ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus" +ACTION=="add", SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt" +ACTION=="add", SUBSYSTEM=="net", WAIT_FOR_SYSFS="address" diff --git a/package/base/udev/devfs.rules b/package/base/udev/rules/50-devfs.rules similarity index 100% rename from package/base/udev/devfs.rules rename to package/base/udev/rules/50-devfs.rules diff --git a/package/base/udev/rules/60-persistent-storage.rules b/package/base/udev/rules/60-persistent-storage.rules new file mode 100644 index 000000000..9424322d6 --- /dev/null +++ b/package/base/udev/rules/60-persistent-storage.rules @@ -0,0 +1,51 @@ +# persistent storage links: /dev/{disk,tape}/{by-id,by-uuid,by-label,by-path,by-name} +# scheme based on "Linux persistent device names", 2004, Hannes Reinecke + +ACTION!="add", GOTO="persistent_storage_end" +SUBSYSTEM!="block", GOTO="persistent_storage_end" + +# skip rules for inappropriate block devices +KERNEL=="ram*|loop*|fd*|nbd*", GOTO="persistent_storage_end" + +# never access removable ide devices, the drivers are causing event loops on open() +KERNEL=="hd*[!0-9]", SYSFS{removable}=="1", DRIVER!="ide-cdrom", GOTO="persistent_storage_end" +KERNEL=="hd*[0-9]", SYSFS{../removable}=="1", DRIVER!="ide-cdrom", GOTO="persistent_storage_end" + +# by-id (hardware serial number) +KERNEL=="hd*[!0-9]", IMPORT{program}="/sbin/ata_id --export $tempnode" +KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" +KERNEL=="hd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" + +KERNEL=="sd*[!0-9]|sr*|st*", SYSFS{ieee1394_id}=="*", ENV{ID_SERIAL}="$sysfs{ieee1394_id}", ENV{ID_BUS}="ieee1394" +KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -s %p -d $tempnode" +KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -a -s %p -d $tempnode" +KERNEL=="dasd*[!0-9]", IMPORT{program}="/sbin/dasd_id --export $tempnode" +KERNEL=="sd*[!0-9]|sr*|dasd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="st*", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}" + +# for partitions import parent information +KERNEL=="sd*[0-9]|dasd*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + +# by-path (shortest physical path) +KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", IMPORT{program}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="st*", ENV{ID_TYPE}=="?*", IMPORT{program}="/sbin/path_id %p", SYMLINK+="tape/by-path/$env{ID_PATH}" +KERNEL=="sr*|st*", GOTO="persistent_storage_end" +KERNEL=="*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" + +# by-label/by-uuid (filesystem properties) +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_storage_end" +IMPORT{program}="/sbin/vol_id --export $tempnode" +ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" +ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" + +# BIOS Enhanced Disk Device +KERNEL=="*[!0-9]", IMPORT{program}="/sbin/edd_id --export $tempnode" +KERNEL=="*[!0-9]", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}" +KERNEL=="*[0-9]", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part%n" + +KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/dmsetup info -c --noopencount --noheadings -o name -j %M -m %m", SYMLINK="disk/by-name/%c" + +LABEL="persistent_storage_end" diff --git a/package/base/udev/permissions.rules b/package/base/udev/rules/permissions.rules similarity index 100% rename from package/base/udev/permissions.rules rename to package/base/udev/rules/permissions.rules diff --git a/package/base/udev/scripts/scsi-devfs.sh b/package/base/udev/scripts/scsi-devfs.sh index 0c899c8d9..3018d6ab5 100644 --- a/package/base/udev/scripts/scsi-devfs.sh +++ b/package/base/udev/scripts/scsi-devfs.sh @@ -1,73 +1,82 @@ -#!/bin/bash +#!/bin/sh -e +# Inspired from a script by Remco . +# Support for /dev/discs/* and /dev/cdroms/* by Daniel Mueller . # -# scsi-devfs.sh: udev external PROGRAM script -# -# Copyright 2004 Richard Gooch -# Copyright 2004 Fujitsu Ltd. -# Distributed under the GNU Copyleft version 2.0. -# -# return devfs-names for scsi-devices -# Usage in udev.rules: -# BUS="scsi", PROGRAM="/lib/udev/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%c{2} %k" +# BUS="scsi", PROGRAM="/etc/udev/scsi-devfs.sh %k %b %n", \ +# NAME="%c{1}", SYMLINK="%k %c{2}" -# Find out where sysfs is mounted. Exit if not available -sysfs=`grep -F sysfs /proc/mounts | awk '{print $2}'` -if [ "$sysfs" = "" ]; then - echo "sysfs is required" - exit 1 -fi -cd $sysfs/bus/scsi/devices +get_ide_offset() { + local num=0 + local dev -case "$1" in - sd*) - # Extract partition component - if [ "$3" = "" ]; then - lpart="disc" - spart="" - else - lpart="part$3" - spart="p$3" - fi - ;; - sr*) - lpart="cdrom" - spart="" - ;; - st*) - # Not supported yet - exit 1 - ;; - sg*) - lpart="generic" - spart="" - ;; - *) - exit 1 - ;; -esac + for dev in /proc/ide/*/media; do + if [ "`cat $dev`" = "$1" ]; then + num=$(($num + 1)) + fi + done -# Extract SCSI logical address components -scsi_host=`echo $2 | cut -f 1 -d:` -scsi_bus=`echo $2 | cut -f 2 -d:` -scsi_target=`echo $2 | cut -f 3 -d:` -scsi_lun=`echo $2 | cut -f 4 -d:` + echo $num +} -# Generate common and logical names -l_com="bus$scsi_bus/target$scsi_target/lun$scsi_lun/$lpart" -l_log="scsi/host$scsi_host/$l_com" +get_next_number() { + local num=0 + local dev + local offset=`get_ide_offset $2` + + if [ "$2" = "disk" ]; then + local DRIVE="${1%%[0-9]*}" + local DEVLIST="/sys/block/sd*" + else + local DRIVE=$1 + local DEVLIST="/sys/block/sr*" + fi -if [ -d /dev/discs ] ; then - for x in /dev/discs/disc* ; do - if readlink `ls -d $x/* | awk '{print $0; exit;}'` | grep -q "${l_log%${lpart}}" ; then - x=`echo $x | cut -f3 -dc` # gives the number in disc0 - break - fi - unset x + for dev in $DEVLIST; do + [ "${dev#/sys/block/}" = "$DRIVE" ] && break + num=$(($num + 1)) done -fi -if [ -z "${x}" ] ; then - x="`ls /dev/discs/ 2> /dev/null | grep -c .`" -fi + echo $(($offset + $num)) +} + +# the format is "HOST:BUS:TARGET:LUN" +SCSI_ID=$2 +HOST=${SCSI_ID%%:*} +SCSI_ID=${SCSI_ID#*:} +BUS=${SCSI_ID%%:*} +SCSI_ID=${SCSI_ID#*:} +TARGET=${SCSI_ID%%:*} +SCSI_ID=${SCSI_ID#*:} +LUN=$SCSI_ID + +case "$1" in +scd*|sr*) + # CDROM/DVD + NAME=cd + LINK="cdroms/cdrom"`get_next_number $1 cdrom` + ;; +sd*) + if [ "$3" ]; then + NAME=part$3 + LINK="discs/disc"`get_next_number $1 disk`/part${3} + else + NAME=disc + LINK="discs/disc"`get_next_number $1 disk`/disc + fi + ;; +nst*) + NAME=$(echo "$1" | sed -e 's/nst0m/nmt/') + [ $NAME = "mt0" ] && LINK=ntape + ;; +st*) + NAME=$(echo "$1" | sed -e 's/st0m/mt/') + [ $NAME = "mt0" ] && LINK=tape + ;; +sg*|*) + NAME=generic + ;; +esac + +echo scsi/host$HOST/bus$BUS/target$TARGET/lun$LUN/$NAME $LINK -echo $l_log discs/disc${x}/${lpart} +exit 0 diff --git a/package/base/udev/udev.conf b/package/base/udev/udev.conf index d029bf084..afee2e8dd 100644 --- a/package/base/udev/udev.conf +++ b/package/base/udev/udev.conf @@ -38,10 +38,9 @@ udev_pm() { # mkinitrd quickhack - wouldn't be included in the initrd otherwise touch $root/lib/udev/devices/{pts,shm}/.empty - cp -v $confdir/devfs.rules $root/etc/udev/rules.d/50-udev.rules + cp -v $confdir/rules/* $root/etc/udev/rules.d/ cp -v $confdir/scripts/*.sh $root/lib/udev/ chmod +x $root/lib/udev/*.sh - cp -v $confdir/permissions.rules $root/etc/udev/rules.d/ install -v extras/path_id $root/sbin/ }