Search:  
Gentoo Wiki

UDEV_Overview

Wikipedia has an article on:
Udev

Contents

Introduction

Normally, devices get assigned device nodes (/dev/sda) when the kernel probes them at boot and continue until the machine is shut down. With transient devices such as USB gadgets that are added and removed from the system dynamically, there is no guarantee that a device will be assigned the same node everytime it is plugged in. This can negate the effectiveness of /etc/fstab and play havoc with the scripting/programming of the gadgets.

UDEV seeks to alleviate this problem by having devices assigned not only to the "standard" device node, but an additional specific "custom" node determined by the system administrator.

For example, a particular USB flash drive may be assigned to a particular "custom" node based on the model and serial numbers of the gadget. This could allow a particular flash drive to be assigned to /dev/co_fd (company flash drive), which /etc/fstab could then mount to, say, /mnt/company_data. While another flash drive of the same model, but different serial number, might be assigned to /dev/my_fd (my flash drive) which is mounted to /mnt/my_data.

Writing custom udev rules

D.Drake has written excellent instructions on writing custom udev rules. The latest version can be found at http://www.reactivated.net/writing_udev_rules.html .

In short, place your custom rules here:

# nano /etc/udev/rules.d/10-local.rules

And re-start udev with:

# udevstart

or just have udev rescan sysfs with:

# udevtrigger

Example rules

Note: It looks like the SYSFS keyword have been renamed to ATTRS in the latest stable version of udev in portage

change Logitech USB mouse resolution on every insertion

SYSFS{manufacturer}=="Logitech", SYSFS{product}=="USB-PS/2 Optical Mouse", NAME="input/%k", MODE="0644", RUN+="/usr/bin/logitech_applet -s 800"

mount USB-Sticks

One can use the following rule to auto-mount usb sticks:

# mount block device when added
SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/local/bin/mount-device.sh /dev/%k"

mount-device.sh

To do anything useful you need the script /usr/local/bin/mount-device.sh:

#!/bin/sh

DEVICE="$1"
GID=`grep plugdev /etc/group | cut -d: -f 3`

if [ "$DEVICE" = "" ] ; then exit 1 ; fi

# wait a moment till' hal has information about the device
sleep 2

HAL_UDI=`hal-find-by-property --key block.device --string "$DEVICE"`

function get_hal_label {
    CUR_UDI=$1
    LABEL=""
    COUNTER=0;
    while [ -z "$LABEL" -a $COUNTER -lt 4 ]; do
	LABEL=`hal-get-property --key volume.label --udi "$CUR_UDI" 2>/dev/null`
	if [ -z "$LABEL" ]; then
	    LABEL=`hal-get-property --key storage.serial --udi "$CUR_UDI" 2>/dev/null`
	fi
	CUR_UDI=`hal-get-property --key info.parent --udi "$CUR_UDI" 2>/dev/null`
	let COUNTER=COUNTER+1
    done
    
    if [ -z $LABEL ]; then
	LABEL=${DEVICE##/dev/}
    fi
}

function get_hal_removable {
    CUR_UDI=$1
    REMOVABLE=""
    COUNTER=0
    while [ -z "$REMOVABLE" -a $COUNTER -lt 4 ]; do
	REMOVABLE=`hal-get-property --key storage.removable --udi "$CUR_UDI" 2>/dev/null`
	if [ -z "$REMOVABLE" ]; then
	    BUS=`hal-get-property --key storage.bus --udi "$CUR_UDI" 2>/dev/null`
	    if [ "$BUS" = "usb" ]; then
		REMOVABLE="true"
	    fi
	fi
	CUR_UDI=`hal-get-property --key info.parent --udi "$CUR_UDI" 2>/dev/null`
	let COUNTER=COUNTER+1
    done
    
    if [ -z "$REMOVABLE" ]; then
	logger "assuming $HAL_UDI is removable for safety reasons"
	REMOVABLE="true"
    fi
}

if [ -z "$HAL_UDI" ]; then # can't find device in hal db
    logger "hald didn't know about $DEVICE"
    LABEL=${DEVICE##/dev/}
else # device found in hal db.
    get_hal_label "$HAL_UDI"
    get_hal_removable "$HAL_UDI"
fi

logger "Mounting HAL_UDI $HAL_UDI as $DEVICE to $LABEL (removable: $REMOVABLE)"

SYNC_OPT=""

if [ $REMOVABLE = "true" ]; then
    SYNC_OPT="--sync"
fi

pmount --umask 007 $SYNC_OPT "$DEVICE" "$LABEL"

# if you do not want to use pmount (why should you?)
#MOUNTPOINT=/media/${LABEL}
#mkdir -p "$MOUNTPOINT" &&
#touch "$MOUNTPOINT"/.created_by_pmount &&
#mount "$DEVICE" "$MOUNTPOINT" -o gid=$GID,umask=007 ||
#rm "$MOUNTPOINT"/.created_by_pmount &&
#rmdir "$MOUNTPOINT"


The file .created_by_pmount is created to make pumount remove the mount point after unmounting the filesystem. Typically /usr/lib/hal/hal-unmount.sh calls pumount when unplugging the USB stick. Therefore pmount should be installed!

References

Useful commands

'rc-update -s' - show what's been updated and at what level
'less /proc/scsi/scsi'
'ls /sys'
'udevinfo' - 'udevinfo -n /dev/hda -q all'
             'udevinfo -q all -d | less'
             'udevinfo -a -p /sys/class/scsi_generic/sg0' - look at a device chain
             'udevinfo -a -p $(udevinfo -q path -n /dev/hda)' - look at device chain via the /dev node (check dmesg for newly added hardware)

Troubleshooting guidance

UDEV troubleshooting algorithm, as of version 081 http://www.reactivated.net/writing_udev_rules.html remains the definitive reference. The following guidance may also be of use.


  1. Edit /etc/udev/udev.conf udev_log line needs to read:
    udev_log="debug"
  2. You may need to reboot, and then figure where the output is going. Mine went to /var/log/everything/current
  3. Try something in /etc/udev/rules.d/10-udev.rules, udevcontrol reload_rules.
  4. Cycle your USB device.
  5. If success (you got the desired rule to fire, /dev/whatever is groovy), GOTO 8
  6. Else, read /var/log/everything/current
  7. Attempt to pinpoint the /etc/udev/rules.d/50-udev.rules entry that _did_ fire. Google. Try www.gentoo-wiki.info. Try forums.gentoo.org. Try bugzilla. Try the #gentoo* channels on freenode. Slaughter chicken, examine entrails.
  8. UDEV automatically translates "unsafe" characters into underscores which can cause problems with some rules. Therefore, if your rule(s) depend on special names and don't seem to be working, manually check /sys to confirm. As an example, I had a recent peroblem with udevinfo giving me 'ATTRS{name}=="cx88 IR _Hauppauge Nova-T DVB-T"' whereas the rule would only work with 'ATTRS{name}=="cx88 IR (Hauppauge Nova-T DVB-T"'. If you are unsure of what the name really is, try hooking the value directly out of sysfs e.g.
    cat /sys/class/input/input6/name
    cx88 IR (Hauppauge Nova-T DVB-T

    You have been warned!
  9. GOTO 2.
  10. Rejoice and knock one out, you did it. Restore /etc/udev/udev.conf.

Important files

Further hints relating to udev

The udevd daemon requires Unix Domain Sockets in order to operate. If the unix module is not built into the kernel, it is neccessary to apply a Fix to allow Unix Domain Sockets as a module to the startup scripts. This loads the necessary support module, before the udevd daemon is started.

Retrieved from "http://www.gentoo-wiki.info/UDEV"

Last modified: Tue, 08 Apr 2008 09:53:00 +0000 Hits: 53,882