All of lore.kernel.org
 help / color / mirror / Atom feed
From: md@Linux.IT (Marco d'Itri)
To: linux-hotplug@vger.kernel.org
Subject: scripts for persistent names support
Date: Sat, 02 Sep 2006 09:06:53 +0000	[thread overview]
Message-ID: <20060902090653.GA4424@wonderland.linux.it> (raw)

[-- Attachment #1: Type: text/plain, Size: 272 bytes --]

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

[-- Attachment #2: write_cd_rules --]
[-- Type: text/plain, Size: 1793 bytes --]

#!/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


[-- Attachment #3: write_net_rules --]
[-- Type: text/plain, Size: 4544 bytes --]

#!/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


[-- Attachment #4: hotplug.functions --]
[-- Type: text/plain, Size: 2561 bytes --]

# 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)
}


[-- Attachment #5: udev.udev-mtab.init --]
[-- Type: text/plain, Size: 422 bytes --]

#!/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

[-- Attachment #6: cd-aliases-generator.rules --]
[-- Type: text/plain, Size: 558 bytes --]

# 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"


[-- Attachment #7: persistent-net-generator.rules --]
[-- Type: text/plain, Size: 497 bytes --]

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"


[-- Attachment #8: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
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

[-- Attachment #9: Type: text/plain, Size: 226 bytes --]

_______________________________________________
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

             reply	other threads:[~2006-09-02  9:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-09-02  9:06 Marco d'Itri [this message]
2006-09-03  3:16 ` scripts for persistent names support Kay Sievers
2006-09-03 10:10 ` Marco d'Itri
2006-09-03 12:48 ` Kay Sievers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060902090653.GA4424@wonderland.linux.it \
    --to=md@linux.it \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.