[opensuse] new network naming scheme (was: migration from openSUSE 12.3 to 13.2)
Andrei Borzenkov wrote:
One reason for inventing new names was avoiding name clash with automatic kernel assignment. This still applies.
Yes, I remember reading that as part of the reasoning.
If you do not like "predictable" names (I do not) use something like netXX. But do not use ethXX, as it puts you back on square one.
Which is where I want to be :-)
The only case when it is sure to work is when your names are the same as autossigned by kernels, in which case you can simply leave it to kernel in the first place.
I think in fact my names (ethXX) are always the same as those allocated by the kernel. Sofar I have never had any problems with names clashing. I guess "simply leave it to kernel" means using net.ifnames=0 ? Just wondering out loud - surely the loading sequence of the network drivers is important too? On one system I see 'e1000' loaded first, followed by 'tg3'. e1000 is for a 4port gigE card, tg3 is for two builtin gigE interfaces. My renaming makes the two tg3 interface = eth0, eth1 and the e1000 eth2-3-4-5. If I had left it to the kernel, I guess I would have e1000 = eth0-1-2-3 and tg3 = eth4-5. -- Per Jessen, Zürich (3.1°C) http://www.hostsuisse.com/ - virtual servers, made in Switzerland. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
I think it is the order the BIOS discovers/lists the cards. We have some SuperMicro MBs where each boot the drivers may be loaded in a different order. Then ethX moves around and we are not happy campers. The new naming has been a very good thing for us as our systems reboot at least once a day. The kernel naming is not usable as it is not consistent across boots. On Tue, Mar 3, 2015 at 8:18 AM, Per Jessen <per@computer.org> wrote:
Andrei Borzenkov wrote:
One reason for inventing new names was avoiding name clash with automatic kernel assignment. This still applies.
Yes, I remember reading that as part of the reasoning.
If you do not like "predictable" names (I do not) use something like netXX. But do not use ethXX, as it puts you back on square one.
Which is where I want to be :-)
The only case when it is sure to work is when your names are the same as autossigned by kernels, in which case you can simply leave it to kernel in the first place.
I think in fact my names (ethXX) are always the same as those allocated by the kernel. Sofar I have never had any problems with names clashing. I guess "simply leave it to kernel" means using net.ifnames=0 ?
Just wondering out loud - surely the loading sequence of the network drivers is important too? On one system I see 'e1000' loaded first, followed by 'tg3'. e1000 is for a 4port gigE card, tg3 is for two builtin gigE interfaces. My renaming makes the two tg3 interface = eth0, eth1 and the e1000 eth2-3-4-5. If I had left it to the kernel, I guess I would have e1000 = eth0-1-2-3 and tg3 = eth4-5.
-- Per Jessen, Zürich (3.1°C) http://www.hostsuisse.com/ - virtual servers, made in Switzerland.
-- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
-- Roger Oberholtzer -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Roger Oberholtzer wrote:
I think it is the order the BIOS discovers/lists the cards.
Of course, you're right.
We have some SuperMicro MBs where each boot the drivers may be loaded in a different order. Then ethX moves around and we are not happy campers.
I agree, that is a problem.
The new naming has been a very good thing for us as our systems reboot at least once a day. The kernel naming is not usable as it is not consistent across boots.
I guess it depends on the hardware. We have always used the udev renaming rules, it works fine. -- Per Jessen, Zürich (6.1°C) http://www.dns24.ch/ - your free DNS host, made in Switzerland. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Roger Oberholtzer wrote:
I think it is the order the BIOS discovers/lists the cards. We have some SuperMicro MBs where each boot the drivers may be loaded in a different order. Then ethX moves around and we are not happy campers. The new naming has been a very good thing for us as our systems reboot at least once a day. The kernel naming is not usable as it is not consistent across boots.
I have a bash script I run as part of my boot procedure that checks the hardware-ethernet addrs and renames them. You could use it or adapt it to your setup... It reads it's config out of /etc/sysconfig/assign_netif_names. No guarantees, but seems to work for me. It's run as one of the S50boot scripts out of /etc/init.d/boot.d. ---- Might have to be adapted to work w/SD ... Sample /etc/sysconfig/assign_netif_names at the end of the script. #!/bin/bash #boot.assign_network_names ### BEGIN INIT INFO # Provides: net-devices # Required-Start: boot.usr-mount boot.udev boot.device-mapper boot.localfs # Required-Stop: $null # Default-Start: B # Default-Stop: # Short-Description: reorder and rename net devices # Description: reorder and rename net devs if needed ### END INIT INFO # # assign network names as rc-script # L A Walsh, (free to use/modify/distribute to nice people) (c) 2013-2014 # #include standard template: _prgpth=${0:?}; _prgpth=${_prgpth#-} _prg=${_prgpth##*/}; _prgdr=${_prgpth%/$_prg} [[ -z $_prgdr || $_prg == $_prgdr ]] && _prgdr="$PWD" #if ! typeset -f include >&/dev/null ;then # source ${_LOCAL_DIR:=/etc/local}/bash_env.sh; #fi export PATH="/etc/local/bin:/etc/local/lib:$PATH" export PS4='>>${BASH_SOURCE:+${BASH_SOURCE[0]}}#${LINENO}${FUNCNAME:+(${FUNCNAME[0]})}> ' #include stdalias (needed entries included "inline", below) shopt -s extglob expand_aliases alias dcl=declare sub=function alias int=dcl\ -i map=dcl\ -A hash=dcl\ -A array=dcl\ -a alias lower=dcl\ -l upper=dcl\ -u string=dcl my=dcl alias map2int=dcl\ -Ai intArray=dcl\ -ia cfg_fn="/etc/sysconfig/assign_netif_names" [[ -f $cfg_fn ]] || { echo "Cannot find required config file: $cfg_fn"; exit 1; } # expected variables to be read in array needed_drivers array Linknames array Default map if2hw . $cfg_fn || { echo "Error in reading config file $cfg_fn"; exit 2; } DfltRE="^+(${Default_good[@]})$" DfltRE=${DfltRE// /|} declare -a down_ln=() for ln in "${Linknames[@]}"; do [[ $DfltRE =~ $ln ]] && continue; down_ln+=($ln) done map hw2if for intf in "${!if2hw[@]}" ; do addr=${if2hw[$intf]} hw2if[$addr]="$intf" done ############# end read config ###### #include rc.status -- essential funcs included below: int rc_status=0 sub rc_reset { rc_status=0; } sub rc_status { rc_status=$?; if ((rc_status)) && { (($#)) && [[ $1 = -v ]] ; }; then echo "Abnormal rc_status was $rc_status." elif (($#)) && [[ $1 = -v ]] ; then echo "rc_status: ok" fi } sub rc_exit { rc_status=$?; rc_status exit $rc_status } sub warn () { local msg="Warning: ${1:-"general"}" printf "%s" >&2 "$msg" } sub die () { int stat=$?; local msg="Error. ${1:-"unknown"}" echo "$msg (errno=$stat)" >&2 (exit $stat); #sets $? (doesn't exit inside () rc_status -v rc_exit exit $stat # exit unless die called in subshell } sysfs=/sys sysnet=$sysfs/class/net [[ -d $sysfs && -d $sysnet ]] || sysnet=$sysfs/class/net sys_modules=$sysfs/module if [[ -z $(type -P modprobe) ]]; then # verify find of modprobe export PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH fi if [[ -n $(type -P modprobe) ]]; then # if found, alias it alias modprobe="$(type -P modprobe)" else # only throw error if needed alias modprobe="die 'cannot load required modules'" fi if [[ -z $(type -P ip ) ]]; then # ip is needed, so no delayed error die "Cannot find 'ip' util -- needed for network setup" fi alias ip="$(type -P ip)" sub varflags() { # util: get dcl flags of a var my var="${1:-""}" read out <<<$(declare -p "$var" ) [[ $out =~ /^declare.*=.*$/ ]] || die "no such variable" out="${out%% +([^-])=*}" out="${out#declare }" [[ ${out:0:1} == - ]] || { echo ""; return 0 ; } echo "${out#-}" } sub isarray() { # util: chk if pass name is an array my name="${1:-""}" flags=$(varflags $name) [[ $flags =~ a ]] && return 0 return 1 } sub ipcmd () { # unused/incomplete my ipcmd="${1:?}"; shift; array tmpbuff my outbuff="${2:-tmpbuff}" } sub rev () { # reverse elements of a list, 1/iteration (recursive) (($#==0)) && { echo ""; return 0 ;} my element=${1:?}; shift; (($#==0)) && { echo "$element"; return 0;} echo "$(rev "$@") $element" } sub rename_if () { my old_name=${1:?} new_name=${2:?} echo ip link set name "$new_name" dev "$old_name" } sub down_if () { my if_name=${1:?} echo ip link set down dev "$if_name" } sub set_links_down() { # can't operate on up links for int in "${down_ln[@]}"; do down_if "$int" down done } sub vrfy_drivers () { int errors=0; for i in ${needed_drivers[@]} ; do if [[ ! -d $sys_modules/$i ]]; then # check for loaded or static drivers modprobe "$i" || { warn "Module $i is not in kernel and can't be loaded" errors+=1 } fi done return $errors } map act_hw2if #actual values (to be read in) map act_if2hw map XIF #tmp array to hold exchanged IF's sub get_net_IFnames_hwaddrs () { # get names + addrs from /sys vrfy_drivers array pseudo_devs=(br bond ifb team) string pseudo_RE="^+(${pseudo_devs[@]})$" pseudo_RE=${pseudo_RE// /|} string netdev_pat="+([_0-9a-z])+([0-9])" ( cd "$sysnet" && for nm in $( echo $netdev_pat); do [[ $pseudo_re =~ $nm ]] && continue hwaddr="$(<$nm/address)" echo "$nm" "$(<$nm/address)" done ) } sub read_actuals () { # parse output stream from above my ifname hwaddr ls -ld /proc/self/fd /dev/fd >&2 while read ifname hwaddr; do act_hw2if[$hwaddr]="$ifname" act_if2hw["$ifname"]="$hwaddr" done < <(get_net_IFnames_hwaddrs) } sub ifaddr_cmd () { if ((${#act_hw2if[@]:-0}==0)) ;then read_actuals; fi for ifname in $(printf "%s\n" "${act_hw2if[@]}"|sort|tr "\n" " ") ; do my first_ifn="$ifname" if [[ $ifname =~ \+ ]] ; then first_ifn="${ifname%%+*}" fi printf "%s\t%s\n" "$ifname" "${act_if2hw["$first_ifn"]}" done } sub ifmap_cmd () { ifaddr_cmd "$@" ; } sub remap_cmd () { # remap devnames if needed if ((${#act_hw2if[@]}==0)); then read_actuals; fi my key ifname int count=0 array ifnames=$(printf "%s\n" "${!if2hw[@]}"|sort| grep -P '^[^~+]*$' |tr "\n" " ") array rev_ifns=($(rev "${ifnames[@]}" )) for key in "${rev_ifns[@]}"; do int is_regex=0; ifname="$key" if [[ ${key:0:1} == ~ ]];then ifname=${key:1}; is_regex=1; fi my hwaddr="${if2hw["$key"]:-""}" my actual_hw="${act_if2hw["$ifname"]:-""}" my actual_if="${act_hw2if["$actual_hw"]:-""}" ##line 233 if [[ ${actual_hw:-""} && ! $actual_hw =~ \+ ]]; then ## if ((is_regex)); then [[ $actual_hw =~ $hwaddr ]] && continue else [[ $actual_hw == $hwaddr ]] && continue; fi if [[ ! ${act_if2hw["$ifname"]:-} ]]; then down_if "$actual_hw" rename_if "$actual_hw" "$ifname" ; count+=1 else rename_if "$actual_if" "X$ifname"; #don't count temp renames 2x XIF["X$ifname"]="$hwaddr" fi fi done if ((${#XIF[@]}==0)); then echo "HW interfaces appear to be in order."; return 0; fi int count=0 for ifname in "${!XIF[@]}"; do hwaddr=${XIF[$ifname]}; ifname=${ifname#X} my destname=${hw2if[$hwaddr]} rename_if "$ifname" "$destname" ; count+=1 done printf "%d interface%s renamed\n" $count "$( (($count!=1)) && echo "s" )" } sub start_cmd () { remap_cmd "$@" ; } hash switches=([ifmap]=1 [remap]=1 [start]=1) sub help () { echo "$_prg:" echo "Options: ifmap - show current hw# -> IF map" echo " remap - verify & remap ifnames if needed" return 1 } if (($#)) ; then dcl op="${1#:-}" if [[ ${switches[$op]:-} ]]; then cmd="${op}_cmd" shift $cmd "$@" else echo "Unknown switch :-$op" fi else help fi # vim: ts=2 sw=2 number fdm=marker fdc=1 #/etc/sysconfig/assign_netif_names - sample config # to be sourced by BASH ###### # assign_netif_names reads this at boot to learn of a users # desired network naming (and ordering) #needed_drivers=(e1000e bnx2 ixgbe) # (list builtin as well as modules) # Note -- using brace_expansions #Linknames=( $(echo eth{0..5}) ) # Links that we _expect_ will come up with right names (built-mods) #Default_good=( $(echo eth{0..1}) ) # store as hash, with intfname as key and it's ethernet addr as the data # if2hw=([eth0]="00:15:17:bf:be:b2" [eth1]="00:15:17:bf:be:b3" # [eth2]="00:26:b9:48:71:e2" [eth3]="00:26:b9:48:71:e4" # [eth4]="a0:36:9f:15:c9:c0" [eth5]="a0:36:9f:15:c9:c2" )
Linda Walsh wrote:
Roger Oberholtzer wrote:
I think it is the order the BIOS discovers/lists the cards. We have some SuperMicro MBs where each boot the drivers may be loaded in a different order. Then ethX moves around and we are not happy campers. The new naming has been a very good thing for us as our systems reboot at least once a day. The kernel naming is not usable as it is not consistent across boots.
I have a bash script I run as part of my boot procedure that checks the hardware-ethernet addrs and renames them.
Do you have a reason for not just using the udev renaming? -- Per Jessen, Zürich (6.8°C) http://www.hostsuisse.com/ - virtual servers, made in Switzerland. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
Per Jessen wrote:
Linda Walsh wrote:
Roger Oberholtzer wrote:
I think it is the order the BIOS discovers/lists the cards. We have some SuperMicro MBs where each boot the drivers may be loaded in a different order. Then ethX moves around and we are not happy campers. The new naming has been a very good thing for us as our systems reboot at least once a day. The kernel naming is not usable as it is not consistent across boots.
I have a bash script I run as part of my boot procedure that checks the hardware-ethernet addrs and renames them.
Do you have a reason for not just using the udev renaming?
Because every once in a while, some piece of the udev software got updated and remangled the names. It wasn't _that_ often, but the more often I updated the more likely some upgrade would cause it to change things. News about what's going to happen to network naming has gone back and forth as well, intermixed with new upstream SW that hasn't always been reliably tested and certainly hasn't been vetted for compatibility (fairly obvious that is not high on the priority list). With the udev being integrated into systemd, it's future stability doesn't seem likely to improve... So... the script simply says to heck with the chaos and tries to go with something *nix is good at -- using scripting to fix and manage things. Having it in script also makes it easier to debug if something goes wrong or changes. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
В Tue, 03 Mar 2015 08:18:20 +0100 Per Jessen <per@computer.org> пишет:
Andrei Borzenkov wrote:
One reason for inventing new names was avoiding name clash with automatic kernel assignment. This still applies.
Yes, I remember reading that as part of the reasoning.
If you do not like "predictable" names (I do not) use something like netXX. But do not use ethXX, as it puts you back on square one.
Which is where I want to be :-)
The only case when it is sure to work is when your names are the same as autossigned by kernels, in which case you can simply leave it to kernel in the first place.
I think in fact my names (ethXX) are always the same as those allocated by the kernel. Sofar I have never had any problems with names clashing. I guess "simply leave it to kernel" means using net.ifnames=0 ?
Not really. In openSUSE having net.ifnames=0 will enable legacy persistent names generator (that writes 70-persistent-net.rules). It tries to find non-conflicting names for ethX interfaces (i.e. those that are not already defined in 70-persistent-net.rules). What I miss is where temporary rules (created while root is read-only) are copied to /etc. Another consideration is that persistent generation is not present in initrd. So interface in initrd may have different name. To truly enable kernel names just create udev rule that sets NAME=${INTERFACE} early enough.
Just wondering out loud - surely the loading sequence of the network drivers is important too?
Yes, of course.
On one system I see 'e1000' loaded first, followed by 'tg3'. e1000 is for a 4port gigE card, tg3 is for two builtin gigE interfaces. My renaming makes the two tg3 interface = eth0, eth1 and the e1000 eth2-3-4-5. If I had left it to the kernel, I guess I would have e1000 = eth0-1-2-3 and tg3 = eth4-5.
-- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 03/03/2015 12:27 PM, Andrei Borzenkov wrote:
В Tue, 03 Mar 2015 08:18:20 +0100 Per Jessen <per@computer.org> пишет:
Andrei Borzenkov wrote:
One reason for inventing new names was avoiding name clash with automatic kernel assignment. This still applies.
Yes, I remember reading that as part of the reasoning.
If you do not like "predictable" names (I do not) use something like netXX. But do not use ethXX, as it puts you back on square one.
Which is where I want to be :-)
yeah, that part is not being understood. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
participants (5)
-
Andrei Borzenkov
-
Linda Walsh
-
Per Jessen
-
Roger Oberholtzer
-
Ruben