Reinicie automaticamente, se não houver conexão wifi por um determinado período

13

Parece que meu servidor Raspberry Pi perde a conexão wifi após um tempo aleatório e, de alguma forma, não é capaz de se recuperar automaticamente.

Normalmente, uma reinicialização feita manualmente resolve o problema.

Gostaria de fazê-lo reiniciar automaticamente se não houver wifi após cerca de 30 minutos. Como eu posso fazer isso?

braçadeira
fonte
5
Você já tentou desativar a interface e trazê-la de volta? Que tal descarregar e recarregar o módulo do kernel da sua placa wireless? Pode haver outra coisa que você pode fazer para redefinir o cartão sem reiniciar.
hololeap
1
Sim, isso provavelmente também funcionaria, mas o principal problema aqui é como detectar isso automaticamente e executar a ação apropriada.
Clamp

Respostas:

10

Esta é essencialmente a resposta de Warwick, apenas com instruções passo a passo.


  1. Crie o seguinte script de shell na sua pasta pessoal:

    check_inet.sh

    #!/bin/bash
    
    TMP_FILE=/tmp/inet_up
    
    # Edit this function if you want to do something besides reboot
    no_inet_action() {
        shutdown -r +1 'No internet.'
    }
    
    if ping -c5 google.com; then
        echo 1 > $TMP_FILE
    else
        [[ `cat $TMP_FILE` == 0 ]] && no_inet_action || echo 0 > $TMP_FILE
    fi
    
  2. Altere as permissões para que seja executável

    $ chmod +x check_inet.sh
    
  3. Edite /etc/crontabusando sudoe adicione a seguinte linha (substitua yournamepelo seu nome de usuário real):

    */30 * * * * /home/yourname/check_inet.sh
    
Hololeap
fonte
5

Uma maneira seria colocar uma entrada no cron do root que executa um script a cada 30 minutos. O script testaria a conexão WIFI, talvez usando ping, e gravaria o resultado em um arquivo em / tmp - 1 para a conexão existir, 0 se não existir. As iterações subsequentes do script verificariam esse arquivo e, se fosse 0, e a conexão WIFI ainda estivesse ruim, execute um init 6comando.

Warwick
fonte
3

Acho que a solução hololeap está funcionando.

Minha solução verifica a cada N minutos (dependendo de como você configura seu crontab) em busca de uma conexão de rede em funcionamento. Se a verificação falhar, acompanho a falha. Quando a contagem de falhas é> 5, tento reiniciar o wifi (você também pode reiniciar o Raspberry se a reinicialização do wifi falhar, verifique os comentários).

Aqui está um repositório do GitHub sempre contendo a versão mais recente do script: https://github.com/ltpitt/bash-network-repair-automation

Aqui está, de acordo com a política geral de stackexchange (todas as respostas não devem conter apenas links), também o arquivo network_check.sh, copie e cole-o em qualquer pasta que você desejar, as instruções de instalação estão nos comentários do script.

#!/bin/bash
# Author:
# twitter.com/pitto
#
# HOW TO INSTALL:
#
# 1) Install ifupdown and fping with the following command:
# sudo apt-get install ifupdown fping
#
# 2) Then install this script into a folder and add to your crontab -e this row:
# */5 * * * * /yourhome/yourname/network_check.sh
#
# Note:
# If you want to perform automatic repair fsck at reboot
# remember to uncomment fsck autorepair here: nano /etc/default/rcS

# Let's clear the screen
clear

# Write here the gateway you want to check to declare network working or not
gateway_ip='www.google.com'

# Here we initialize the check counter to zero
network_check_tries=0

# Here we specify the maximum number of failed checks
network_check_threshold=5

# This function will be called when network_check_tries is equal or greather than network_check_threshold
function restart_wlan0 {
    # If network test failed more than $network_check_threshold
    echo "Network was not working for the previous $network_check_tries checks."
    # We restart wlan0
    echo "Restarting wlan0"
    /sbin/ifdown 'wlan0'
    sleep 5
    /sbin/ifup --force 'wlan0'
    sleep 60
    # If network is still down after recovery and you want to force a reboot simply uncomment following 4 rows
    #host_status=$(fping $gateway_ip)
    #if [[ $host_status != *"alive"* ]]; then
    #    reboot
    #fi
}

# This loop will run network_check_tries times and if we have network_check_threshold failures
# we declare network as not working and we restart wlan0
while [ $network_check_tries -lt $network_check_threshold ]; do
    # We check if ping to gateway is working and perform the ok / ko actions
    host_status=$(fping $gateway_ip)
    # Increase network_check_tries by 1 unit
    network_check_tries=$[$network_check_tries+1]
    # If network is working
    if [[ $host_status == *"alive"* ]]; then
        # We print positive feedback and quit
        echo "Network is working correctly" && exit 0
    else
        # If network is down print negative feedback and continue
        echo "Network is down, failed check number $network_check_tries of $network_check_threshold"
    fi
    # If we hit the threshold we restart wlan0
    if [ $network_check_tries -ge $network_check_threshold ]; then
        restart_wlan0
    fi
    # Let's wait a bit between every check
    sleep 5 # Increase this value if you prefer longer time delta between checks
done

editar 26/01/2018: removi os arquivos temporários para permitir a execução do script na memória e evitar a gravação no cartão SD do Raspberry.

Pitto
fonte
1
Este script evita a reinicialização em desconexões temporárias. Excelente, obrigado!
wezzix
1
Você parece ter feito uma grande mudança neste script. Pelo que entendi, a versão anterior faria uma passagem, fazendo coisas (incluindo a atualização de arquivos tmp) e saindo. Não contém loops; em vez disso, dependia do cron para executá-lo a cada cinco minutos. Se a rede estivesse inoperante por cinco verificações consecutivas (por um período de cerca de meia hora), o script faria o possível para redefinir a rede. Essa parecia ser uma boa resposta para a pergunta, embora o fato de ela ter sido gravada em arquivos tmp fosse uma desvantagem. ... (continua)
Scott
(Continua)… A nova versão contém um loop e verifica a rede a cada cinco segundos . Se a rede estiver inativa por cinco verificações consecutivas (ou seja, por um período de cerca de meio minuto ), o script fará o possível para redefinir a rede. (Isso parece ser diferente do que a pergunta pede.) E aqui fica um pouco estranho. Depois de detectar uma falha de rede cinco vezes consecutivas e redefinir a rede, o script é encerrado. (E, aliás, ele sai sem nunca verificar se a rede realmente veio para cima.) ... (Cont)
Scott
(Continua) ... Mas, enquanto a rede estiver ativa, o script continuará sendo executado para sempre, aguardando a falha da rede. Enquanto isso, o cron continua reiniciando o script a cada cinco minutos. Se a rede permanecer ativa por uma hora, haverá uma dúzia de cópias do script em execução. E, se a rede falhar , essas dúzias de processos se enfrentam, fazendo de forma assíncrona ifdowne ifup, talvez, consertando a rede, e talvez não. ………………………………………………………………………… Se eu entendi algo errado, por favor, explique-me. ... (continua)
Scott
(Continua) ... (1) Se você pretende fazer uma reformulação tão importante de uma resposta publicada há mais de um ano, deve dizer o que fez. “Eu removi os arquivos temporários para permitir que o script seja executado na memória” não é uma descrição adequada das suas alterações. (2) Parece que você tem uma coleção de pinos quadrados, pinos redondos, orifícios quadrados e orifícios redondos, e não os combinou corretamente. Você deve modificar o script para sair quando perceber que a rede está ativa ou modificá-lo para rodar para sempre e alterar o crontab para iniciar o script apenas uma vez (ou seja, no momento da inicialização).
Scott Scott
0

I modiffied roteiro de Pitto para o meu MTAC Multitech loraWAN gateway (sem fping). Eu também adicionei um arquivo de log.

#!/bin/bash
# Author: 
# twitter.com/pitto
#
# HOW TO INSTALL:
#
# 1) Install ifupdown with the following command:
# sudo apt-get install ifupdown
#
# 2) Create files in any folder you like (ensure that the filename variables, set below,
# match the names of the files you created) with the following commands:
# sudo touch /home/root/scripts/network_check_tries.txt &&
#                               sudo chmod 777 /home/root/network_check_tries.txt
# sudo touch /home/root/scripts/N_reboots_file.txt      &&
#                               sudo chmod 777 /home/root/N_reboots_file.txt
# sudo touch /home/root/scripts/network_check.log       &&
#                               sudo chmod 777 /home/root/network_check.log
#
# 3) Then install this script into a folder and add to your crontab -e this row:
# */5 * * * * /yourhome/yourname/network_check.sh
#
# Note:
# If additionally you want to perform automatic repair fsck at reboot
# remember to uncomment fsck autorepair here: nano /etc/default/rcS

# Specify the paths of the text file where the network failures count, reboot count,
# and log will be held:
network_check_tries_file='/home/root/network_check_tries.txt'
N_reboots_file='/home/root/N_reboots_file.txt'
log_file='/home/root/network_check.log'

# Save file contents into corresponding variables:
network_check_tries=$(cat "$network_check_tries_file")
N_reboots=$(cat "$N_reboots_file")


# If host is / is not alive we perform the ok / ko actions that simply involve
# increasing or resetting the failure counter
ping -c1 google.com
if [ $? -eq 0 ]
then
    # if you want to log when there is no problem also,
    # uncomment the following line, starting at "date".
    echo 0 > "$network_check_tries_file" #&& date >> "$log_file" && echo -e "-- Network is working correctly -- \n" >> "$log_file"
else
    date >> "$log_file" && echo -e "-- Network is down... -- \n" >> "$log_file" && echo "$(($network_check_tries + 1))" > "$network_check_tries_file"
fi

# If network test failed more than 5 times (you can change this value to whatever you
# prefer)
if [ "$network_check_tries" -gt 5 ] 
then
    # Time to restart ppp0
    date >> "$log_file" && echo "Network was not working for the previous $network_check_tries checks." >> "$log_file" && echo "Restarting ppp0" >> "$log_file"
    killall pppd
    sleep 20
    /usr/sbin/pppd call gsm
    sleep 120
    # Then we check again if restarting wlan0 fixed the issue;
    # if not we reboot as last resort
    ping -c1 google.com
    if [ $? -eq 0 ]
    then
        date >> "$log_file" && echo -e "-- Network is working correctly -- \n" >> "$log_file" && echo 0 > "$network_check_tries_file"
    else
        date >> "$log_file" && echo -e  "-- Network still down after ifdownup... reboot time!-- \n" >> "$log_file" && echo 0 > "$network_check_tries_file" && echo "$(($N_reboots + 1))" > "$N_reboots_file" && reboot
    fi
fi
user3036425
fonte
(1) Por que você ainda fala ifupdownse não os usa? (2) Por que você mudou gateway_ipde uma variável para uma constante codificada?
Scott
oi scott, esqueci de excluir os comentários ifup ifdown. Esqueci de mudar o gatewy_ip codificado.
usar o seguinte comando
Agradável! Adicionei uma nova versão que não está usando arquivos temporários (escrever no SD do Raspberry não era uma ótima idéia), você pode conferir na minha resposta.
Pitto 26/01
Este script herda alguns problemas que estavam na versão original do script de Pitto (que foram corrigidos posteriormente): (1) Se a rede estiver inoperante a partir das 00:00:01 (um segundo após a meia-noite), o script não será reaja até 00:35 (ou seja, 35 minutos depois, na sétima verificação), porque, mesmo que aumente o valor no network_check_tries_filearquivo (quando pingfalhar), não incrementa a network_check_triesvariável. ... (continua)
Scott
(Continua) ... Portanto, o script é executado sete vezes (às 00:05, 00:10, 00:15, 00:20, 00:25, 00:30 e 00:35) com network_check_triesigual a 0, 1, 2, 3, 4, 5 e 6 - e é apenas na sétima invocação (com network_check_triesigual a 6) que o if [ "$network_check_tries" -gt 5 ]teste é bem-sucedido. Indiscutivelmente, esse é o comportamento correto. Tanto quanto o script sabe, a rede pode ter caído às 00:04:59, portanto, são necessárias sete falhas consecutivas para garantir que você tenha coberto um período de 30 minutos. ... (continua)
Scott