Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/wireless: use udev to wait for interfaces #127595

Merged
merged 1 commit into from
Aug 11, 2021
Merged

Conversation

rnhmjoj
Copy link
Contributor

@rnhmjoj rnhmjoj commented Jun 20, 2021

I may have finally found a clean solution to the issues1 2 3 with
the automatic discovery of wireless network interfaces.

Currently the start script fails right away if no interface is available
by the time it's running, possibly leaving the system without network.
This happens when running a little early in the boot. A solution is to
instead wait for at least one interface to appear before scanning the
/sys/class/net/ directory. This is done here by listening for the right
udev events (from the net/wlan subsystem) using the udevadm monitor
command and some awk script to parse its output.

This methods guarantees the availability of at least one interface to
wpa_supplicant, but won't add additional interfaces once it has started.
However, if the current interface is lost, say unplugged, the service is
automatically stopped and will be restarted as soon as a one (not
necessarily the same) is detected. It would be possible make this fully
dynamic by running another service that continously listen for udev
events and manages the main wpa_supplicant daemon, but this is probably
overkill.

I tested the following cases:

  • one interface, starting at boot, w/o predictable naming scheme
  • two interfaces, starting at boot (intel wireless and a usb adapter),
    w/o predictable naming scheme
  • one interface after the system booted, w/o predictable naming scheme
  • two interfaces after the system booted, w/o predictable naming scheme
  • unplugging and plugging back the current interface
Motivation for this change
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • 21.11 Release Notes
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@rnhmjoj rnhmjoj requested review from grahamc, bendlas and Ma27 June 20, 2021 20:06
@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Jun 20, 2021
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Jun 20, 2021
@mweinelt
Copy link
Member

Couldn't we just add After= and possibly BindsTo for the .device unit (e.g. sys-subsystem-net-devices-wlp8s0.device) that is managed by wpa_supplicant?

@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Jun 23, 2021

Couldn't we just add After= and possibly BindsTo for the .device unit (e.g. sys-subsystem-net-devices-wlp8s0.device) that is managed by wpa_supplicant?

Not if we don't know the interface name, ie. wireless.interfaces = [ ].

I may have finally found a clean solution to the issues[1][2][3] with
the automatic discovery of wireless network interfaces.

[1]: NixOS#101963
[2]: NixOS#23196
[3]: NixOS#125917 (comment)

Currently the start script fails right away if no interface is available
by the time it's running, possibly leaving the system without network.
This happens when running a little early in the boot. A solution is to
instead wait for at least one interface to appear before scanning the
/sys/class/net/ directory. This is done here by listening for the right
udev events (from the net/wlan subsystem) using the `udevadm monitor`
command and grep to match its output.

This methods guarantees the availability of at least one interface to
wpa_supplicant, but won't add additional interfaces once it has started.
However, if the current interface is lost, say unplugged, the service is
automatically stopped and will be restarted as soon as a one (not
necessarily the same) is detected. It would be possible make this fully
dynamic by running another service that continously listen for udev
events and manages the main wpa_supplicant daemon, but this is probably
overkill.

I tested the following cases:

  - one interface, starting at boot, w/o predictable naming scheme
  - two interfaces, starting at boot (intel wireless and a usb adapter),
    w/o predictable naming scheme
  - one interface after the system booted, w/o predictable naming scheme
  - two interfaces after the system booted, w/o predictable naming scheme
  - unplugging and plugging back the current interface
@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Aug 11, 2021

I fixed a subtle shell issue with the piping of udevadm and grep.
I tested everything again and on two machines with different network cards. It should be pretty safe to merge, now.

Copy link
Member

@mweinelt mweinelt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try this. Looks promising.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants