mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
mac80211: Fix race condition leading to wifi interfaces not coming up at boot sometimes.
In the drv_mac80211_setup function, mac80211_interface_cleanup
is called to ask the kernel to delete all existing interfaces
for the phy that is being configured via netlink.
Later in the first function, mac80211_prepare_vif is called to
set up the new interfaces as required.
But sometimes, when mac80211_prepare_vif (and so the relevant
`iw phy x interface add y` command) runs, the kernel might still
be cleaning up the old interface with the same ifname. It usually
takes very few time to do that; possibly a few milliseconds of
sleep in the script after detecting this error condition could be
enough, but the busybox sh does not support sub-second sleep
intervals.
When this happens, iw obviously fails to create the new interface;
and the following message is printed in the system log, followed by
subsequent failure messages from hostapd in case this would have been
an AP interface.
Tue Mar 14 04:21:57 2017 daemon.notice netifd: radio1 (2767): command failed: Too many open files in system (-23)
This was a long-standing issue existing since at least OpenWrt Backfire,
and today I finally managed to debug and (hopefully) solve it.
It was happening very few times on most devices; but it was happening
a lot more frequently on fast platforms with multiple radios, such as
the powerpc-based dual-ath9k-radio tl-wdr4900-v1.
Signed-off-by: Vittorio Gambaletta <openwrt@vittgam.net>
(cherry picked from commit 8301e61365
)
This commit is contained in:
parent
5f03ce1213
commit
62a8252a0f
@ -411,6 +411,28 @@ mac80211_check_ap() {
|
|||||||
has_ap=1
|
has_ap=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mac80211_iw_interface_add() {
|
||||||
|
local phy="$1"
|
||||||
|
local ifname="$2"
|
||||||
|
local type="$3"
|
||||||
|
local wdsflag="$4"
|
||||||
|
local rc
|
||||||
|
|
||||||
|
iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
|
||||||
|
rc="$?"
|
||||||
|
|
||||||
|
[ "$rc" = 233 ] && {
|
||||||
|
# Device might have just been deleted, give the kernel some time to finish cleaning it up
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
|
||||||
|
rc="$?"
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
mac80211_prepare_vif() {
|
mac80211_prepare_vif() {
|
||||||
json_select config
|
json_select config
|
||||||
|
|
||||||
@ -437,7 +459,7 @@ mac80211_prepare_vif() {
|
|||||||
# It is far easier to delete and create the desired interface
|
# It is far easier to delete and create the desired interface
|
||||||
case "$mode" in
|
case "$mode" in
|
||||||
adhoc)
|
adhoc)
|
||||||
iw phy "$phy" interface add "$ifname" type adhoc
|
mac80211_iw_interface_add "$phy" "$ifname" adhoc || return
|
||||||
;;
|
;;
|
||||||
ap)
|
ap)
|
||||||
# Hostapd will handle recreating the interface and
|
# Hostapd will handle recreating the interface and
|
||||||
@ -451,21 +473,21 @@ mac80211_prepare_vif() {
|
|||||||
mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return
|
mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return
|
||||||
|
|
||||||
[ -n "$hostapd_ctrl" ] || {
|
[ -n "$hostapd_ctrl" ] || {
|
||||||
iw phy "$phy" interface add "$ifname" type __ap
|
mac80211_iw_interface_add "$phy" "$ifname" __ap || return
|
||||||
hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}"
|
hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}"
|
||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
mesh)
|
mesh)
|
||||||
iw phy "$phy" interface add "$ifname" type mp
|
mac80211_iw_interface_add "$phy" "$ifname" mp || return
|
||||||
;;
|
;;
|
||||||
monitor)
|
monitor)
|
||||||
iw phy "$phy" interface add "$ifname" type monitor
|
mac80211_iw_interface_add "$phy" "$ifname" monitor || return
|
||||||
;;
|
;;
|
||||||
sta)
|
sta)
|
||||||
local wdsflag=
|
local wdsflag=
|
||||||
staidx="$(($staidx + 1))"
|
staidx="$(($staidx + 1))"
|
||||||
[ "$wds" -gt 0 ] && wdsflag="4addr on"
|
[ "$wds" -gt 0 ] && wdsflag="4addr on"
|
||||||
iw phy "$phy" interface add "$ifname" type managed $wdsflag
|
mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return
|
||||||
[ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
|
[ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
|
||||||
iw "$ifname" set power_save "$powersave"
|
iw "$ifname" set power_save "$powersave"
|
||||||
;;
|
;;
|
||||||
|
Loading…
Reference in New Issue
Block a user