bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

script-input problems ... /dev/fd/62 and HERE docs failing


From: Linda Walsh
Subject: script-input problems ... /dev/fd/62 and HERE docs failing
Date: Sun, 27 Jul 2014 14:51:32 -0700
User-agent: Thunderbird

Not sure if this went out the first time, but if it isn't
clear, the script ensures the network cards are "named"
correctly when the system comes up, so that other
functions (traffic control/services) can talk to the correct
interface.  My distro is moving away from standard 'eth'
naming to 'hw-serial#-based naming that isn't very portable
for scripts, so I need to rename the interfaces to standardized
names before the system comes up so services and such
listen to the correct ports.



Chet Ramey wrote:
 Maybe you should post your script so readers can take a look.  It's
 unlikely that there is a bug in here-documents, but it's possible.


----
If you ask for it...   I "inlined" the needed library functions,
so should run standalone.

FWIW, this script DOES work interactively in normal operation.

Just when the system is in pre-single-user state and not
much in the way of resources is available that it blows.

Right now only have 'start' implemented, as there is little call
for deconstructing network configs when the system is going down.

'ifmap' by itself should show current eth-dev mappings.

Note, buried in this code are absolute numbers (MAC addrs),
so to test on another machine they would need to be changed.

Have intended to put "site-local" info in a config file, but
as it doesn't work....haven't spent alot of time on expanding it.



--- ifmap -------------------------------------------------------------

#!/bin/bash

### BEGIN INIT INFO
# Provides:           net-devices
# Required-Start:     boot.udev boot.device-mapper boot.localfs
# Required-Stop:      $null
# Default-Start:       B
# Default-Stop:
# Short-Description:   order net devices
# Description:         order 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:
# gvim=:SetNumberAndWidth
echo "assign_netif_names=$0 $@"
_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 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

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

# need to list commands here:
# modprobe

sub warn () { local msg="Warning: ${1:-"general"}"
 echo "$msg" >&2
}

sub die () { int stat=$?; local msg="Error. ${1:-"unknown"}"
 echo "$msg (errno=$stat)" >&2
 (exit $stat);
 rc_status -v
 rc_exit
 exit $stat
}

if [[ -z $(type -P modprobe) ]]; then
 export PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH
fi

if [[ -n $(type -P modprobe) ]]; then
 alias modprobe="$(type -P modprobe)"
else
 #delay failure until use
 alias modprobe="die 'cannot load required modules'"
fi

if [[ -z $(type -P ip ) ]]; then
 die "Cannot find 'ip' util -- needed for network setup"
fi

alias ip="$(type -P ip)"


sub varflags() {
 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() {
 my name="${1:-""}"
 flags=$(varflags $name)
 [[ $flags =~ a ]] && return 0
 return 1
}

sub ipcmd () {
 my ipcmd="${1:?}"; shift; array tmpbuff
 my outbuff="${2:-tmpbuff}"
}

sysfs=/sys
sysnet=$sysfs/class/net
sys_modules=$sysfs/module

sub rev () {
 (($#==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
 down_if eth2 down
 down_if eth3 down
 down_if eth4 down
 down_if eth5 down
}


map act_hw2if=()  #actual values (to be read in)
map act_if2hw=()
map XIF=()        #tmp array to hold exchanged IF's



##inline data (should be in external file)
map hw2if=( [00:15:17:bf:be:b2]=eth0  [00:15:17:bf:be:b3]=eth1
           [00:26:b9:48:71:e2]=eth2  [00:26:b9:48:71:e4]=eth3
           [a0:36:9f:15:c9:c0]=eth4  [a0:36:9f:15:c9:c2]=eth5 )

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


#needed_drivers=(e1000e bnx2 ixgbe bonding)
needed_drivers=(e1000e bnx2 ixgbe)

sub vrfy_drivers () {
 int errors=0;
 for i in ${needed_drivers[@]} ; do
   if [[ ! -d $sys_modules/$i ]]; then
     modprobe "$i" || {
       warn "Module $i is not in kernel and can't be loaded"
       errors+=1
     }
   fi
 done
 return $errors
}



sub get_net_IFnames_hwaddrs () {
 vrfy_drivers
 array pseudo_devs=(br bond ifb team)
 string pseudo_RE='^(?:'"$(echo "${pseudo_devs[@]}"|tr " " "|")"')\d+$'
 string netdev_pat="+([_0-9a-z])+([0-9])"
 ( cd "$sysnet" &&
   for nm in $(eval "echo $netdev_pat" | tr ' ' "\n" |
               sort | grep -Pv "$pseudo_RE"); do
     echo "$nm $(<$nm/address)"
   done )
}


sub read_actuals () {
 my ifname hwaddr

 while read ifname hwaddr; do
   printf "ifname=%s, hwaddr=%s\n" "$ifname" "$hwaddr"
   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
 my hwaddr
 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 () {
 if ((${#act_hw2if[@]}==0)); then read_actuals; fi
 my key ifname
 int count=0
 map XIF  act_hw2if act_if2hw

 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
       #Nobody has the name, use it
       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







reply via email to

[Prev in Thread] Current Thread [Next in Thread]