From mboxrd@z Thu Jan 1 00:00:00 1970 From: md@Linux.IT (Marco d'Itri) Date: Sat, 02 Sep 2006 09:06:53 +0000 Subject: scripts for persistent names support Message-Id: <20060902090653.GA4424@wonderland.linux.it> MIME-Version: 1 Content-Type: multipart/mixed; boundary="mYCpIKhGyMATD0i+" List-Id: To: linux-hotplug@vger.kernel.org --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I implemented both the "try again later" and "use a temporary file now" methods to work around the read-only root problem. Removing the part of the code you do not need is trivial, and I expect that everybody will only use the scripts as examples anyway. -- ciao, Marco --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=write_cd_rules #!/bin/sh -e RULES_FILE="/etc/udev/rules.d/z25_persistent-cd.rules" . /lib/udev/hotplug.functions ############################################################################## find_next_available() { raw_find_next_available "$(find_all_rules 'SYMLINK+=' $1)" } write_rule() { local match="$1" local link="$2" local comment="$3" { if [ "$PRINT_HEADER" ]; then PRINT_HEADER= echo "# This file was automatically generated by the $0" echo "# program, probably run by the cd-aliases-generator.rules rules file." echo "#" echo "# You can modify it, as long as you keep each rule on a single line" echo "# and set the \$GENERATED variable." echo "" fi [ "$comment" ] && echo "# $comment" echo "$match, SYMLINK+=\"$link\", ENV{GENERATED}=\"1\"" } >> $RULES_FILE SYMLINKS="$SYMLINKS $link" } ############################################################################## if [ -z "$DEVPATH" ]; then echo "Missing \$DEVPATH." >&2 exit 1 fi if [ -z "$ID_CDROM" ]; then echo "$DEVPATH is not a CD reader." >&2 exit 1 fi # Exit if the rules file should not be written yet. abort_if_run_early # Prevent concurrent processes from modifying the file at the same time. lock_rules_file # Check if the rules file is writeable. choose_rules_file link_num=$(find_next_available 'cdrom[0-9]*') match="ENV{ID_CDROM}==\"?*\", ENV{ID_PATH}==\"$ID_PATH\"" comment="$ID_MODEL ($ID_PATH)" write_rule "$match" "cdrom$link_num" "$comment" [ "$ID_CDROM_CD_R" -o "$ID_CDROM_CD_RW" ] && \ write_rule "$match" "cdrw$link_num" [ "$ID_CDROM_DVD" ] && \ write_rule "$match" "dvd$link_num" [ "$ID_CDROM_DVD_R" -o "$ID_CDROM_DVD_RW" -o "$ID_CDROM_DVD_RAM" ] && \ write_rule "$match" "dvdrw$link_num" unlock_rules_file echo $SYMLINKS exit 0 --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=write_net_rules #!/bin/sh -e # # This script is run if the interface (recognized by its MAC address) lacks # a rule for persistent naming. # # If there is already a persistent rule with that interface name then the # current interface needs to be renamed. # If the interface needs to be renamed, a NAME=value pair will be printed # on stdout to allow udev to IMPORT it # # Then a rule for the MAC address and interface name is written. RULES_FILE='/etc/udev/rules.d/z25_persistent-net.rules' . /lib/udev/hotplug.functions ############################################################################## device_description() { local bus=$(sysreadlink device/bus) bus=${bus##*/} if [ "$bus" = pci ]; then local vendor_id=$(sysread device/vendor) local device_id=$(sysread device/device) echo -n "PCI device ${vendor_id#0x}:${device_id#0x}" elif [ "$bus" = usb ]; then local device=$(sysreadlink device) if [ "$device" -a -e $device/../idVendor ]; then local idVendor idProduct read idVendor < $device/../idVendor || true read idProduct < $device/../idProduct || true printf 'USB device %x/%x' 0x$idVendor 0x$idProduct else echo -n "UNKNOWN USB device ($DEVPATH)" fi elif [ "$bus" = ieee1394 ]; then local hostid=$(sysreadlink device/host_id) if [ "$hostid" ]; then hostid=${hostid##*/} echo -n "FireWire host adapter $hostid ($DEVPATH)" else echo -n "UNKNOWN FireWire device ($DEVPATH)" fi elif [ "$bus" = xen ]; then echo -n "Xen virtual interface" elif [ "$bus" ]; then echo -n "UNKNOWN $bus device ($DEVPATH)" else echo -n "UNKNOWN device ($DEVPATH)" fi local driver=$(sysreadlink device/driver) if [ "$driver" ]; then echo -n " (${driver##*/})"; fi } ############################################################################## interface_name_taken() { local value="$(find_all_rules 'NAME=' $INTERFACE)" if [ "$value" ]; then return 0 else return 1 fi } find_next_available() { raw_find_next_available "$(find_all_rules 'NAME=' "$1")" } write_rule() { local match="$1" local name="$2" local comment="$3" { if [ "$PRINT_HEADER" ]; then PRINT_HEADER= echo "# This file was automatically generated by the $0" echo "# program, probably run by the persistent-net-generator.rules rules file." echo "#" echo "# You can modify it, as long as you keep each rule on a single line." fi echo "" [ "$comment" ] && echo "# $comment" echo "SUBSYSTEM==\"net\", $match, NAME=\"$name\"" } >> $RULES_FILE } write_all_rules() { cd /sys/class/net/ || return 0 for INTERFACE in *; do case $INTERFACE in eth*|ath*|wlan*|ra*|sta*) ;; *) continue ;; esac INTERFACE="$INTERFACE" DEVPATH="/class/net/$INTERFACE" \ /lib/udev/write_net_rules || true done } ############################################################################## # can be used only if $RULES_FILE is empty if [ "$1" = "all_interfaces" ]; then if [ -e $RULES_FILE ]; then printf "$RULES_FILE exists, persistent interface names\nnot saved.\n" >&2 exit 0 fi if [ ! -e /sys/class/net/ ]; then echo "/sys/class/net/ is not available, persistent interface names not saved." >&2 exit 0 fi write_all_rules exit 0 fi if [ -z "$INTERFACE" ]; then echo "Missing \$INTERFACE." >&2 exit 1 fi if [ "$1" ]; then MAC_ADDR="$1" else MAC_ADDR=$(sysread address) fi if [ -z "$MAC_ADDR" ]; then echo "No MAC address for $INTERFACE." >&2 exit 1 fi if [ "$MAC_ADDR" = "00:00:00:00:00:00" ]; then echo "NULL MAC address for $INTERFACE." >&2 exit 1 fi # Exit if the rules file should not be written yet. abort_if_run_early # Prevent concurrent processes from modifying the file at the same time. lock_rules_file # Check if the rules file is writeable. choose_rules_file # If a rule using the current name already exists then find a new name and # report it to udev which will rename the interface. basename=${INTERFACE%%[0-9]*} if interface_name_taken; then INTERFACE="$basename$(find_next_available "$basename[0-9]*")" if [ ! -t 1 ]; then echo "INTERFACE_NEW=$INTERFACE" fi fi comment=$(device_description) # the DRIVERS key is needed to not match bridges and VLAN sub-interfaces match="DRIVERS==\"?*\", ATTRS{address}==\"$MAC_ADDR\"" if [ $basename = "ath" -o $basename = "wlan" ]; then match="$match, ATTRS{type}==\"1\"" # do not match the wifi* interfaces fi write_rule "$match" "$INTERFACE" "$comment" unlock_rules_file exit 0 --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="hotplug.functions" # vim: syntax=sh PATH='/sbin:/bin' # Read a single line from file $1 in the $DEVPATH directory. # The function must not return an error even if the file does not exist. sysread() { local file="$1" [ -e "/sys$DEVPATH/$file" ] || return 0 local value read value < "/sys$DEVPATH/$file" || return 0 echo "$value" } sysreadlink() { local file="$1" [ -e "/sys$DEVPATH/$file" ] || return 0 readlink -f /sys$DEVPATH/$file 2> /dev/null || true } ############################################################################## # Return true if a directory is writeable. writeable() { if ln -s test-link $1/.is-writeable 2> /dev/null; then rm -f $1/.is-writeable return 0 else return 1 fi } ############################################################################## # Create a lock file for the current rules file. lock_rules_file() { [ -e /dev/.udev/ ] || return 0 RULES_LOCK="/dev/.udev/.lock-${RULES_FILE##*/}" retry=30 while ! mkdir $RULES_LOCK 2> /dev/null; do if [ $retry -eq 0 ]; then echo "Cannot lock $RULES_FILE!" >&2 exit 2 fi sleep 1 retry=$(($retry - 1)) done } unlock_rules_file() { [ "$RULES_LOCK" ] || return 0 rmdir $RULES_LOCK || true } # Choose the real rules file if it is writeable or a temporary file if not. # Both files should be checked later when looking for existing rules. choose_rules_file() { local tmp_rules_file="/dev/.udev/tmp-rules--${RULES_FILE##*/}" [ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1 if writeable ${RULES_FILE%/*}; then RO_RULES_FILE='/dev/null' else RO_RULES_FILE=$RULES_FILE RULES_FILE=$tmp_rules_file fi } abort_if_run_early() { return # DISABLED if ! writeable ${RULES_FILE%/*}; then exit 0 fi } ############################################################################## # Return the name of the first free device. raw_find_next_available() { local links="$1" local basename=${links%%[ 0-9]*} local max=-1 for name in $links; do local num=${name#$basename} [ "$num" ] || num=0 [ $num -gt $max ] && max=$num done local max=$(($max + 1)) # "name0" actually is just "name" [ $max -eq 0 ] && return echo "$max" } # Find all rules matching a key (with action) and a pattern. find_all_rules() { local key="$1" local linkre="$2" local match="$3" [ -e $RULES_FILE ] || return local search='.*[[:space:],]'"$key"'"\('"$linkre"'\)"[[:space:]]*\(,.*\|\\\|\)$' echo $(sed -n -e "${match}s/${search}/\1/p" $RO_RULES_FILE $RULES_FILE) } --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="udev.udev-mtab.init" #!/bin/sh -e ### BEGIN INIT INFO # Provides: udev-mtab # Required-Start: udev checkroot # Required-Stop: # Default-Start: S # Default-Stop: ### END INIT INFO PATH="/sbin:/bin" # copy the rules generated before / was mounted read-write for file in /dev/.udev/tmp-rules--*; do dest=${file##*tmp-rules--} [ "$dest" = '*' ] && break cat $file >> /etc/udev/rules.d/$dest rm -f $file done exit 0 --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="cd-aliases-generator.rules" # These rules generate rules for the /dev/{cdrom,dvd,...} symlinks and # write them in /etc/udev/rules.d/z20_persistent-cd.rules. # # If you want to configure them manually then just delete the symlink # pointing to this file. # # The default symlink for this file is z75_cd-aliases-generator.rules. ACTION!="add", GOTO="cd_aliases_generator_end" SUBSYSTEM!="block", GOTO="cd_aliases_generator_end" ENV{GENERATED}=="?*", GOTO="cd_aliases_generator_end" ENV{ID_CDROM}=="?*", PROGRAM="write_cd_rules", SYMLINK+="%c" LABEL="cd_aliases_generator_end" --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="persistent-net-generator.rules" ACTION!="add", GOTO="persistent_net_generator_end" SUBSYSTEM!="net", GOTO="persistent_net_generator_end" # ignore the interface if a name has already been set NAME=="?*", GOTO="persistent_net_generator_end" # ignore interfaces without a driver link ENV{DRIVER}!="?*", GOTO="persistent_net_generator_end" KERNEL=="eth*|ath*|wlan*|ra*|sta*", \ IMPORT{program}="write_net_rules $attr{address}" ENV{INTERFACE_NEW}=="?*", NAME="$env{INTERFACE_NEW}" LABEL="persistent_net_generator_end" --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 --mYCpIKhGyMATD0i+ Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel --mYCpIKhGyMATD0i+--