From 46513bab888f0d9c29e48d63c0146676a18a25e4 Mon Sep 17 00:00:00 2001 From: Andy Dixon Date: Fri, 9 Oct 2026 18:13:17 +0100 Subject: [PATCH] Hardware fixes: rpi_volt under-voltage fallback, dnsmasq except-interface=lo, installer AP check after iw install --- internal/netgen/netgen.go | 1 + internal/sysinfo/sysinfo.go | 15 +++++++++++++++ scripts/install.sh | 11 +++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/internal/netgen/netgen.go b/internal/netgen/netgen.go index 77e85ad..c73aef5 100644 --- a/internal/netgen/netgen.go +++ b/internal/netgen/netgen.go @@ -92,6 +92,7 @@ func DnsmasqConf(n config.Network) string { w("# Managed by PiLens. Changes are overwritten; use the PiLens UI.") w("interface=%s", n.AP.Interface) w("bind-dynamic") // only the AP interface; survives the address appearing late + w("except-interface=lo") // dnsmasq otherwise adds loopback implicitly w("no-hosts") w("domain-needed") w("bogus-priv") diff --git a/internal/sysinfo/sysinfo.go b/internal/sysinfo/sysinfo.go index 5eb30f9..ab24d24 100644 --- a/internal/sysinfo/sysinfo.go +++ b/internal/sysinfo/sysinfo.go @@ -231,6 +231,21 @@ func ReadHealth(paths map[string]string) Health { } } } + if h.Throttled == "" { + // vcgencmd needs /dev/vcio (root only on recent Pi OS). The rpi_volt hwmon + // under-voltage alarm is world-readable, so report that instead. + h.Throttled = "vcgencmd unavailable to the service user" + if m, _ := filepath.Glob("/sys/class/hwmon/hwmon*"); len(m) > 0 { + for _, d := range m { + if readTrim(d+"/name") == "rpi_volt" { + h.Throttled = "under-voltage alarm (rpi_volt): " + readTrim(d+"/in0_lcrit_alarm") + if readTrim(d+"/in0_lcrit_alarm") == "1" { + h.ThrottleBits = append(h.ThrottleBits, "under-voltage detected now") + } + } + } + } + } h.Load = readTrim("/proc/loadavg") up := strings.Fields(readTrim("/proc/uptime")) if len(up) > 0 { diff --git a/scripts/install.sh b/scripts/install.sh index 9ed217b..1ddbeff 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -83,9 +83,7 @@ echo " (a wired network is not trusted just because it is wired; narrow this # ---------------------------------------------------------------- 3-5. capabilities, resources, conflicts say "Checking Wi-Fi, resources and conflicts" -if command -v iw >/dev/null && [ -n "$WIFI" ]; then - iw list 2>/dev/null | awk '/Supported interface modes/{f=1;next} f&&/^\t\t\*/{print} f&&!/^\t\t\*/{f=0}' | grep -q '\* AP$' && echo " AP mode supported" || warn "Wi-Fi radio does not report AP mode support" -elif [ -z "$WIFI" ]; then warn "no Wi-Fi interface found; the access point cannot be configured"; fi +[ -z "$WIFI" ] && warn "no Wi-Fi interface found; the access point cannot be configured" FREE_MB=$(df -Pm / | awk 'NR==2{print $4}'); MEM_MB=$(awk '/MemTotal/{print int($2/1024)}' /proc/meminfo) echo " free disk ${FREE_MB} MiB, memory ${MEM_MB} MiB" [ "$FREE_MB" -ge 1024 ] || die "at least 1 GiB free disk space is required" @@ -154,7 +152,12 @@ export DEBIAN_FRONTEND=noninteractive apt-get update -qq >>"$LOG" 2>&1 || warn "apt-get update failed; trying with cached package lists" apt-get install -y -qq --no-install-recommends tshark wireshark-common nftables dnsmasq-base iw ca-certificates >>"$LOG" 2>&1 || die "apt-get install failed (see $LOG)" dpkg-reconfigure -f noninteractive wireshark-common >>"$LOG" 2>&1 || true -getcap /usr/bin/dumpcap | grep -q cap_net_raw || die "dumpcap has no capture capabilities after install (getcap /usr/bin/dumpcap)" + +if [ -n "$WIFI" ]; then + /usr/sbin/iw list 2>/dev/null | awk '/Supported interface modes/{f=1;next} f&&/^\t\t\*/{print} f&&!/^\t\t\*/{f=0}' | grep -q '\* AP$' \ + && echo " Wi-Fi radio supports AP mode" || warn "Wi-Fi radio does not report AP mode support: the access point may not start" +fi +/usr/sbin/getcap /usr/bin/dumpcap | grep -q cap_net_raw || die "dumpcap has no capture capabilities after install (getcap /usr/bin/dumpcap)" # dnsmasq-base must not bring a competing system dnsmasq service. systemctl is-enabled --quiet dnsmasq 2>/dev/null && warn "dnsmasq.service (full package) is enabled. Disable it, or make sure it does not listen on the AP interface."