random-archer / mkinitcpio-systemd-tool

Provisioning tool for systemd in initramfs (systemd-tool)
https://www.archlinux.org/packages/community/any/mkinitcpio-systemd-tool/
Other
113 stars 27 forks source link

Wi-fi interface doesn't exist #27

Closed C0rn3j closed 4 years ago

C0rn3j commented 5 years ago

When using systemd-tool hook my laptop does not detect its internal wi-fi card. There's wi-fi no interface in ip a at all, ethernet works.

Plugging in a USB wi-fi adapter works fine. FN+wifi button combo does nothing besides enabling/disabling bluetooth which is also present on the chip.

Only the first line exists in dmesg if initramfs is generated with systemd-tool included:

[   11.865321] iwlwifi 0000:08:00.0: loaded firmware version 17.3216344376.0 op_mode iwlmvm
[   12.023498] iwlwifi 0000:08:00.0: Detected Intel(R) Dual Band Wireless AC 3160, REV=0x164
[   12.042434] iwlwifi 0000:08:00.0: base HW address: 2c:6e:aa:aa:aa:aa
[   12.154954] ieee80211 phy0: Selected rate control algorithm 'iwl-mvm-rs'
[   12.157350] iwlwifi 0000:08:00.0 wlp8s0: renamed from wlan0

System info:

systemd 242.32-3
Linux test 5.2.0-arch2-1-ARCH #1 SMP PREEMPT Mon Jul 8 18:18:54 UTC 2019 x86_64 GNU/Linux
HOOKS=(base systemd autodetect keyboard sd-vconsole modconf block sd-encrypt sd-lvm2 filesystems fsck systemd-tool)
[0] # cat /proc/cmdline
initrd=\intel-ucode.img initrd=\initramfs-linux.img rd.luks.name=5054b30f-5441-4052-853b-3be38e4a9a33=cryptlvm root=/dev/ArchVol/root rw
Andrei-Pozolotin commented 5 years ago
  1. probably that has to do with initrd-network.network interface name filter: https://github.com/random-archer/mkinitcpio-systemd-tool/blob/master/initrd-network.network#L10

  2. try to add new initrd-network-wifi.network file with proper name filter

  3. also verify enable/disable works fine for the wifi interface: https://github.com/random-archer/mkinitcpio-systemd-tool/blob/master/initrd-network.service#L18

C0rn3j commented 5 years ago

What would the proper name filter be? All three combos when editing initrd-network.network directly result in a broken wi-fi on boot.

Name=eth*
#Name=en*
#Name=eth*
Name=en*
Name=eth*
Name=en*
Andrei-Pozolotin commented 5 years ago
  1. connect first with ethernet, not wifi, then ip ad and look around

  2. note the difference: kernel vs udev names: https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/ https://unix.stackexchange.com/questions/400893/renaming-my-wlan-network-interface

  3. likely boot time name is wlan0

C0rn3j commented 5 years ago
=> ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
    link/ether d4:be:d9:52:f3:3c brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.15/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 43181sec preferred_lft 43181sec

I don't see the interface at all in initramfs

Andrei-Pozolotin commented 5 years ago
  1. load a driver module in initramfs (by checking what is present in non-initramfs)

  2. sample snippet from network.service

    
    # graphics: intel
    InitrdCall=add_module i915

network: wifi

InitrdCall=add_module iwldvm

network: wire

InitrdCall=add_module e1000e

C0rn3j commented 5 years ago

I've an intel card - https://haste.rys.pw/raw/rawevumupi

So I added InitrdCall=add_module i915 to the end of /etc/systemd/system/initrd-network.service and rebuilt the initramfs, but I still get no wifi interface in ip a in the initramfs nor in the booted system

Andrei-Pozolotin commented 5 years ago
  1. no. i915 is just an example of graphic driver, will not help wifi

  2. find wifi driver via lsmod on non-initramfs, for example on my laptop: https://cateee.net/lkddb/web-lkddb/IWLMVM.html

    lsmod|grep wl
    iwldvm                282624  0
    mac80211              999424  5 iwldvm,rtl_usb,rtl8192cu,rtlwifi,rtl8xxxu
    iwlwifi               385024  1 iwldvm
    cfg80211              856064  4 iwldvm,rtlwifi,iwlwifi,mac80211
  3. see https://wiki.archlinux.org/index.php/Wireless_network_configuration#Device_driver

C0rn3j commented 4 years ago

Sorry for the delay.

lspci -k tells me iwlwifi is in use, so I edited the InitrdCall line to match that.

08:00.0 Network controller: Intel Corporation Wireless 3160 (rev 83)
        Subsystem: Intel Corporation Dual Band Wireless-AC 3160
        Kernel driver in use: iwlwifi
        Kernel modules: iwlwifi

After rebuilding initramfs I still get no wi-fi interface in the initramfs and no wi-fi in the booted OS however.

My initrd-network.network is as follows -

cat /etc/systemd/network/initrd-network.network | grep -v \#
[Match]
Name=eth*
Name=wlan*

[Network]
DHCP=ipv4

[DHCP]
UseHostname=true
Andrei-Pozolotin commented 4 years ago
  1. what do you see for lsmod|grep wl inside initrd?

  2. have you applied proper wifi config while logged in initrd?

  3. you next step would be to setup wpa-supplicant in inside initrd

Andrei-Pozolotin commented 4 years ago

closing as obsolete. feel free to re-open if is still relevant

phinfinity commented 3 years ago

Apologies for bumping an old bug. I ran into this exact same issue and figured out the fix after a while.

Adding iwlmvm to MODULES in /etc/mkinitcpio.conf fixed the interface not loading issue for me. For some reason this does not automatically get picked up by mkinitcpio, effectively loading iwlwifi too early, and preventing my wireless card from being detected correctly even later when iwlmvm gets loaded. (Others might need a different module: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi#firmware)

Andrei, could you please give me some pointers on how to setup wpa_supplicant inside of systemd initramfs init? I don't know how to get the wpa supplicant service to startup inside the initramfs.

Andrei-Pozolotin commented 3 years ago

@phinfinity

  1. there is no conceptual difference between running systemd/wpa-supplicant in rootfs vs initramfs only need to make sure that required service, config, binary files are baked into the initrd image

  2. start by making sure that you can follow this guide https://wiki.archlinux.org/title/Wpa_supplicant and make wpa-supplicant work inside initramfs manually, via terminal, in debug mode this will force you to generate proper wpa-supplicant config file and discover required/missing dependencies

  3. finally, you need to produce the following:

your own, brand new initrd-wireless.network and initrd-wireless.service, by combining features form

a) this-project-provided initrd-network.network and initrd-network.service:

b) wpa_supplicant/systemd-provided wpa_supplicant-XXX.service, config, etc.:

  1. please post your results here
phinfinity commented 3 years ago

Hi Andrei, Thanks very much for the suggestions! I managed to combine your suggestions get my wifi device working for remote unlock on boot. I added & enabled a new custom service under /etc/systemd/system/initrd-wifi.service. I edited the existing initrd-network.network to manage wlan0 and added a dependency on it to re-use it.

Contents of my initrd-wifi.service

[Unit]
Description=Initrd Wpa Service
ConditionPathExists=/etc/initrd-release
Requires=initrd-network.service
After=initrd-network.service
Before=cryptsetup-pre.target
Before=initrd-tinysshd.service
DefaultDependencies=no

[Service]
# Sleep because some weird ordering issue for wlan0 not being available immediately.
ExecStart=/usr/bin/sh -c "/usr/bin/sleep 5; /usr/bin/wpa_supplicant -W -i wlan0 -c /etc/mkinitcpio-systemd-tool/network/wpa_supplicant.conf"

[Install]
WantedBy=sysinit.target

[X-SystemdTool]

InitrdPath=/etc/mkinitcpio-systemd-tool/network/wpa_supplicant.conf
InitrdBinary=/usr/bin/wpa_supplicant

I created the wpa_supplicant.conf with my wifi details using wpa_passphrase. Normal system wpa_supplicant service has an "After=sys-subsystem-net-devices-%i.device" , but mkinitcpio always errors & fails to find this service if I specify it. So I had to use a sleep as hacky solution for waiting till my wifi device gets initialized. Without it , it was getting started too early and would fail to find wlan0 properly.

Thanks for your help!

Andrei-Pozolotin commented 3 years ago
  1. great, thank you for the update

  2. please publish your result, including file templates, on the wiki: https://github.com/random-archer/mkinitcpio-systemd-tool/wiki/Case:-Wireless

  3. perhaps sleep/hack can be corrected by introduction of a dedicated initrd-wifi.network file, i.e:

    
    #
    # wireless network
    #

[Match] Type=wlan

[Network] DHCP=ipv4 IPForward=ipv4 LinkLocalAddressing=no

[DHCP] UseHostname=true RouteMetric=2048

phinfinity commented 3 years ago

Sure, Updated https://github.com/random-archer/mkinitcpio-systemd-tool/wiki/Case:-Wireless.

I tried several more attempts to avoid the sleep hack, but none of them worked & I gave up finally. Mentioning a few of my attempts in case it's useful for others:

I tried the above initrd-wifi.network, but didn't seem to help. I tried adding various After= systemd dependencies but none of them helped either.

I think the problem is that systemd-networkd.service is what actually sets up wlan0 & wpa_supplicant must only run after that. Everytime I've seen through systemctl status wpa_supplicant always runs earlier in time before systemd-networkd.service gets a chance to setup wlan0.

Adding After=systemd-networkd.service didn't help, because systemd-networkd.service isn't a oneshot, it stays running. I've also tried After=systemd-networkd-wait-online.service but the wait-online service just hangs even if I set a lower MIN_OPERSTATE. After=sys-subsystem-net-devices-wlan0.device is what the native system-level wpa_supplicant.service uses , but that didn't work either.

Anyways, I guess I can live with the sleep hack :) , Thanks for your help!

Andrei-Pozolotin commented 3 years ago

your wiki looks good, thank you

pierrou-andreas commented 3 years ago

I created the wpa_supplicant.conf with my wifi details using wpa_passphrase. Normal system wpa_supplicant service has an "After=sys-subsystem-net-devices-%i.device" , but mkinitcpio always errors & fails to find this service if I specify it. So I had to use a sleep as hacky solution for waiting till my wifi device gets initialized. Without it , it was getting started too early and would fail to find wlan0 properly.

I think I have, to some degree, got this working for me without the sleep hack. If I only add After=sys-subsystem-net-devices-wlan0.device (and not Requires=...) to initrd-wifi.service, mkinitcpio does not complain about not finding the unit, but in that case wpa_supplicant starts before the wlan0 device is present. However, if I also add Requires=sys-subsystem-net-devices-wlan0.device, mkinitcpio complains (showing error messages about not finding the service), but still builds a functional and bootable initramfs in which wpa_supplicant waits for the wlan0 device to be present before it starts. For some reason, mkinitcpio is not able to detect that sys-subsystem-net-devices-wlan0.device is an auto-generated unit but instead seems to try to find a .device-file for it.

If you are able to reproduce this solution, I can update the wiki with it.

Though, it feels wrong to have to ignore error messages to get it working without the sleep hack.