home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / rescue / lib / udev / rename_netiface < prev    next >
Text File  |  2006-11-29  |  6KB  |  230 lines

  1. #! /bin/bash
  2. #
  3. PATH="/sbin:/bin"
  4.  
  5. declare -i MAXLOOPS=40          #
  6. declare -i LOOPDELAY=500000     # useconds
  7. declare -i MAXIFNUM=1024        #
  8. RULE_FILE=/etc/udev/rules.d/30-net_persistent_names.rules
  9. USED_IFACE_FILE_STUB=/tmp/used_interface_names
  10. USED_IFACE_FILE="`mktemp $USED_IFACE_FILE_STUB.XXXXXXXX`"
  11.  
  12. STAMPFILE=/tmp/dummy_stamp
  13. trap 'rm -f $USED_IFACE_FILE
  14.       echo renamed > $STAMPFILE
  15.       echo INTERFACE=$INTERFACE
  16.       echo DEVPATH=${DEVPATH%/*}/$INTERFACE
  17.       echo RENAMED=yes' EXIT
  18.  
  19. . /etc/sysconfig/network/config
  20. . /etc/sysconfig/network/scripts/functions
  21.  
  22. if [ -r /sys/class/net/$1/ifindex ] ; then
  23.     STAMPFILE=$STAMPFILE_STUB`cat /sys/class/net/$1/ifindex`
  24. else
  25.     STAMPFILE=${STAMPFILE_STUB}no_iface
  26. fi
  27. echo virgin > $STAMPFILE
  28.  
  29. if [ "$FORCE_PERSISTENT_NAMES" != yes ] ; then
  30.     info_mesg "No persistent names wanted"
  31.     exit 0
  32. fi
  33.  
  34. #exec 2>>/tmp/rename_netiface.$1-$2.$SEQNUM.log
  35. #set -x
  36.  
  37. error_exit() {
  38.     local RET
  39.     declare -i RET=$1
  40.     if [ $RET -ne "$1" ] ; then
  41.         RET=255
  42.     else
  43.         shift
  44.     fi
  45.     err_mesg "$@"
  46.     exit $RET
  47. }
  48.  
  49. usage() {
  50.     mesg "usage: $0 <oldname> [<newname>]" >&2
  51.     error_exit $*
  52. }
  53.  
  54. check_if_name_is_free() {
  55.     grep -qs "^[^#].*rename_netiface %k $NEWNAME\"" $RULE_FILE && return 1
  56.     cat $USED_IFACE_FILE_STUB* \
  57.         | grep -vs "$DEV_ID" \
  58.         | grep -q "^$NEWNAME" && return 1
  59.     echo $NEWNAME $DEV_ID >> $USED_IFACE_FILE
  60.     usleep $((RANDOM%600+700))000
  61.     cat $USED_IFACE_FILE_STUB* \
  62.         | grep -vs "$DEV_ID" \
  63.         | grep -q "^$NEWNAME" && return 1
  64.     return 0
  65. }
  66.  
  67. # Return 0 only if rule was successfully written (if needed of course)
  68. write_rule() {
  69.     test "$WRITE_RULE" == yes || return 0
  70.     check_if_name_is_free || return 1
  71.     if [ "$PHYSDEVBUS" == ccwgroup ] ; then
  72.         echo "SUBSYSTEM==\"net\", ACTION==\"add\"," \
  73.              "ENV{PHYSDEVPATH}==\"*$DEV_ID\"," \
  74.              "IMPORT=\"/lib/udev/rename_netiface %k $NEWNAME\"" \
  75.              >> $RULE_FILE
  76.     elif [ "$NOMAC_HACK_APPLIED" == yes ] ; then
  77.         echo "SUBSYSTEM==\"net\", ACTION==\"add\"," \
  78.              "ENV{ADDRESS}==\"$DEV_ID\"," \
  79.              "IMPORT=\"/lib/udev/rename_netiface %k $NEWNAME\"" \
  80.              >> $RULE_FILE
  81.     else
  82.         echo "SUBSYSTEM==\"net\", ACTION==\"add\"," \
  83.              "SYSFS{address}==\"$DEV_ID\"," \
  84.              "IMPORT=\"/lib/udev/rename_netiface %k $NEWNAME\"" \
  85.              >> $RULE_FILE
  86.     fi
  87.     /sbin/udevcontrol reload_rules || return 1
  88.     info_mesg "New rule for $DEV_ID added."
  89. }
  90.  
  91. test $# -gt 2 && usage 1 "too many arguments: $*"
  92. OLDNAME=$1
  93. NEWNAME=$2
  94. test -z "$OLDNAME" && usage 2 "too little arguments"
  95. ls /sys/class/net/$OLDNAME 2>/dev/null 1>&2 \
  96.     || error_exit 3 "oldname $OLDNAME does not exist"
  97. NAMEBASE=${OLDNAME%%[0-9]*}
  98. case "$NAMEBASE" in
  99.     eth|ath|wlan|ra|hsi|ctc|tr)
  100.         : go on
  101.         ;;
  102.     *)
  103.         exit 0
  104.         ;;
  105. esac
  106. # Also check if interface is not an vlan interface
  107. test -f "/proc/net/vlan/$OLDNAME" && exit 0
  108. declare -i IFNUM=${OLDNAME##$NAMEBASE}
  109.  
  110. if [ "$PHYSDEVBUS" == ccwgroup ] ; then
  111.     get_device_id() {
  112.         if [ -z "$PHYSDEVPATH" -a -L /sys/class/net/$1/device ] ; then
  113.             PHYSDEVPATH=`cd -P /sys/class/net/$1/device; pwd`
  114.             PHYSDEVPATH=${PHYSDEVPATH#/sys}
  115.         fi
  116.         if [ -n "$PHYSDEVPATH" -a -d /sys/$PHYSDEVPATH ] ; then
  117.             DEV_ID=${PHYSDEVPATH##*/}
  118.         else
  119.             DEV_ID=$2
  120.         fi
  121.     }
  122. else
  123.     get_device_id() {
  124.         if ls /sys/class/net/$1 2>/dev/null 1>&2; then
  125.             DEV_ID=`cat /sys/class/net/$1/address`
  126.         else
  127.             DEV_ID=$2
  128.         fi
  129.     }
  130. fi
  131.  
  132. if [ -z "$NEWNAME" ] ; then
  133.     # This routine looks for a network interface name that is still not
  134.     # used as persistent name. At first it tries the name the interface
  135.     # currently has. If this name is already occupied, then increase the
  136.     # number and try again.
  137.     # To check if a name is occupied we have to look in
  138.     # /etc/udev/rules.d/60-net_*.rules and in /tmp/used_interface_names*.
  139.     # The latter serves as temporary registration file to avoid race
  140.     # conditions. It will be removed when the script exits.
  141.  
  142.     NEWNAME=$OLDNAME
  143.     get_device_id "$OLDNAME" "$2"
  144.     if [ -z "$DEV_ID" ] ; then
  145.         error_exit 4 "no device id for $OLDNAME"
  146.     fi
  147.     if [ "${DEV_ID//0/}" == ":::::" ] ; then
  148.         # Workaround for some drivers which don't request their
  149.         # firmware before beeing set up and don't have a mac address
  150.         # before firmware was loaded.
  151.         ip link set up dev $OLDNAME
  152.         ip link set down dev $OLDNAME
  153.         # Do we have to wait some time?
  154.         for i in 0 1 2 3 4 5 6 7 8 9; do
  155.             get_device_id "$OLDNAME"
  156.             info_mesg "waiting for a usefull mac address: $DEV_ID"
  157.             test "${DEV_ID//0/}" != ":::::" && break
  158.             sleep 1
  159.         done
  160.     fi
  161.     if [ "${DEV_ID//0/}" == ":::::" ] ; then
  162.         error_exit 5 "all zero mac address for $OLDNAME"
  163.     fi
  164.     
  165.     while ! check_if_name_is_free; do
  166.         while [ $IFNUM -lt $MAXIFNUM ] ; do
  167.             : $((IFNUM++))
  168.             NEWNAME=$NAMEBASE$IFNUM
  169.             ls /sys/class/net/$NEWNAME 2>/dev/null 1>&2 && continue
  170.             continue 2
  171.         done
  172.         error_exit 6 "could not get a free persistent interfacename" \
  173.                  "for $OLDNAME ($DEV_ID)"
  174.     done
  175.     WRITE_RULE=yes
  176.     info_mesg "$OLDNAME: new persistent name for $DEV_ID is $NEWNAME"
  177. fi
  178. if [ -z "$NEWNAME" ] ; then
  179.     error_exit 7 "cannot get a valid new interface name"
  180. fi
  181.  
  182. # Simply try to rename directly, because it will work in most cases
  183. if nameif -r "$NEWNAME" "$OLDNAME" 2>/dev/null 1>&2; then
  184.     write_rule || error_exit 8 "Name $NEWNAME for $DEV_ID is NOT" \
  185.                            "persistent"
  186.     info_mesg "$OLDNAME -> $NEWNAME: immediate success"
  187.     INTERFACE=$NEWNAME
  188.     exit 0
  189. fi
  190.  
  191. # Generate a temporary interface name
  192. TMPNAME="${NAMEBASE}xx${IFNUM}"
  193. ls /sys/class/net/$TMPNAME 2>/dev/null 1>&2 \
  194.     && error_exit 10 "temporary interface name $TMPNAME does exist"
  195.  
  196. # Rename it to the temporary name.
  197. # Then try several times to rename it to new name
  198. nameif -r "$TMPNAME" "$OLDNAME" 2>/dev/null 1>&2 \
  199.     || error_exit 11 "cannot rename interface to temporary name $TMPNAME"
  200. echo looping > $STAMPFILE
  201. declare -i LOOPS=0
  202. while [ $MAXLOOPS -gt $LOOPS ] ; do
  203.     : $((LOOPS++))
  204.     if nameif -r "$NEWNAME" "$TMPNAME" 2>/dev/null 1>&2; then
  205.         write_rule || error_exit 12 "Name $NEWNAME for $DEV_ID is" \
  206.                                "NOT persistent"
  207.         info_mesg "$OLDNAME -> $NEWNAME: success after $LOOPS loops"
  208.         INTERFACE=$NEWNAME
  209.         exit 0
  210.     fi
  211.     usleep $LOOPDELAY
  212. done
  213.  
  214. if nameif -r "$OLDNAME" "$TMPNAME" 2>/dev/null 1>&2; then
  215.     info_mesg "$OLDNAME -> $NEWNAME: NO success after $LOOPS loops." \
  216.               "Interface again named $OLDNAME"
  217. else
  218.     info_mesg "$OLDNAME -> $NEWNAME: NO success after $LOOPS loops." \
  219.               "Interface now named $TMPNAME, because $OLDNAME was no" \
  220.               "longer available"
  221.     INTERFACE=$TMPNAME
  222. fi
  223. exit 0
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.