Commit dceacd25 authored by Russ Fish's avatar Russ Fish

Windows nondeterministically lost one or more NICS in ipconfig. ...

Windows nondeterministically lost one or more NICS in ipconfig.  Disable/re-enable the interface when that happens.
parent 57116c53
......@@ -63,55 +63,101 @@ tp=$svcs/Tcpip/Parameters
regtool set -s $tp/Domain $domain
logit "domain = $domain"
# Cache getmac output while all interfaces are still enabled. Used by rc.ifconfig .
bootdir=/var/emulab/boot
getmac /nh /v /fo csv > $bootdir/getmac-cache
nifc=`awk '/./{lines++} END{print lines}' $bootdir/getmac-cache`
bd=/var/emulab/boot
# Cache getmac output while all interfaces are still enabled, otherwise we get lines
# with nothing but 'Disabled Disconnected'. Used by rc.ifconfig .
#
# getmac /v /fo csv gives us comma-separated lines containing these double-quoted items:
# Local Area Connection #, device type (but without the # suffix that makes it a Device
# Description), dash-separated MAC address, and the \Device\Tcpip_{GUID} Transport Name.
#
# Squash out the ^M's and blank line in the getmac output.
gmc=$bd/getmac-cache
getmac /nh /v /fo csv | tr -d '\r' | sed '/^$/d' > $gmc
nifc=`wc -l < $gmc`
logit "number of interfaces = $nifc"
# 'devcon find' returns device_instance_ID: Device Description pairs.
# Squash out the ^M's and the space following the colon, and the summary line.
dfc=$bd/devcon-find-cache
devcon find =net 'PCI*' | tr -d '\r' | \
sed -e 's/ *: */:/' -e '/matching device/d' | sort -t : +1 > $dfc
# In spite of enabling all interfaces with devcon in rc.firstboot, sometimes an
# experimental net interface is omitted from ipconfig, but visible in devcon and
# getmac. Specifically disabling it and re-enabling it fixes the problem. (Yuck.)
icc=$bd/ipconfig-cache icd=$bd/ipconfig-descrs
ipconfig /all | tr -d '\r' > $icc
sed -n '/Description/s/.*: //p' $icc | sort > $icd
nipc=`wc -l < $icd`
logit "number of interfaces in ipconfig = $nipc"
if [[ $nipc < $nifc ]]; then
# Ignore the ones that are in ipconfig already.
logit "Fixing interface(s): `join -v 2 -t : -2 2 -o 2.2 $icd $dfc`"
# 'devcon' takes PCI_device_instance_ID args with leading @ signs.
ids=`join -v 2 -t : -2 2 -o 2.1 $icd $dfc | sed 's/^/@/'`
devcon disable $ids
devcon enable $ids
# Should be fixed.
ipconfig /all | tr -d '\r' > $icc
sed -n '/Description/s/.*: //p' $icc | sort > $icd
nipconfig=`wc -l < $icd`
logit "number of interfaces in ipconfig now = $nipconfig"
fi
# Remember the control net interface MAC address and Local Area Connection name for
# slothd. It's the one whose IP address is returned by looking up the nodeid (pc%d).
cif=/var/emulab/boot/controlif
cif=$bd/controlif cmac=$bd/controlmac
ipaddr=`nslookup $nodeid.$domain | awk '/Address:/{print $2}' | tail -1`
logit "ipaddr = $ipaddr"
if [ -z "$ipaddr" ]; then
logit "$host- No ip address found for '$nodeid.$domain'."
else
# Remember the non-control net interface device descriptions, etc.
xid=$bootdir/xif_descrs xim=$bootdir/xif_macs xin=$bootdir/xif_names
ipconfig /all | tr -d '\r' | awk \
'/^Ethernet adapter/{ ifc = gensub("Ethernet adapter (.*):", "\\1", 1); next }\
# Remember the non-control net interface device descriptions, etc. as well.
xid=$bd/xif_descrs xim=$bd/xif_macs xin=$bd/xif_names xii=$bd/xif_ids
awk '/^Ethernet adapter/{ ifc = gensub("Ethernet adapter (.*):", "\\1", 1); next }\
/Description/{ gsub("^[^:]*: ", ""); descr = $0; next }\
/Physical Address/{ gsub("-", ":"); mac = tolower($NF); next }\
/IP Address/ && $NF=="'$ipaddr'"{ ctl=1; print mac, ifc > "'$cif'"; next }\
# Blank lines between device sections in ifconfig output.\
/IP Address/ && $NF=="'$ipaddr'"{ ctl=1; print mac, ifc > "'$cif'"; \
gsub(":", "", mac); print mac > "'$cmac'"; next }\
# Blank lines separate the device sections in ifconfig output.\
/^$/ && descr != "" { if (!ctl) do_xif(); descr = ctl = ""; next }\
END{ if (!ctl) do_xif() }\
function do_xif() {\
print mac > "'$xim'"; print ifc > "'$xin'"; print descr > "'$xid'" }'
nxifc=`awk '/./{lines++} END{print lines}' $xim`
print mac > "'$xim'"; print ifc > "'$xin'"; print descr > "'$xid'" }' $icc
nxifc=`wc -l < $xim`
logit "number of experimental net interfaces = $nxifc"
if (( $nxifc >= $nifc )); then
logit "$host - Can't find control net interface. Bad ip address '$ipaddr'?"
else
# Disable all NICs except the control net interface. Experimental net interfaces
# will be enabled by $bootdir/rc.ifc later. (Generated by rc.ifconfig .)
xii=$bootdir/xif_ids
# 'devcon find' returns device_instance_ID: device description.
# Map from device names to PCI instance id's for liblocsetup.pm:os_ifconfig_line().
# Make the device id order the same as ipconfig for pasting files together.
devcon find =net 'PCI*' | sed 's/ *: */:/' | awk -F : \
awk -F : < $dfc \
'BEGIN{ while ((getline descr < "'$xid'") > 0) descrs[++n] = descr }\
{ ids[$2] = $1 }\
END { for (i=1; i<=n; i++) print "@"ids[descrs[i]] > "'$xii'" }'
# 'devcon disable' takes device_instance_ID args with leading @ signs.
devcon disable `cat $xii`
fi
# devcon takes PCI_device_instance_ID args with leading @ signs.
ximap=$bd/xif_map
paste -d: $xin $xii > $ximap
# Map from device names to instance id's for liblocsetup.pm:os_ifconfig_line().
ximap=$bootdir/xif_map
paste -d: $xin $xii > $ximap
# Disable NICs that won't be used. Addresses, etc for experimental net
# interfaces will be configured by rc.ifc later (generated by rc.ifconfig .)
mim=$bd/mac-id-map umac=$bd/used_macs
# mac-id-map is MAC:PCI_device_instance_ID.
tr -d : < $xim | paste -d: - $xii | sort > $mim
# Make a list of NIC macs that will be used.
tmcc ifconfig | sed -e 's/.*MAC=//' -e 's/ .*//' | cat $cmac - | sort > $umac
# The others.
unused=`join -v 2 -t : -o 2.1 $umac $mim`
if [ ! -z "$unused" ]; then
logit "Disabling unused interface(s): $unused"
devcon disable `join -v 2 -t : -o 2.2 $umac $mim`
fi
fi
fi
# Start up the service which will deliver a SHUTDOWN state event on reboot.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment