| # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| description "Preload network drivers" |
| author "chromium-os-dev@chromium.org" |
| |
| # Run on boot-services; "stay running" until we stop system-services |
| # (which is shutdown). |
| start on starting boot-services |
| |
| # crbug.com/810916: Use an event where we are confident all needed "net" |
| # driver modules have registered with "net" subsystem. The assumption is |
| # this set of drivers will be used again on next boot. |
| # |
| # "stop on stopped udev-trigger" has proven to be too early. |
| # |
| # "stop on starting system-services" means boot-services have completed |
| # (including udev-trigger) and conditions are meet to start system-services. |
| # But it's still racing. |
| # "stop on started system-services" is slightly better as this indicates |
| # some system-services have started. But it's still racing too. |
| # |
| # "stop on stopping system-services" would certainly qualify (shutdown) - but |
| # slows down shutdown which is expected to be quick (no benchmark though). |
| # |
| # Compromise is to check for WiFi (wlan0) device well after system services |
| # have been started. "failsafe" service meets that criteria even though |
| # it's not a 100% guarantee either that any given WiFi driver has registered |
| # with "net" subsystem. |
| # |
| # We also try to mitigate this race by looping for "expected" (WiFi) devices. |
| # |
| # https://dev.chromium.org/chromium-os/chromiumos-design-docs/boot-design#TOC-Failsafe-service |
| stop on started failsafe |
| |
| env drvfile=/var/lib/preload-network-drivers |
| |
| pre-start script |
| # Drivers for Ethernet and WiFi devices are generally modules. |
| # Our post-stop script will have recorded the driver names on the |
| # previous boot cycle. Load those drivers now so shill can config |
| # the network sooner. |
| # |
| # Note: failure to probe the module here is NOT fatal. |
| if [ -s "${drvfile}" ] ; then |
| for drv in $(head -1 "${drvfile}"); do |
| if ! modprobe -q -- "${drv}"; then |
| # If modprobe didn't like the alias file for some reason, just |
| # move it out of the way. The post-stop script will make a new |
| # one. |
| mv "${drvfile}" "${drvfile}.bad" |
| logger -t "${UPSTART_JOB}" \ |
| "modprobe ${drv} failed. Renamed ${drvfile} with .bad suffix." |
| fi |
| done |
| fi |
| end script |
| |
| post-stop script |
| # Create/Update list of networking driver names (i.e. Ethernet and WiFi). |
| # Used to preload Ethernet and WiFi drivers in pre-start script. |
| newdrv='' |
| |
| # "found" is set when an interface we are looking for is present. |
| found=0 |
| |
| probe_driver() { |
| local mod_dev="$1" |
| local mod_link="/sys/class/net/${mod_dev}/device/driver/module" |
| local drvmod='' |
| |
| if [ -e "${mod_link}" ] ; then |
| drvmod="$(basename "$(readlink "${mod_link}")")" |
| newdrv="${drvmod} ${newdrv}" |
| found=1 |
| fi |
| } |
| |
| for n in $(seq 30); do |
| # We will only find one of the following. Only Marvell WiFi uses "mlan". |
| probe_driver "wlan0" |
| probe_driver "mlan0" |
| |
| if [ "${found}" -eq 1 ] ; then |
| break |
| fi |
| |
| sleep 1 |
| done |
| |
| # We expect to find WiFi in all Chrome OS devices. Announce results here. |
| if [ "${found}" -eq 1 ] ; then |
| logger -t "${UPSTART_JOB}" "WiFi ${newdrv} found after ${n} seconds." |
| else |
| logger -t "${UPSTART_JOB}" "WiFi interface not found after ${n} seconds." |
| fi |
| |
| # USB wired ethernet driver is optional - add it if present. |
| # TODO(grundler): PCI wired ethernet is "built-in" to chromeboxes and |
| # it would be nice to warn when the PCI driver isn't registering. |
| probe_driver "eth0" |
| |
| if [ -s "${drvfile}" ] ; then |
| olddrv=$(head -1 "${drvfile}") |
| fi |
| |
| # Only update contents if they've changed. |
| if [ "${newdrv}" != "${olddrv}" ] ; then |
| echo "${newdrv}" > "${drvfile}" |
| # Force ureadahead to rebuild its block list. |
| rm -f /var/lib/ureadahead/pack |
| fi |
| end script |