commit:     b3889e9bf7d486f83db3c182844b1217ce75d472
Author:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 18 20:08:23 2019 +0000
Commit:     Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Thu Jul 18 20:08:23 2019 +0000
URL:        https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=b3889e9b

linuxrc: Load network modules only when needed

To avoid problems related to drivers requiring special firmware which
might be not available when loading the module because the user don't really
need that module but it was added based on genkernel's module_load file,
we will no longer load network modules on boot.

Instead we will only load network modules when needed, for example
when dosshd is set or NFS is used.

Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>

 defaults/initrd.defaults |  5 +--
 defaults/initrd.scripts  | 83 +++++++++++++++++++++++++++++++++++++++++-------
 doc/genkernel.8.txt      |  3 ++
 3 files changed, 78 insertions(+), 13 deletions(-)

diff --git a/defaults/initrd.defaults b/defaults/initrd.defaults
index fbbd214..c617064 100644
--- a/defaults/initrd.defaults
+++ b/defaults/initrd.defaults
@@ -80,6 +80,7 @@ GK_NET_ROUTES=
 GK_NET_TIMEOUT_DAD=10
 GK_NET_TIMEOUT_DECONFIGURATION=10
 GK_NET_TIMEOUT_DHCP=10
+GK_NET_TIMEOUT_INTERFACE=10
 GK_SHELL_LOCKFILE='/var/run/rescueshell.pid'
 GK_SSHD_LOCKFILE='/tmp/remote-rescueshell.lock'
 GK_SSHD_PIDFILE='/var/run/dropbear.pid'
@@ -119,8 +120,8 @@ DEFAULT_NFSOPTIONS="ro,nolock"
 # - modules
 HWOPTS_BLK='nvme pata sata scsi usb firewire waitscan'
 HWOPTS_OBSOLETE='pcmcia ataraid' # Obsolete stuff that might be useful on old 
hardware, do$X only.
-HWOPTS="keymap cache modules virtio hyperv ${HWOPTS_BLK} bcache lvm dmraid 
multipath mdadm zfs fs net iscsi crypto"
+HWOPTS="keymap cache modules virtio hyperv ${HWOPTS_BLK} bcache lvm dmraid 
multipath mdadm zfs fs iscsi crypto"
 
 # This is the set of default HWOPTS, in the order that they are loaded.
 # This is whitespace aligned with HWOPTS above.
-MY_HWOPTS="          modules virtio hyperv ${HWOPTS_BLK} bcache lvm dmraid     
      mdadm     fs net       crypto"
+MY_HWOPTS="          modules virtio hyperv ${HWOPTS_BLK} bcache lvm dmraid     
      mdadm     fs       crypto"

diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts
index bc19fff..61ae534 100644
--- a/defaults/initrd.scripts
+++ b/defaults/initrd.scripts
@@ -1597,6 +1597,10 @@ iface_name() {
 }
 
 start_network() {
+       # Load network modules only when we need them to avoid possible
+       # firmware problems for people not using network that early
+       MY_HWOPTS=net load_modules
+
        # At least gk.net.iface can only be processed after sysfs was
        # mounted.
        local x=
@@ -1620,17 +1624,21 @@ start_network() {
                                GK_NET_GW=${x#*=}
                        ;;
                        gk.net.iface=*)
-                               local tmp_iface=$(iface_name "${x#*=}")
-                               if [ -z "${tmp_iface}" ]
-                               then
-                                       warn_msg "Interface specified by '${x}' 
not found, falling back to genkernel defaults ..."
-                               else
-                                       GK_NET_IFACE=${tmp_iface}
-                               fi
+                               GK_NET_IFACE=${x#*=}
                        ;;
                        gk.net.routes=*)
                                GK_NET_ROUTES=${x#*=}
                        ;;
+                       gk.net.timeout.interface=*)
+                               local tmp_interface_timeout=${x#*=}
+                               if is_int "${tmp_interface_timeout}"
+                               then
+                                       
GK_NET_TIMEOUT_INTERFACE=${tmp_interface_timeout}
+                               else
+                                       warn_msg "'${x}' does not look like a 
valid number -- will keep using default value ${GK_NET_TIMEOUT_INTERFACE}!"
+                               fi
+                               unset tmp_interface_timeout
+                       ;;
                        gk.net.timeout.dad=*)
                                local tmp_dad_timeout=${x#*=}
                                if is_int "${tmp_dad_timeout}"
@@ -1664,10 +1672,63 @@ start_network() {
                esac
        done
 
-       if [ ! -d "/sys/class/net/${GK_NET_IFACE}" ]
+       local interface_identifier=device
+       if echo "${GK_NET_IFACE}" | grep -qE ':|-'
        then
-               warn_msg "Interface ${GK_NET_IFACE} not found; Will not try to 
start network ..."
-               return
+               interface_identifier=mac
+               good_msg_n "Waiting for interface with MAC address 
${GK_NET_IFACE} ..."
+       else
+               good_msg_n "Waiting for interface ${GK_NET_IFACE} ..."
+       fi
+
+       local tmp_interface=
+       local have_interface=0
+       local interface_time_waited=0
+       local interface_timeout_100msec_modulo=
+       local interface_timeout && let interface_timeout=$(date +%s)+1
+       [ -n "${GK_NET_TIMEOUT_INTERFACE}" -a "${GK_NET_TIMEOUT_INTERFACE}" -gt 
0 ] && let interface_timeout=${interface_timeout}+${GK_NET_TIMEOUT_INTERFACE}-1
+
+       while [ "${have_interface}" != '1' -a $(date +%s) -le 
${interface_timeout} ]
+       do
+               tmp_interface=$(iface_name "${GK_NET_IFACE}")
+               if [ -n "${tmp_interface}" ]
+               then
+                       # We got at least something to probe
+                       if [ -d "/sys/class/net/${tmp_interface}" ]
+                       then
+                               GK_NET_IFACE="${tmp_interface}"
+                               have_interface=1
+                               break
+                       fi
+               fi
+
+               if [ "${have_interface}" != '1' ]
+               then
+                       let interface_time_waited=${interface_time_waited}+1
+                       sleep 0.1s
+
+                       let 
interface_timeout_100msec_modulo=${interface_time_waited}%10
+                       if [ ${interface_timeout_100msec_modulo} = 0 ]
+                       then
+                               printf "."
+                       fi
+               fi
+       done
+
+       echo
+
+       if [ "${have_interface}" != '1' ]
+       then
+               # Timeout!
+               if [ "${interface_identifier}" = 'mac' ]
+               then
+                       bad_msg "Interface with MAC address ${GK_NET_IFACE} not 
found!"
+               else
+                       bad_msg "Interface ${GK_NET_IFACE} not found!"
+               fi
+
+               warn_msg "Will not try to start network ..."
+               return 1
        fi
 
        if [ -z "${IP}" -o "${IP}" = 'dhcp' ]
@@ -1677,7 +1738,7 @@ start_network() {
                if [ $? -ne 0 ]
                then
                        bad_msg "Failed to start udhcpc for interface 
${GK_NET_IFACE}!"
-                       return
+                       return 1
                fi
        else
                good_msg "Bringing up interface ${GK_NET_IFACE} ..." ${QUIET}

diff --git a/doc/genkernel.8.txt b/doc/genkernel.8.txt
index da0f44e..3b96d8e 100644
--- a/doc/genkernel.8.txt
+++ b/doc/genkernel.8.txt
@@ -572,6 +572,9 @@ recognized by the kernel itself.
 *gk.net.timeout.dhcp*=<...>::
     By default we will wait up to 10 seconds for a DHCP server reply.
 
+*gk.net.timeout.interface*=<...>::
+    By default we will wait up to 10 seconds for interface to show up.
+
 *dosshd*::
     Will start an SSH daemon within initramfs allowing to remotely unlock
     encrypted devices or just for debugging purpose.

Reply via email to