mac80211.sh: fix deadlock on configuring multiple PHYs simultaneously

When hitting a timing window where ubus configuration calls are hitting hostapd
and wpa_supplicant simultaneously, they can deadlock waiting for each other.
Fix this by using a lock around the ubus calls.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Felix Fietkau 2023-10-22 18:00:08 +02:00
parent 2d4552a96c
commit d5a1de17ad

View File

@ -19,6 +19,10 @@ wdev_tool() {
ucode /usr/share/hostap/wdev.uc "$@"
}
ubus_call() {
flock /var/run/hostapd.lock ubus call "$@"
}
drv_mac80211_init_device_config() {
hostapd_common_add_device_config
@ -903,7 +907,7 @@ wpa_supplicant_set_config() {
ubus wait_for wpa_supplicant
}
local supplicant_res="$(ubus call wpa_supplicant config_set "$data")"
local supplicant_res="$(ubus_call wpa_supplicant config_set "$data")"
ret="$?"
[ "$ret" != 0 -o -z "$supplicant_res" ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED
@ -913,12 +917,12 @@ wpa_supplicant_set_config() {
hostapd_set_config() {
[ -n "$hostapd_ctrl" ] || {
ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"${hostapd_conf_file}.prev"'" }' > /dev/null
return 0;
}
ubus wait_for hostapd
local hostapd_res="$(ubus call hostapd config_set "{ \"phy\": \"$phy\", \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")"
local hostapd_res="$(ubus_call hostapd config_set "{ \"phy\": \"$phy\", \"config\":\"${hostapd_conf_file}\", \"prev_config\": \"${hostapd_conf_file}.prev\"}")"
ret="$?"
[ "$ret" != 0 -o -z "$hostapd_res" ] && {
wireless_setup_failed HOSTAPD_START_FAILED
@ -933,7 +937,7 @@ wpa_supplicant_start() {
[ -n "$wpa_supp_init" ] || return 0
ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'" }' > /dev/null
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'" }' > /dev/null
}
mac80211_setup_supplicant() {
@ -1041,8 +1045,8 @@ mac80211_reset_config() {
local phy="$1"
hostapd_conf_file="/var/run/hostapd-$phy.conf"
ubus call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null
ubus call wpa_supplicant config_set '{ "phy": "'"$phy"'", "config": [] }' > /dev/null
ubus_call hostapd config_set '{ "phy": "'"$phy"'", "config": "", "prev_config": "'"$hostapd_conf_file"'" }' > /dev/null
ubus_call wpa_supplicant config_set '{ "phy": "'"$phy"'", "config": [] }' > /dev/null
wdev_tool "$phy" set_config '{}'
}