Posts by dpapavas

    chewitt may well be right, but I can confirm that some firmwares, at least for the Broadcom chip in my 4B do indeed fail to load the correct MAC address and instead assign a random MAC address at module load time. This normally happens at boot, but it may also happen during operation if the firmware crashes.

    hiimLimp Try loading the firmware I'm currently using. You need to get the files ap6256/fw_bcm43456c5_ag.bin and ap6256/nvram_ap6256.txt from here and copy them to /storage/.config/firmware/brcm/, but under new names. For my 4B the names are brcmfmac43456-sdio.radxa,rockpi4b.bin and brcmfmac43456-sdio.radxa,rockpi4b.txt, I'm not sure what the designator for the Pi 4 SE is, so yours probably need to have something other than rockpi4b in there. chewitt will hopefully know what it is.

    I tried a recompile with wpa_supplicant, as suggested and have been using it for the past few days. The connection has certainly been more stable. I still get disconnects from my router

    Quote

    Mar 03 21:59:08 pi4b wpa_supplicant[513]: wlan0: CTRL-EVENT-DISCONNECTED bssid=c0:9f:51:23:10:8e reason=3

    but now it reconnects without issues. With iwd, I'd get failures such as the one described with the link-local address and also more curious cases, where Kodi would ask for a passphrase again (perhaps the MAC address changed on reconnect?). I asked Radxa, if they know of any issues with iwd, but they're using NetworkManager, for which iwd support is still experimental, so they use wpa_supplicant by default.

    Not sure if wpa_supplicant would be the appropriate choice for all Pi 4B users, but I though I'd mention my experience.

    I don't think it's just a matter of systemd service configuration. The wireguard service just issues a connmanctl connect vpn_name and exits, yes, so it has no way of monitoring the connection. In fact, due to connman pretty much always returning a succesful exit status, it has no way of knowing whether the connection was established at all. It's always successful.

    The openvpn service forks the process that actually establishes the connection and maintains it, so if something happens to the connection, this process fails and the whole service fails. One can then set this up, so that it also stops dependent services.

    The only ways I see of getting something similar with Wireguard, as handled by connman, is to either somehow use connman monitor services inside the wireguard service, to monitor the connection status, or to use the virtual network interface device that is created by udev and systemd.

    I've done the latter. Briefly, assume you get a wg0 network interface when the connection is established, then you also get a sys-devices-virtual-net-wg0.device systemd unit when that happens, which goes away if the connection is dropped for whatever reason. If you then want, say, kodi.service to only run when the VPN connection is up and running, you can add to its [Unit] section:

    Code
    Requires=wireguard.service
    After=wireguard.service
    BindsTo=sys-devices-virtual-net-wg0.device
    After=sys-devices-virtual-net-wg0.device

    This starts the wireguard service to (hopefully) establish the connection, but also waits for the connection to appear (via BindsTo on the virtual device) before starting Kodi. If then the connection is dropped, Kodi is also stopped.

    This is reliable, but still has a kink: Due to the way wireguard.service works, it remains "active", since it has no way of knowing that the connection has been dropped. So if you want to restart Kodi, you need to restart the wireguard.service manually first, because otherwise the dependent Kodi service thinks it's already started and never restarts the connection. If you only want the wireguard.service to start in tandem with Kodi, you can add the following to its [Unit] section:

    Code
    StopWhenUnneeded=true

    Then if the connection drops, Kodi is stopped, which makes the wireguard.service "unneeded", so it is stopped too.

    It does seem to work better. One issue I have though, is that if the connection is lost once I've started the service, connman reconnects to my wireless connection. And since the wireguard service has exited succesfully, even if I make it RequiredBy/Before another service, say kodi there doesn't seem to be a way to make sure that VPN always stays connected (unless perhaps explicitly and manually disconnected).

    Thanks for the pointer! Before trying that, I thought I'd try to set up my VPN connection with WireGuard. I've created a configuration file, but can't seem to be able to have it show up under connmanctl services. Here's the config file:

    The connman-vpn service is running normally. I can't see any sort of error in the logs. Any idea what might be wrong, or how I could go about troubleshooting it?

    First time I've heard of systemctl mask, I must confess. Thanks, I'll give it a try.

    I'm afraid though, that this is not the root of my problem, as I see now that I've been getting these "ping restarts" even without connman running. I've also been getting the following weird issues, seemingly only when openvpn is running, although it's hard to tell. Out of the blue I get a disconnect with

    and then it reconnects with a weird IP, which it obviously doesn't get from my router's DHCP.

    Quote

    Mar 01 12:20:52 pi4b connmand[532]: wlan0 {add} address 169.254.35.186/16 label wlan0 family 2
    Mar 01 12:20:52 pi4b connmand[532]: wlan0 {add} route 169.254.0.0 gw 0.0.0.0 scope 253 <LINK>
    Mar 01 12:20:52 pi4b connmand[532]: wlan0 {add} route 0.0.0.0 gw 0.0.0.0 scope 253 <LINK>
    Mar 01 12:20:52 pi4b connmand[532]: wlan0 {add} route 0.0.0.0 gw 0.0.0.0 scope 253 <LINK>

    I had reached out to Radxa, about the firmware, and one of their devs said I should make sure to disable WPA3, as it may give their devices connectivity problems. If you know how I can do that in LE, let me know.

    I've set up an openvpn-based connection, based on .config/system.d/openvpn.service.sample. It works, but I periodically get log messages such as these

    and the connection is unstable, i.e. some time after starting the openvpn service the device seems to lose internet connectivity. I have a hunch this may be due to the fact that the connman-vpn service is running at the same time, even though I have no active configuration for it. It seems though that onve I stop it, the above messages stop and the connection is more stable.

    The problem is that I can't seem to disable this service. It is shown as disabled, but is started nevertheless on next boot. I think that's because all these system services reside in /usr/lib/systemd/system, which is on a readonly partition, so that systemctl disable can't remove the symlinks that bind it to the multi-user target.

    Is there some way to disable the connman-vpn service?

    I've been using the firmware found here for a while and it seems the best I've tried so far. The files in question are ap6256/fw_bcm43456c5_ag.bin and ap6256/nvram_ap6256.txt and the version, as reported by the kernel driver, is:

    Quote

    Firmware: BCM4345/9 wl0: Jul 6 2020 11:29:52 version 7.45.96.68 (f9ee141@shgit) (r745790) FWID 01-b299bba7 es7.c5.n4.a3

    I get no suspicious messages with this firmware and it works well as far as I can see. There are some cases where the device isn't reachable from some of my other LAN devices, but a) this happens rarely, b) it seems to fix itself quickly and c) only happens from the Kore app on my tablet or phone, so that this may well be due to a bug in this app. I haven't had issues connecting via ssh on my desktop machine.

    I've also contacted Radxa and they've pointed me to try this image, which contains the firmware reported as

    Quote

    Firmware: BCM4345/9 wl0: Feb 11 2020 11:54:51 version 7.45.96.61 (be7af2d@shgit) (r745790) FWID 01-a41d86bd es7.c5.n4.a3

    mentioned a few messages back. As I've said, I've tried it briefly, and it seemed to work mostly correct too (i.e the proper MAC address was set and retained), but there were a lot of messages about SDIO errors and I seemed to have more of the issues regarding reachability.

    It's hard to be very definite, as testing each firmware entails waiting for hours or days for issues to appear, so pehaps the Feb 11 firmware was just as good, but at any rate, I can recommend the one from Jul 6, which I've used for days and seems to work fine, as far as I can tell.

    You cannot store things directly in /var/lib/alsa because /var resides inside a read-only squashfs file that's decompressed on boot to create a non-persistent virtual filesystem.

    Ah, yes. I lazily just quickly tested /var for writability and didn't look much deeper ^^

    So, I used systemd-tmpfiles to create /storage/.cache/alsa/ plus a symlink /var/lib/alsa -> /storage/.cache/alsa. Seems to work fine, is simple to do and has the extra benefit of retaining the "usual" setup as much as possible.

    I think I have enough for a first PR now, at least as a basis for further disucssion. I'll review it again and probably open it tomorrow.

    I realize I've probably not been very clear. The system-shipped functionality I'm trying to restore, is this. So the service saves the state on shutdown by default, but can be configured to run as a daemon, saving the state as it is changed. The end result is the same: the user can make desired changes and these are persisted across reboots. This is essentially the same as the existing approach, only there's no need on behalf of the user to save the state of the sound cards; just to set it.

    That should be possible; I'll look into it. If we do change the state directory though, to either of these choices, the directory still won't exist. How should it be created?

    Also, out of curiosity, why change the default setting? It is the appropriate location, at least per the standards. Quoting from the Filesystem Hierarchy Standard, on the purpose of /run:

    Quote

    This directory contains system information data describing the system since it was booted. Files under this directory must be cleared (removed or truncated as appropriate) at the beginning of the boot process.

    On the other hand, about /var/lib:

    Quote

    This hierarchy holds state information pertaining to an application or the system. State information is data that programs modify while they run, and that pertains to one specific host.

    I'm trying to restore the default alsa-utils functionality regarding card state handling and it's relatively straightforward so far, except for one point. By default alsactl attempts to store state to /var/lib/alsa/asound.state but /var/lib/alsa/ does not exist, because it is not created. So when the alsa-restore service runs, trying to save the state at shutdown, it fails.

    As far as I can see, various package-created directories are explicitly removed by the build scritps, and this includes /var/* directories, so I suppose this is all intended and I wonder what the preferred way of handling this would be. Should we:

    1. Try to change the default ALSA state file to something else, like .config/sound.conf. I don't think so since this is always overwrriten by the system at shutdown, saving the current state.

    2. Recreate the /var/lib/alsa/ directory post-install? If so, what would be the canonical way to do that?

    3. Do omething else?

    Ah, I think I've found the issue. According to the udev(8) man page, regading the RUN action:

    Quote

    Starting daemons or other long-running processes is not allowed; the forked processes, detached or not, will be unconditionally killed after the event handling has finished.

    Debian's system-shipped rule does call alsactl via RUN though, so I suppose that's fine.

    Great, I'll look into it a bit more and open a PR then. So, to your knowledge, there may be no reason (any more) not to use the system-shipped rules? If not, I could try to restore those, since the existing setup does seem to be a bit ad-hoc. My only concern is with testing, as LE runs on a lot of disparate setups and I can only test it on one of those.

    I understand that the intended way of restoring a custom mixer state for ASLA sound cards on boot, is to do something like

    Code
    alsactl store -f /storage/.config/sound.conf

    which would then restore the state of the mixers of all devices to that stored when the above command was executed. This does not quite work for me.

    Running

    Code
    alsactl restore-f $HOME/.config/sound.conf

    manually at any point via SSH works fine, but it doesn't work on boot, even though the soundconfig script does run (i.e. I do see "Setting up sound card" in the journal logs).

    There seem to be various interesting things about that setup. First, the udev rule in charge of running this script, is

    Code
      KERNEL=="controlC[0-9]*",  NAME="snd/%k", ACTION=="add", RUN+="soundconfig %k"

    Now that NAME="snd/%k" part, which presumably is meant to say something like "match only events having to do with snd/controlC*", actually is an action saying "rename this network interface to that". As this is not a network inteface, the journal has lines like

    Quote

    (udev-worker)[402]: controlC1: /usr/lib/udev/rules.d/90-alsa-restore.rules:5 Only network interfaces can be renamed, ignoring NAME="snd/%k".

    and that action has no effect. The system-shipped rule on my PC additionally has a KERNELS!="card*" rule. I'm not quite clear on what it's there for, but if I'm interpreting the intent of that NAME action correctly, I suspect it's doing something similar.

    On another note, that KERNEL=="controlC[0-9]*" looks like its meant to be a regular expression, saying "controlC, potentially followed by numbers", but these are actually glob patterns, so it means "controlC, followed by a number and whatever else". If that is the case, it doesn't hurt, but the rule on my PC has just KERNEL=="controlC*", which is probably enough.

    Moving on to the soundconfig script, the relevant portion in it, reads:

    Code
    if [ -f $HOME/.config/sound.conf ]; then
     alsactl restore -f $HOME/.config/sound.conf
    else
    ...

    One issue with this, is that it gets run when each card gets added to the system, and when there's no saved state, it does initialize that specific card. When there is a saved state though, it attempts to reset the state of all cards each time a new card gets added. That probably doesn't break anything but it should result in some wasted work. The restore command does take an optional card argument, so that can be improved.

    Anyway, all of that doesn't seem to have anything to do with my problem. My problem seems to be more insidious and I suspect there's some sort of race going on. I've tried various changes and got it to work, but I'm not sure as to the how and why. It seems that after attaching something like > /tmp/log 2>&1 to the end of the alsactl command (which I did just to get any error messages) it did work. If I then removed it, it kept working for some reason. (I should say here that for testing purposes, I installed a copy of the system-wide udev rule inside /etc/udev/rules.d, running a copy of soundconfig, which I could then edit and retry, by removing and reloading my sound card's module to get the device to disappear and reappear.)

    I took a guess and removed that final & in the soundconfig script, backgrounding the whole subshell and it now works correctly. I'm not sure why, but I have the vague notion that the main script's shell exits before the subshell has finished and something tricky happens there.

    So, in conclusion:

    1. Does this work for you?

    2. Is there some specific reason for backgrounding the subshell?

    3. I have a patch for most of the changes discussed here. Would there be interest in trying them out and potentially applying them? Should I open a PR?