diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-10-21 16:57:16 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-10-26 14:06:00 -0700 |
commit | 4a92157b9e077514fdbf5845169323ed7370bedb (patch) | |
tree | 404806994809509f52b2f39fc67975900c24b42a /scripts | |
parent | 28abf7773e5fc6c26725340e19dade4166d930cd (diff) | |
download | vyatta-cfg-quagga-4a92157b9e077514fdbf5845169323ed7370bedb.tar.gz vyatta-cfg-quagga-4a92157b9e077514fdbf5845169323ed7370bedb.zip |
Change vyatta_net_name into a perl script
Use existing config parser and perl to handle udev device naming.
Do renaming early in udev boot, and fixup config file later.
This avoids rescanning udev devices on boot and adds preliminary
support for hotplug.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/add_bootfile_eth_hwid | 29 | ||||
-rwxr-xr-x | scripts/mod_bootfile_eth_hwid | 36 | ||||
-rwxr-xr-x | scripts/rl-system.init | 20 | ||||
-rwxr-xr-x | scripts/system/vyatta_interface_rescan | 137 | ||||
-rwxr-xr-x | scripts/vyatta_net_name | 512 |
5 files changed, 325 insertions, 409 deletions
diff --git a/scripts/add_bootfile_eth_hwid b/scripts/add_bootfile_eth_hwid deleted file mode 100755 index 61deea56..00000000 --- a/scripts/add_bootfile_eth_hwid +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# add ethnet interface sub-block to configure file - -shopt -s extglob - -if [[ "$*" == *--help* ]] ; then - echo ${0##*/} [test_]FILE INTERFACE HWID - exit 0 -fi - -if [[ "$1" == test_* ]] ; then - origfile=$1 - bootfile=/tmp/${1##*/}_$$ - cp $origfile $bootfile - trap "diff -c $origfile $bootfile; rm -f $bootfile; exit 0" $? -else - origfile= - bootfile=$1 -fi -eth=$2 -hwid=$3 - -sed -i '/^interfaces {$/,/^}$/ { - /^}$/i\ - ethernet '"$eth"' {\ - hw-id '"$hwid"'\ - } - }' $bootfile diff --git a/scripts/mod_bootfile_eth_hwid b/scripts/mod_bootfile_eth_hwid deleted file mode 100755 index feab64f1..00000000 --- a/scripts/mod_bootfile_eth_hwid +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# modify interface sub-block - -shopt -s extglob - -if [[ "$*" == *--help* ]] ; then - echo ${0##*/} [test_]FILE INTERFACE HWID - exit 0 -fi - -if [[ "$1" == test_* ]] ; then - origfile=$1 - bootfile=/tmp/${1##*/}_$$ - cp $origfile $bootfile - trap "diff -c $origfile $bootfile; rm -f $bootfile; exit 0" $? -else - origfile= - bootfile=$1 -fi -eth=$2 -hwid=$3 - -sed -i '/^interfaces {$/,/^}$/ { - /^ ethernet '"$eth"' {$/ { - :join - /\n }$/ { - /hw-id:\? / s/\(hw-id\):\? [0-9a-fA-F:]\+/\1 '"$hwid"'/ - /hw-id:\? /! s/}$/ hw-id '"$hwid"'\n }/ - b - } - N - b join - } -}' $bootfile - diff --git a/scripts/rl-system.init b/scripts/rl-system.init index 3e07e11e..989c51e4 100755 --- a/scripts/rl-system.init +++ b/scripts/rl-system.init @@ -105,20 +105,10 @@ clear_or_override_config_files () done } -udev_rescan () -{ - rm -f /tmp/vyatta_net_name_* - udevadm trigger --subsystem-match=net && udevadm settle --quiet - for ff in /tmp/vyatta_net_name_* ; do - f=${ff##*/} - cmd_name_hwid=${f/vyatta_net_name_/} - cmd=${cmd_name_hwid%%_*} - name_hwid=${cmd_name_hwid#*_} - name=${name_hwid%_*} - hwid=${name_hwid#*_} - syslog $cmd $name $hwid - $vyatta_sbindir/${cmd}_bootfile_eth_hwid $BOOTFILE $name $hwid - done +update_interface_config () { + if [ -d /dev/.udev/vyatta ]; then + $vyatta_sbindir/vyatta_interface_rescan /dev/.udev/vyatta $BOOTFILE + fi } create_ssh_host_keys () { @@ -190,7 +180,7 @@ start () { mkdir -p /var/run/vyatta mkdir -p /var/log/vyatta - udev_rescan + update_interface_config create_ssh_host_keys || \ log_failure_msg "can't initialize ssh host keys" clear_or_override_config_files || \ diff --git a/scripts/system/vyatta_interface_rescan b/scripts/system/vyatta_interface_rescan new file mode 100755 index 00000000..62d550bf --- /dev/null +++ b/scripts/system/vyatta_interface_rescan @@ -0,0 +1,137 @@ +#! /usr/bin/perl + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2010 Vyatta, Inc. +# All Rights Reserved. + +# Thus updates the configuration to add new interfaces. +# It is run on boot after udev and before vyatta configuration. + +use strict; +use lib "/opt/vyatta/share/perl5/"; +use Sys::Syslog qw(:standard :macros); +use XorpConfigParser; +use File::Copy; + +my $TMPFILE = "/tmp/config.boot.$$"; + +# These vendors are known to violate the local MAC address assignment convention +my %whitelist = ( + '02:07:01' => 'Interlan', + '02:60:60' => '3Com', + '02:60:8c' => '3Com', + '02:a0:c9' => 'Intel', + '02:aa:3c' => 'Olivetti', + '02:cf:1f' => 'CMC', + '02:e0:3b' => 'Prominet', + '02:e6:d3' => 'BTI', + '52:54:00' => 'Realtek', + '52:54:4c' => 'Novell 2000', + '52:54:ab' => 'Realtec', + 'e2:0c:0f' => 'Kingston Technologies', +); + +# Ignore devices with local assigned or invalid mac address, +# these devices don't have a persistent address +sub persistent_address { + my $mac = shift; + + # is local assignment bit (IEEE802) not set? + return 1 unless ($mac =~ /^.[2367abef]:/); + + # is address bogus? + return if ($mac eq '00:00:00:00:00:00'); + + # unless it is in whitelist, it is non persistent + $mac =~ /^([0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f])/; + return $whitelist{$1}; +} + +# Map from eth0 to ethernet +# TODO make smarter if more types +sub interface_type { + my $ifname = shift; + + return "ethernet" if ($ifname =~ /^eth/); + return "wireless" if ($ifname =~ /^wlan/); + + die "unknown interface name %s\n", $ifname; +} + +sub get_hwid { + my $name = shift; + + open (my $f, '<', $name) + or die "Can't open $name : $!"; + + my $hwaddr = <$f>; + chomp $hwaddr; + close $f; + + return $hwaddr; +} + +# vyatta_net_name leaves files in /dev/.udev/vyatta +# the filename is the interface and the contents are the hardware id +sub interface_rescan { + my ($VYATTAUDEV, $BOOTFILE) = @_; + + # parse existing config + my $xcp = new XorpConfigParser(); + $xcp->parse($BOOTFILE); + + opendir( my $dir, $VYATTAUDEV ) + or die "Can't open $VYATTAUDEV : $!"; + + foreach my $ifname (grep { ! /^\./ } readdir($dir)) { + my $ifpath = interface_type($ifname) . " $ifname"; + if ($xcp->get_node(['interfaces', $ifpath])) { + syslog(LOG_INFO, "%s: is already in config file", $ifname); + next; + } + + my $hwaddr = get_hwid("$VYATTAUDEV/$ifname"); + unless (persistent_address($hwaddr)) { + syslog(LOG_INFO, "%s: skipping address %s is not persistent", + $ifname, $hwaddr); + next; + } + + # Add new entry to config + syslog(LOG_INFO, "add config for %s hw-id %s", $ifname, $hwaddr); + $xcp->create_node(['interfaces',$ifpath,"hw-id $hwaddr"]); + } + + # Rewrite new config file + open (my $tmp, '>', $TMPFILE) + or die "Can't open $TMPFILE : $!"; + + select $tmp; + $xcp->output(0); + select STDOUT; + close $tmp; + + copy($TMPFILE, $BOOTFILE) + or die "Can't copy $TMPFILE to $BOOTFILE : $!"; + + unlink($TMPFILE); +} + +# main +die "vyatta_interface_rescan called with wrong args" + unless ($#ARGV == 1); + +openlog("vyatta-interface-rescan", "", LOG_DAEMON); + +interface_rescan(@ARGV); +exit 0; + diff --git a/scripts/vyatta_net_name b/scripts/vyatta_net_name index de1fbcbf..c7b217d9 100755 --- a/scripts/vyatta_net_name +++ b/scripts/vyatta_net_name @@ -1,5 +1,5 @@ -#!/bin/bash -# **** License **** +#! /usr/bin/perl + # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. @@ -10,349 +10,203 @@ # General Public License for more details. # # This code was originally developed by Vyatta, Inc. -# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2010 Vyatta, Inc. # All Rights Reserved. -# -# Authors: Tom Grennan <tgrennan@vyatta.com> -# Bob Gilligan <gilligan@vyatta.com> -# Description: search Vyatta config for interface name given address -# -# **** End License **** - -progname=${0##*/} -debug= -match= -attr_address=0:0:0:0:0:0 -declare -i ethn=0 -udev_persistent_net_rules_file="/etc/udev/rules.d/70-persistent-net.rules" - -# Set log_file to "/dev/null" to turn off debugging -log_file="/tmp/vnn_log" - -test -r /etc/default/vyatta && source /etc/default/vyatta - -# process command line variable overrides - -for arg ; do - case "$arg" in - --debug ) - debug=echo - ;; - --*=* ) - arg=${arg#--} - eval ${arg%=*}=\"${arg#*=}\" - ;; - *=* ) - eval ${arg%=*}=\"${arg#*=}\" - ;; - *:*:*:*:*:* ) - attr_address=$arg - ;; - * ) - orig_kname=$arg - ;; - esac -done - -: ${vyatta_prefix:=/opt/vyatta} -: ${vyatta_sbindir:=${vyatta_prefix}/sbin} -: ${vyatta_sysconfdir:=${vyatta_prefix}/etc} -: ${BOOTFILE:=${vyatta_sysconfdir:-/opt/vyatta/etc}/config/config.boot} -: ${DEFAULT_BOOTFILE:=${vyatta_sysconfdir:-/opt/vyatta/etc}/config.boot.default} - -shopt -s extglob nullglob - -# load cfg_eth_hwid array from the Vyatta config file by looking -# for entries formatted as follows: -# -# interface { -# ... -# ethernet eth# { -# ... -# hw-id XX:XX:XX:XX:XX:XX -# ... -# } -# } -# -# The result is an array named "cfg_net_hwid". Each element of the -# array is formatted like this: -# -# eth#=xx:xx:xx:xx:xx:xx -# -declare -a cfg_net_hwid=( $( sed -ne ' - /^interfaces {/,/^}/ { - /^ *ethernet eth[0-9]* {/,/^ $/ { - /^ *ethernet/ { - s/\r// - s/.* eth\([0-9]\+\) {$/ eth\1=/ -# hold interface name - h - } - /^.*hw-id:\?/ { -# translate field name - s/\r// - s/.*hw-id:\? *// -# tolower hex mac address - y/ABCDEF/abcdef/ -# exchange hold and pattern space - x -# concatenate hold and pattern - G - s/\n//p +use strict; +use lib "/opt/vyatta/share/perl5/"; +use XorpConfigParser; +use Vyatta::Config; +use Sys::Syslog qw(:standard :macros); +use Fcntl qw(:flock); + +my $BOOTFILE = "/opt/vyatta/etc/config/config.boot"; +my $UDEVDIR = "/dev/.udev"; + +my $VYATTAUDEV = $UDEVDIR . "/vyatta"; +my $LOCKFILE = $UDEVDIR . "/.vyatta-lock"; +my $VYATTACFG = "/opt/vyatta/config/active"; + +# Check if interface name is free to use +sub is_available { + my ($interfaces, $ifname) = @_; + + my $count = grep { $_ eq $ifname } values %$interfaces; + return ($count == 0); +} + +# Find next available interface name +sub find_available { + my ($interfaces, $ifprefix) = @_; + $ifprefix =~ s/\d+$//; + + for (my $id = 0; ; $id++) { + my $ifname = sprintf("%s%d", $ifprefix, $id); + + # is it in Vyatta config? + return $ifname if (is_available($interfaces, $ifname)); + } +} + +# Find the hardware id in the parsed config node for interface +sub get_hwid_from_children { + my $children = shift; + + foreach my $attr (@$children) { + next unless ($attr->{'name'} =~ /^hw-id ([0-9a-f:]+)/); + return $1; + } + + return; # not found +} + + +# Leave file for vyatta_interface_rescan +sub leave_rescan_hint { + my ($ifname, $hwaddr) = @_; + my $name = "$VYATTAUDEV/$ifname"; + + mkdir($VYATTAUDEV); + open (my $f, '>', $name) + or die "Can't create $name : $!"; + + print {$f} "$hwaddr\n"; + close $f; + return 1; +} + +# Determine network name to use based on Vyatta config during boot +sub coldplug { + my ($ifname, $hwaddr) = @_; + my $xcp = new XorpConfigParser(); + $xcp->parse($BOOTFILE); + + my $interfaces = { }; + my $inode = $xcp->get_node(['interfaces']); + if ($inode) { + foreach my $child (@{$inode->{'children'}}) { + next unless ($child->{'name'} =~ /^ethernet (.*)|^wireless (.*)/); + + my $intf = $1; + my $hwid = get_hwid_from_children($child->{'children'}); + next unless $hwid; + + # TBD this could be a hash with name and path? + $interfaces->{$hwid} = $intf; + } + } + + # is name already in config file + my $newname = $interfaces->{$hwaddr}; + return $newname if ($newname); + + # add already assigned names + if (opendir(my $dir, $VYATTAUDEV)) { + foreach my $intf (grep { ! /^\./ } readdir($dir)) { + if (open (my $f, '<', "$VYATTAUDEV/$intf")) { + my $hwid = <$f>; + close $f; + chomp $hwid; + + $interfaces->{$hwid} = $intf; } } - }' $BOOTFILE )) + } + + # Does biosdevname have a suggestion? + my $biosname = `/sbin/biosdevname -i $ifname`; + chomp $biosname; + if ($biosname ne '') { + $newname = $biosname; + } else { + $newname = $ifname; + } + + $newname = find_available($interfaces, $newname) + unless (is_available($interfaces, $newname)); + + leave_rescan_hint($newname, $hwaddr); + + return $newname; +} + +# Determine name from active config +sub hotplug { + my ($ifname, $hwaddr) = @_; + + openlog("vyatta-net-name", "", LOG_DAEMON); + + # Parse active config + my $cfg = new Vyatta::Config; + $cfg->setLevel('interfaces'); + + my $interfaces = {}; + foreach my $type ($cfg->listOrigNodes()) { + next unless ($type eq 'ethernet') || ($type eq 'wireless'); + foreach my $intf ($cfg->listOrigNodes($type)) { + my $hwid = $cfg->returnOrigValue("$type $intf hw-id"); + next unless $hwid; + # TBD this could be a hash with name and path? + $interfaces->{$hwid} = $intf; + } + } -finish () -{ - local cmd=$1 name=$2 address=$3 + my $newname = $interfaces->{$hwaddr}; + return $newname if ($newname); - # The output from this program tells udev what name to give this device - echo $name + # Does biosdevname have a suggestion? + my $biosname = `/sbin/biosdevname -i $ifname`; + chomp $biosname; + syslog(LOG_DEBUG, "biosdevname for '%s' => '%s'", $ifname, $biosname); - # This file tells rl_system startup script how to update the Vyatta - # config file. - touch /tmp/${progname}_${cmd}_${name}_${address} &> /dev/null + if ($biosname && ($biosname ne '')) { + $newname = $biosname; + } else { + $newname = $ifname; + } - # Remove entry for this MAC addr from the standard udev generated - # config file, if it exists, so it doesn't rename the interface - # out from under us. Remove the subject line plus the comment - # line above it - if [ -e $udev_persistent_net_rules_file ]; then - sed -i -e "/^#/N;/${address}.*NAME/d" $udev_persistent_net_rules_file - fi + $newname = find_available($interfaces, $ifname) + unless is_available($interfaces, $biosname); - exit $? + syslog(LOG_INFO, "new name for '%s' is '%s'", $ifname, $newname); + + return $newname; } -# Determine whether variable "ethn" conflicts with an ethernet unit -# number that was assigned in previous runs of this script -ethn_conflicts() -{ - # Return value 1 (failure) means no conflicts found. - # Return value 0 (success) means conflicts were found. - conflicts=1 - - echo "`date`: ethn_conflicts is checking if $ethn has conflicts" >> $log_file - # Generate list of ethernet unit numbers assigned previously by this script - used_ethn="" - for filename in /tmp/vyatta_net_name* ; do - if [ -e $filename ]; then - # strip off everything before the unit number - unit=${filename##*vyatta_net_name_*_eth} - # strip off everything after the unit number - unit=${unit%%_*} - # add unit number from this file to the list - used_ethn="$used_ethn $unit" - fi - done - - echo "`date`: ethn_conflicts: about to run check" >> $log_file - - for this_ethn in $used_ethn ; do - if [ $ethn -eq $this_ethn ]; then - echo "`date`: ethn $ethn conflicts with previously configured $this_ethn" >> $log_file - conflicts=0 - break - fi - done - - echo "`date`: ethn_conflicts for ethn $ethn returns $conflicts" >> $log_file - # return value (exit status) is true, i.e. 0, if there is a conflict - return $conflicts +my $LOCKF; +sub lock_file { + open ($LOCKF, '>', $LOCKFILE) + or die "Can't open $LOCKFILE : $!"; + + flock ($LOCKF, LOCK_EX) + or die "Can't lock $LOCKFILE : $!"; + } +sub unlock_file { + close $LOCKF; + $LOCKF = undef; +} -# -# Find an ethernet unit number that is neither listed in the config -# file nor assigned by this script in earlier runs. -get_free_ethn() -{ - # list of ethernet unit numbers assigned previously by this script - used_ethn="" - for filename in /tmp/vyatta_net_name* ; do - if [ -e $filename ]; then - # strip off everything before the unit number - unit=${filename##*vyatta_net_name_*_eth} - # strip off everything after the unit number - unit=${unit%%_*} - # add unit number from this file to the list - used_ethn="$used_ethn $unit" - fi - done - - # Counting up from 0, try to find a free ethernet unit number - found=0 - for ((ethn_to_use=0 ; ; ethn_to_use+=1)) ; do - found=1 - # Check to see if this one is in the config file - - echo "`date`: get_free_ethn: cfg_net_hwid is ${cfg_net_hwid[@]}" >> $log_file - - for name_hwid in ${cfg_net_hwid[@]} ; do - name=${name_hwid%=*} - this_ethn=${name/eth/} - echo "`date`: get_free_ethn 1 comparing $ethn_to_use vs $this_ethn" >> $log_file - if [ $ethn_to_use -eq $this_ethn ]; then - found=0 - break - fi - done - - if [ $found -eq 0 ]; then - continue - fi - - echo "`date`: get_free_ethn: used_ethn is $used_ethn" >> $log_file - - # Check to see if this script has assigned this unit number already - for this_ethn in $used_ethn ; do - echo "`date`: get_free_ethn 2 comparing $ethn_to_use vs $this_ethn" >> $log_file - if [ $ethn_to_use -eq $this_ethn ]; then - found=0 - break - fi - done - - if [ $found -eq 1 ]; then - break - fi - done - - # The return value - ethn=$ethn_to_use - - echo "`date`: get_free_ethn found $ethn_to_use" >> $log_file +# This script is called from udev with two arguments +# it outputs the new name (if any) to stdout +if ($#ARGV != 1) { + die "vyatta_net_name called with wrong args(%d) : %s", + $#ARGV, join(' ', @ARGV); } -# -# Main Section -# -# Run with lock held to protect atomicity of access to assigned ethn file -( flock 200 +my $ifname = $ARGV[0]; +my $hwaddr = $ARGV[1]; -touch $log_file +lock_file; +my $newname; +if ( -d $VYATTACFG ) { + $newname = hotplug($ifname, $hwaddr); +} else { + $newname = coldplug($ifname, $hwaddr); +} +unlock_file; -echo "`date`: vyatta_net_name $orig_kname $attr_address" >> $log_file +print "$newname\n" if ($newname); -# The biosdevname program determines the "recommended" name for the NIC -# based on information such its place in the bus topology, and whether it -# resides on the motherboard or not. The ensures deterministic NIC naming. -# -if [ ! -z "$orig_kname" ]; then - if [ -e /sbin/biosdevname ]; then - kname=`/sbin/biosdevname -i $orig_kname` - echo "`date`: /sbin/biosdevname maps $orig_kname to $kname" >> $log_file - else - echo "`date`: /sbin/biosdevname is not present on this system" >> $log_file - kname=$orig_kname - fi -else - kname="" -fi - -if [ ! -f $BOOTFILE ] ; then - cp $DEFAULT_BOOTFILE $BOOTFILE - chgrp vyattacfg $BOOTFILE - chmod 660 $BOOTFILE -fi - -for name_hwid in ${cfg_net_hwid[@]} ; do - name=${name_hwid%=*} - hwid=${name_hwid#*=} - ethn=${name/eth/} - echo "`date`: Checking $name_hwid against $kname $attr_address" >> $log_file - - if [ "$hwid" == "$attr_address" ] ; then - # The MAC addr of this interface matches an entry in the config - # file. We mod the config file interface sub-block in case it - # is missing. - - echo "`date`: finish 1: mod $name $attr_address" >> $log_file - - finish mod $name $attr_address - fi - - if [ "$name" = "$kname" ]; then - # The kernel name matches an entry in the config file. Save the - # config file entry for later examination. - - match=$name_hwid - fi -done - -if [ -z "$kname" ]; then - echo "`date`: Error: interface name not specified by caller" >> $log_file - exit 1 -fi - -# We have not found a matching hwid in the config file. See if we can use -# the kernel name. - -if [ -z "$match" ] ; then - # The kernel interface name is not listed in the config file. - # If the kernel's name is in the standard "ethN" format, and doesn't - # conflict with any other name we've used, then - # we can just go ahead and use the kernel's name. If not, then - # we will generate a name in the standard format that does not - # conflict with any names in the config file, or any other names - # that we have seen. - - non_std_kname=${kname##eth+([0-9])} - if [ -z "$non_std_kname" ]; then - # kname is in standard format, so we get the unit number from it. - ethn=${kname/eth/} - - # We can use this unit number unless it happens to conflict - # with one we have already assigned. - if ethn_conflicts ; then - echo "`date`: kname $kname conflicts with already assigned unit" >> $log_file - get_free_ethn - fi - else - # kname is not in standard format, so we have to generate - # a unit number - echo "`date`: kname $kname is non-standard format" >> $log_file - get_free_ethn - fi - - echo "`date`: finish 2: add eth$ethn $attr_address" >> $log_file - - finish add eth$ethn $attr_address - -elif [ -z "${match#*=}" ] ; then - # The config file has this interface but the sub-block is missing the hwid - # field, so we use the kernel name. In this case, we know that the - # kernel name is in the standard format because it matched an entry - # in the config file, and all entries in the config file are in standard - # format. This will cause the hwid for this NIC to be added to the - # entry in the config file. - - echo "`date`: finish 3: mod $kname $attr_address" >> $log_file - - finish mod $kname $attr_address - -else - # The config file has this interface name, but the mac address is not - # that of this NIC. This indicates that the device is either a - # replacement or new NIC that is being detected earlier than the device - # configured with this name. Since we don't know which case it is, - # we must generate a new unit number. - get_free_ethn - - echo "`date`: finish 4: add eth$ethn $attr_address" >> $log_file - - finish add eth$ethn $attr_address -fi - -# Should never get here. If this shows up in the log file, something -# is wrong! -echo "`date`: no finish: kname = $kname, attr_attr = $attr_address, match = $match" >> $log_file - -) 200> /tmp/vnn_lock - -# Local Variables: -# mode: shell-script -# sh-indentation: 4 -# End: +exit 0; |