check_ethernet: don't ping via "down" links
I've noticed that we have some timing problems since:
https://chromium-review.googlesource.com/1637489
where we're holding /run/autotest_pause_ethernet_hook for upwards of 25
seconds. One reason: we're wasting a lot of time when there are
un-connected links (e.g., Chromeboxes with built-in Ethernet, but the
lab uses a USB dongle). Don't bother pinging anything if the operational
state is not "up".
Per Linux documentation:
Indicates the interface RFC2863 operational state as a string.
Possible values are:
"unknown", "notpresent", "down", "lowerlayerdown", "testing",
"dormant", "up".
BUG=none
TEST=plug in an unused USB ethernet dongle; ensure only eth1 is active;
then watch how long check_ethernet.hook takes
Change-Id: I8c1288c36cc9b15347dc8ea86cafb2e4bf12fb9f
Reviewed-on: https://chromium-review.googlesource.com/1669972
Tested-by: Brian Norris <briannorris@chromium.org>
Commit-Ready: Brian Norris <briannorris@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Grant Grundler <grundler@chromium.org>
diff --git a/recover_duts/hooks/check_ethernet.hook b/recover_duts/hooks/check_ethernet.hook
index 7ad20a5..0f42e34 100755
--- a/recover_duts/hooks/check_ethernet.hook
+++ b/recover_duts/hooks/check_ethernet.hook
@@ -52,13 +52,21 @@
done
}
+# Optional arg: when non-empty, only check for operational links.
search_devices() {
local device_path
local device
+ local operational="$1"
for device_path in /sys/class/net/*; do
device="$(basename "${device_path}")"
+ # Skip non-operational links.
+ if [ -n "${operational}" ] && \
+ [ "$(cat "${device_path}/operstate")" != "up" ]; then
+ continue
+ fi
+
# lab interconnect is full-duplex and tells us so.
# devices w/o link won't get listed here
if cat "${device_path}/duplex" > /dev/null 2>&1 ; then
@@ -86,10 +94,12 @@
}
# Shows the list of Ethernet interfaces found on the system.
+# Optional arg: when non-empty, only check for operational links.
find_ethernet_interfaces() {
local interfaces
+ local operational="$1"
- interfaces=$(search_devices)
+ interfaces=$(search_devices "${operational}")
if [ -z "${interfaces}" ] ; then
# didn't find any eth devices.
# Some possible causes are:
@@ -101,19 +111,19 @@
rescan_usb_hubs
# check again
- interfaces=$(search_devices)
+ interfaces=$(search_devices "${operational}")
fi
echo "$interfaces"
}
-# Pings the given ipaddress through all ethernet devices
+# Pings the given ipaddress through all operational ethernet devices
# $1 - IP address to ping.
do_ping() {
local ip_addr=$1
local eth
- for eth in $(find_ethernet_interfaces); do
+ for eth in $(find_ethernet_interfaces 1); do
ping -q -I "${eth}" -c 9 "${ip_addr}" && return 0
done
@@ -132,7 +142,7 @@
local eth
local neighbor_ip
- for eth in $(find_ethernet_interfaces); do
+ for eth in $(find_ethernet_interfaces 1); do
neighbor_ip=$(ip -4 neigh show dev "${eth}" |
awk '/REACHABLE|DELAY|STALE/ {print $1; exit}')
[ -n "${neighbor_ip}" ] && echo "${neighbor_ip}" && return 0