Fix NetworkManager hotspot readiness

This commit is contained in:
v3d 2026-07-01 18:33:13 +02:00
parent 0f20889948
commit 3340108acd
5 changed files with 136 additions and 4 deletions

View file

@ -2,6 +2,7 @@
set -Eeuo pipefail
source /usr/local/lib/pivilion/common.sh
source /usr/local/lib/pivilion/networkmanager.sh
pivilion_require_root
pivilion_load_config || exit "$PIVILION_E_CONFIG"
@ -60,6 +61,7 @@ activation_error() {
if [ "$existing" = none ] || [ "$existing" = unknown ]; then
pivilion_write_state none "$BACKEND" failed "Activation failed at line $line (exit $rc)" || true
fi
if [ "$BACKEND" = networkmanager ]; then pivilion_nm_log_diagnostics "$IFACE"; fi
refresh_login_banner || true
logger -t pivilion-mode "Failed to activate $MODE mode at line $line (exit $rc)" 2>/dev/null || true
exit "$rc"
@ -208,6 +210,7 @@ update_torname() {
start_hotspot() {
pivilion_write_state none "$BACKEND" activating none
if [ "$BACKEND" = networkmanager ]; then pivilion_nm_prepare_interface "$IFACE"; fi
validate_ap_support || {
pivilion_write_state none "$BACKEND" failed "$IFACE does not advertise Wi-Fi AP support"
refresh_login_banner
@ -235,7 +238,7 @@ start_hotspot() {
nmcli connection modify "$NM_HOTSPOT" 802-11-wireless.mode ap 802-11-wireless.band bg \
802-11-wireless.channel "$PIVILION_HOTSPOT_CHANNEL" \
ipv4.method manual ipv4.addresses 10.1.1.1/24 ipv4.never-default yes ipv6.method disabled connection.autoconnect no
nmcli connection up "$NM_HOTSPOT"
pivilion_nm_connection_up "$NM_HOTSPOT" "$IFACE"
else
command -v dhcpcd >/dev/null 2>&1 && dhcpcd -k "$IFACE" 2>/dev/null || true
systemctl stop "wpa_supplicant@$IFACE.service" 2>/dev/null || true
@ -259,10 +262,14 @@ start_hotspot() {
start_onion() {
local failure=""
pivilion_write_state none "$BACKEND" activating none
if [ "$BACKEND" = networkmanager ]; then pivilion_nm_prepare_interface "$IFACE"; fi
cleanup_hotspot
rm -f "$CAPTIVE_LIVE"
if [ "$BACKEND" = networkmanager ]; then
nmcli connection up pivilion-onion >/dev/null 2>&1 || failure="No saved Pivilion Wi-Fi connection; run pikey"
nmcli connection up pivilion-onion >/dev/null 2>&1 || {
pivilion_nm_log_diagnostics "$IFACE"
failure="No saved Pivilion Wi-Fi connection; run pikey"
}
else
systemctl restart dhcpcd 2>/dev/null || true
systemctl restart "wpa_supplicant@$IFACE.service" 2>/dev/null || systemctl restart wpa_supplicant 2>/dev/null || true

View file

@ -0,0 +1,53 @@
#!/bin/bash
pivilion_nm_log_diagnostics() {
local iface=$1
{
echo "NetworkManager Wi-Fi diagnostics for $iface:"
echo "-- nmcli radio --"
LC_ALL=C nmcli radio || true
echo "-- nmcli device status --"
LC_ALL=C nmcli device status || true
echo "-- $iface state and reason --"
LC_ALL=C nmcli -f GENERAL.STATE,GENERAL.REASON device show "$iface" || true
echo "-- rfkill Wi-Fi state --"
rfkill list wifi || rfkill list || true
} >&2
}
pivilion_nm_prepare_interface() {
local iface=$1 timeout=${PIVILION_NM_READY_TIMEOUT:-30} state i
if ! nmcli radio wifi on; then
echo "NetworkManager could not enable the Wi-Fi software radio" >&2
pivilion_nm_log_diagnostics "$iface"
return 1
fi
if ! nmcli device set "$iface" managed yes; then
echo "NetworkManager could not mark $iface as managed" >&2
pivilion_nm_log_diagnostics "$iface"
return 1
fi
for ((i = 0; i < timeout; i++)); do
state=$(LC_ALL=C nmcli -g GENERAL.STATE device show "$iface" 2>/dev/null || true)
case "$state" in
*unmanaged*|*unavailable*|'10 '*|'20 '*|'') ;;
*) return 0 ;;
esac
sleep 1
done
echo "Timed out after ${timeout}s waiting for $iface to leave the unavailable/unmanaged state" >&2
pivilion_nm_log_diagnostics "$iface"
return 1
}
pivilion_nm_connection_up() {
local connection=$1 iface=$2
if ! nmcli connection up "$connection" ifname "$iface"; then
echo "NetworkManager could not activate $connection on $iface" >&2
pivilion_nm_log_diagnostics "$iface"
return 1
fi
}