summary refs log tree commit diff
diff options
context:
space:
mode:
authorMartin Weinelt <mweinelt@users.noreply.github.com>2021-08-12 00:49:33 +0200
committerGitHub <noreply@github.com>2021-08-12 00:49:33 +0200
commit41eb076ed812d00b83a516e3590dac08336c4c3a (patch)
tree473b9fe6bfc78a2c3301c09498899949f3e5f2a9
parentcd6e93c8b00b4ad44ece7f0d15151c36ea5d1b20 (diff)
parent99e8af51b28f9e978e8137a6c4ca16d817c64d40 (diff)
downloadnixpkgs-41eb076ed812d00b83a516e3590dac08336c4c3a.tar
nixpkgs-41eb076ed812d00b83a516e3590dac08336c4c3a.tar.gz
nixpkgs-41eb076ed812d00b83a516e3590dac08336c4c3a.tar.bz2
nixpkgs-41eb076ed812d00b83a516e3590dac08336c4c3a.tar.lz
nixpkgs-41eb076ed812d00b83a516e3590dac08336c4c3a.tar.xz
nixpkgs-41eb076ed812d00b83a516e3590dac08336c4c3a.tar.zst
nixpkgs-41eb076ed812d00b83a516e3590dac08336c4c3a.zip
Merge pull request #127595 from rnhmjoj/wpa-auto
nixos/wireless: use udev to wait for interfaces
-rw-r--r--nixos/modules/services/networking/wpa_supplicant.nix51
1 files changed, 26 insertions, 25 deletions
diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix
index 494d21cc867..6238a351b99 100644
--- a/nixos/modules/services/networking/wpa_supplicant.nix
+++ b/nixos/modules/services/networking/wpa_supplicant.nix
@@ -42,11 +42,6 @@ in {
         description = ''
           The interfaces <command>wpa_supplicant</command> will use. If empty, it will
           automatically use all wireless interfaces.
-          <warning><para>
-            The automatic discovery of interfaces does not work reliably on boot:
-            it may fail and leave the system without network. When possible, specify
-            a known interface name.
-          </para></warning>
         '';
       };
 
@@ -230,14 +225,6 @@ in {
       message = ''options networking.wireless."${name}".{psk,pskRaw,auth} are mutually exclusive'';
     });
 
-    warnings =
-      optional (cfg.interfaces == [] && config.systemd.services.wpa_supplicant.wantedBy != [])
-      ''
-        No network interfaces for wpa_supplicant have been configured: the service
-        may randomly fail to start at boot. You should specify at least one using the option
-        networking.wireless.interfaces.
-      '';
-
     environment.systemPackages = [ package ];
 
     services.dbus.packages = [ package ];
@@ -258,31 +245,45 @@ in {
       wantedBy = [ "multi-user.target" ];
       stopIfChanged = false;
 
-      path = [ package ];
+      path = [ package pkgs.udev ];
 
       script = let
         configStr = if cfg.allowAuxiliaryImperativeNetworks
           then "-c /etc/wpa_supplicant.conf -I ${configFile}"
           else "-c ${configFile}";
       in ''
-        if [ -f /etc/wpa_supplicant.conf -a "/etc/wpa_supplicant.conf" != "${configFile}" ]
-        then echo >&2 "<3>/etc/wpa_supplicant.conf present but ignored. Generated ${configFile} is used instead."
+        if [ -f /etc/wpa_supplicant.conf -a "/etc/wpa_supplicant.conf" != "${configFile}" ]; then
+          echo >&2 "<3>/etc/wpa_supplicant.conf present but ignored. Generated ${configFile} is used instead."
         fi
+
         iface_args="-s -u -D${cfg.driver} ${configStr}"
+
         ${if ifaces == [] then ''
-          for i in $(cd /sys/class/net && echo *); do
-            DEVTYPE=
-            UEVENT_PATH=/sys/class/net/$i/uevent
-            if [ -e "$UEVENT_PATH" ]; then
-              source "$UEVENT_PATH"
-              if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then
-                args+="''${args:+ -N} -i$i $iface_args"
-              fi
-            fi
+          # detect interfaces automatically
+
+          # check if there are no wireless interface
+          if ! find -H /sys/class/net/* -name wireless | grep -q .; then
+            # if so, wait until one appears
+            echo "Waiting for wireless interfaces"
+            grep -q '^ACTION=add' < <(stdbuf -oL -- udevadm monitor -s net/wlan -pu)
+            # Note: the above line has been carefully written:
+            # 1. The process substitution avoids udevadm hanging (after grep has quit)
+            #    until it tries to write to the pipe again. Not even pipefail works here.
+            # 2. stdbuf is needed because udevadm output is buffered by default and grep
+            #    may hang until more udev events enter the pipe.
+          fi
+
+          # add any interface found to the daemon arguments
+          for name in $(find -H /sys/class/net/* -name wireless | cut -d/ -f 5); do
+            echo "Adding interface $name"
+            args+="''${args:+ -N} -i$name $iface_args"
           done
         '' else ''
+          # add known interfaces to the daemon arguments
           args="${concatMapStringsSep " -N " (i: "-i${i} $iface_args") ifaces}"
         ''}
+
+        # finally start daemon
         exec wpa_supplicant $args
       '';
     };