You are not logged in.

#1 2017-03-13 05:53:16

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,433

Restarting wpa_supplicant in a loop

Back to the topic.
I found that my wifi stops working, (though still having ip address), frequently especially when I am not close to the router. It starts working again if I restart wpa_supplicant. However If I enable systemd service I have to restart it manually everytime I loose net connection. So here is my solution.

#!/bin/bash

restartwifi() {
    [[ "$(pidof wpa_supplicant)" ]] && sudo killall wpa_supplicant && sleep 1
    sudo wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
    [[ ! "$(pidof dhcpcd)" ]] && sudo dhcpcd -4 wlan0
}

while true; do
    (ping -c 1 8.8.8.8 || restartwifi) &> /dev/null
    sleep 60
done

Offline

#2 2017-03-13 08:00:05

Awebb
Member
Registered: 2010-05-06
Posts: 6,273

Re: Restarting wpa_supplicant in a loop

Time to step up your game, Docbroke! Get rid of the sudo calls (and supposedly the sudoers/root autorun hack), by turning this into a systemd one-shot with a timer, so you can turn this while true...wait into something reliable and debuggable.

Offline

#3 2017-03-13 10:44:48

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,444
Website

Re: Restarting wpa_supplicant in a loop

I don't see why you'd need to restart a service any more "manually" than you do wpa_supplicant and dhcpcd.  Why not restart the service in the loop?  My work network is horribly crippled, and I regularly have to do something similar, but as I just use dhcpcd@<interface>.service with the wpa_supplicant hook, all I need is `systemctl restart dhcpcd@<interface>.service`.  I suppose I could have something like your loop:

while true; do
ping -c 1 8.8.8.8 || systemctl restart dhcpcd@wlp3s0.service
sleep 60;
done

But AWebb's timer suggestion would be better.  There's definitely no reason to put the check and restart in it's own subshell: you unconditionally create a new subshell every minute whether or not you are still connected.  If you want to redirect the output, you can do that without a subshell.  The subshell could actually cause real problems if it ever takes ~60 seconds to ping and restart the wireless as these are running in the background while "sleep 60" counts down.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#4 2017-03-13 18:10:00

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,433

Re: Restarting wpa_supplicant in a loop

Awebb & Trilby thank you both for your suggestions.
@Awebb, I was connecting to wifi manually for quite a sometime, which gradually lead me to add those commands to sudoers, just to avoid entering the password everytime. Though I soon intend to cleanup my sudoers and modify my script to use with systemd.
@Trilby, In my limited experience I have found that "systemctl restart wpa_supplicant*" doesn't work as well as stop,wait ~1 second and start the service, probably systemctl tries to start the service immediately even before it has stopped completely, therefore I am using "sleep 1" before starting wpa_supplicant again.
    Another point is restarting dhcpcd is mostly not needed, infact it doesn't always work as intended, (reason may be same as above), it is wpa_supplicant that needs restart. (at least in case of my wifi network)
    Yes, I used subshell to redirect the output, as I was trying to avoid polluting the terminal. I will remove that subshell.

Offline

#5 2017-03-13 18:37:40

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,444
Website

Re: Restarting wpa_supplicant in a loop

I don't use wpa_supplicant service directly, I just use the wpa_supplicant hook of dhcpcd@.service which has worked wonderfully.

When I do need to restart it I've never had an issue with just "systemctl restart dhcpcd@wlp3s0.service".  Perhaps the dhcpcd service handles this delay itself, I'm not sure: but I do know it always works for me.

On the subshell, I assume you thought that might be the way to redirect stderr as well, but there are better ways to do that:

command >/dev/null 2>&1

This directs the stdout of "command" to /dev/null and the stderr (fd 2) to stdout (fd 1) which is already going to /dev/null: so everything is silent.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#6 2017-03-13 19:22:37

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,433

Re: Restarting wpa_supplicant in a loop

I removed all "sudo", removed the subshell along with redirection, removed the while loop and added the script to root's crontab to run every minute and @reboot. It appers to be working fine there. ( in other words I found creating systemd timer very confusing)
About dhcpcd, I just remembered this, in past when I  start wpa_supplicant using dhcpcd hook, and I restart dhcpcd it doesn't kill wpa_supplicant, it just kills itself and starts again. So it fails to connect for me, as wpa_supplicant is not restarted. It may be possible that my wifi network needs wpa_supplicant to restart!!

Last edited by Docbroke (2017-03-13 19:23:33)

Offline

#7 2017-03-13 19:24:17

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,444
Website

Re: Restarting wpa_supplicant in a loop

So does mine.  I'm not sure why the behavior would be different, but when I restart dhcpcd.service it does stop and restart wpa_supplicant (if the wpa_supplicant process was started by dhcpcd service).


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#8 2017-03-13 19:41:43

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,433

Re: Restarting wpa_supplicant in a loop

try this, wpa_supplicant still running after killing dhcpcd (and wifi is still connected)

┌─[sharad] (01:07 AM)-(Tue Mar 14) [~]
└─ $ pidof wpa_supplicant

┌─[sharad] (01:07 AM)-(Tue Mar 14) !5135! [~]
└─ $ pidof dhcpcd

┌─[sharad] (01:07 AM)-(Tue Mar 14) !5136! [~]
└─ $ sudo dhcpcd -4 wlan0
[sudo] password for sharad:
wlan0: starting wpa_supplicant
wlan0: waiting for carrier
wlan0: carrier acquired
DUID 00:01:00:01:1d:80:7d:59:80:56:f2:b7:28:0f
wlan0: IAID f2:b7:28:0f
wlan0: rebinding lease of 192.168.2.101
wlan0: leased 192.168.2.101 for 3600 seconds
wlan0: adding route to 192.168.2.0/24
wlan0: adding default route via 192.168.2.1
forked to background, child pid 20978

┌─[sharad] (01:08 AM)-(Tue Mar 14) [~]
└─ $ sudo killall dhcpcd

┌─[sharad] (01:08 AM)-(Tue Mar 14) [~]
└─ $ pidof wpa_supplicant
20820

┌─[sharad] (01:08 AM)-(Tue Mar 14) [~]
└─ $ pidof dhcpcd

┌─[sharad] (01:08 AM)-(Tue Mar 14) !5140! [~]
└─ $

Offline

#9 2017-03-13 19:52:43

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,444
Website

Re: Restarting wpa_supplicant in a loop

That test is irrelevant: you explicitly start dhcpcd (and presumably wpa_supplicant).  Like I've said several times, I use the dhcpcd@.service with it's wpa_supplicant hook.  The *only* service I start/enable is dhcpcd@wlp3s0 this in turn starts wpa_supplicant (thus the dhcpcd service keeps track of the wpa_supplicant process).  If I were to manually kill wpa_supplicant and/or dhcpcd I suspect I'd have similar problems as you are having - but I don't do this.  Again, I only restart dhcpcd@.service which takes care of everything else.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#10 2017-03-13 20:10:11

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,433

Re: Restarting wpa_supplicant in a loop

It appears that dhcpcd started by systemd behaves differently. I checked the service file and couln't find the reason though. ( it starts as "dhcpcd -q -w %I"(interface) and stops as dhcpcd -x %I). I tried the same commands manually but it failed to kill wpa_supplicant.
And I didn't explicitly start wpa_supplicant in my test (as you can see pidof wpa_supplicant was absent before starting dhcpcd).
Anyway the issue of wifi is solved, time to take some sleep now. Good night.

Offline

#11 2017-03-14 02:34:34

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: Restarting wpa_supplicant in a loop

Splitting out as this has become its own support thread...


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#12 2017-03-14 06:10:30

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,433

Re: Restarting wpa_supplicant in a loop

So here is my current setup.

root's crontab

## start and keep connected to wifi at boot ##
@reboot /home/sharad/bin/netstart
* * * * * [[ ! -f /tmp/stopwifi ]] && /home/sharad/bin/netstart

netstart script

#!/bin/bash

restartwifi() {
    [[ "$(pidof wpa_supplicant)" ]] && killall wpa_supplicant && sleep 1
    wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
    [[ ! "$(pidof dhcpcd)" ]] && dhcpcd -4 wlan0
}

ping -c 1 8.8.8.8 || restartwifi

network script for manual use (to stop cronjob while connecting with mobile_broadband & more)

#!/bin/bash

stopwifi() {
    sudo killall wpa_supplicant
    sudo killall dhcpcd
}

echo -n "
choose, what to do with network?
	ww) startwifi	wx) stopwifi	ws) scan for wifi   wn) connect to new-wifi
	bb) bsnl	b2) bsnl2	ps) pppstatus	    px) stopppp	    pg) ping google
	uu) unblock	xx) exit
#?  "

read -n 2 ops
case $ops in
    ww)		rm /tmp/stopwifi; echo "wait for 1 min, please"; network ;;
    wx)		echo ""
		echo "stopping cronjob for wifi connection..."
		touch /tmp/stopwifi
		echo -n "do you want to stop wpa_supplicant and dhcpcd too? y/n $ "
		read -n 1 ANS
		if [[ $ANS = y ]]; then stopwifi; else echo "ok, bye"; fi
		network ;;
    wn)		echo ""
		wpa_cli scan wlan0 && wpa_cli scan_results wlan0
		echo ""
		echo -n "Network essid to use? $ "
		read ESSID
		echo -n "Password for $ESSID? $ "
		read PASS
		wpa_passphrase "$ESSID" "$PASS" 
		echo -n "write to wpa_supplicant.conf? $ "
		read ANS
		case $ANS in
		    y|yes|true) wpa_passphrase "$ESSID" "$PASS" | sudo tee -a /etc/wpa_supplicant/wpa_supplicant.conf > /dev/null && echo "successfully modified wpa_supplicant, exiting....." && sleep 1 ;;
		    n|no|false) echo "nothing modified, restarting..."; network ;;
		esac
		;;
    uu)		sudo rfkill unblock all; network ;;
    bb)		sudo pon bsnl ;;
    px)		sudo poff -a && network ;;
    b2)		sudo pon bsnl2 ;;
    ps)		grep pppd < /var/log/daemon.log; network ;;
#		journalctl -b --no-pager | grep pppd ;;
    x|xx)	echo ""
		echo "bye" && sleep 1 ;;
    pg)		echo ""
		ping -c 1 8.8.8.8 && echo success || echo failure 
		network ;;
    *)		echo "invalid option"; network ;;
esac

Offline

#13 2017-03-17 02:15:30

Docbroke
Member
From: India
Registered: 2015-06-13
Posts: 1,433

Re: Restarting wpa_supplicant in a loop

Just discovered a better way. This is to use "wpa_cli reassociate" inplace of restarting wpa_supplicant or dhcpcd. This one works without sudo and it's quicker to connect.

#!/bin/bash

restartwifi() {
    if [[ "$(pidof wpa_supplicant)" ]]; then 
	wpa_cli reassociate 
    else
	wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
    fi
    
    [[ ! "$(pidof dhcpcd)" ]] && dhcpcd -4 wlan0
}

ping -c 1 8.8.8.8 || restartwifi

Offline

Board footer

Powered by FluxBB