Сторожевой таймер для 4G модема в CentOS 7

от автора

Эта статья является дополнением моей предыдущий статьи о настройке домашнего роутера / файл-сервера. Здесь речь пойдет об проблеме автоматического переподключения к интернету при зависании 4G USB модема. На оригинальность идеи не претендую, просто хочу поделиться с читателями своим решением данной проблемы.


В процессе постоянной работы, примерно раз в месяц, случалось так, что USB модем зависал. Это доставляло мне определенные неудобства: невозможность удаленно попасть на домашний компьютер, заранее поставить на закачку фильмы. Удаленно эту проблему решить было невозможно, помогала только перезагрузка модема по питанию. Решение было единственным написать сценарий, который в определенное время проверяет доступность узла в интернете и при возникновении проблемы перезагружает модем.

В интернете я нашел несколько решений, но не одно из них у меня нормально не заработало. Поэтому я решил написать свой сторожевой таймер с преферансом и барышнями. За основу был взят скрипт из этой темы. Переписан, насколько мне позволяет моя квалификация, и дополнен новыми возможностями такими как внешние опции.

Установка и настройка USB 4G модема в CentOS 7.

Для начала необходимо скачать недостающие пакеты.

yum install usb_modeswitch usb_modeswitch-data 

Подключить модем и посмотреть как он определяется в системе.

dmesg ip a 

Далее необходимо настроить интерфейс 4G модема.

vim /etc/sysconfig/network-scripts/ifcfg-wwp6s0u1i1 

DEVICE="wwp6s0u1i1" NAME="wwp6s0u1i1" TYPE="Ethernet" ONBOOT="yes" BOOTPROTO="dhcp" HWADDR="XX:XX:XX:XX:XX:XX" NM_CONTROLLED="no" DNS1=127.0.0.1 DNS2=127.0.0.1 DNS3=127.0.0.1 NOZEROCONF="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="no" ZONE="external" 

Создаем скрипты для активации и де активации интернета при включении или отключении интерфейса.

vim /sbin/ifup-pre-local 

#!/bin/bash # PREUP="/etc/sysconfig/network-scripts/pre-up-${1:6}" if [ -x $PREUP ]; then exec $PREUP fi 

vim /sbin/ifdown-pre-local 

#!/bin/bash # PREDOWN="/etc/sysconfig/network-scripts/pre-down-$1" if [ -x $PREDOWN ]; then exec $PREDOWN fi 

vim /etc/sysconfig/network-scripts/pre-up-wwp6s0u1i1 

#!/bin/bash # echo -en 'AT^NDISDUP=1,1,"internet.yota"\r\n' > /dev/ttyUSB0 

vim /etc/sysconfig/network-scripts/pre-down-wwp6s0u1i1 

#!/bin/bash # echo -en 'AT^NDISDUP=1,0,"internet.yota"\r\n' > /dev/ttyUSB0 

Здесь ttyUSB0 это порт модема.

Поднимаем интерфейс и проверяем соединение.

ifup wwp6s0u1i1 ip a 

Непосредственно сам скрипт

#!/bin/bash  SN="$(basename "$0")"  function print_help() {     printf "\n"     printf "Использование: %s options...\n" "$SN"     printf "Параметры:\n"     printf "  -s         Проверяемый ресурс.\n"     printf "  -i         Имя сетевого интерфейса.\n"     printf "  -d         Шина и порт модема lsusb -t.\n"     printf "  -n         Число ошибочных пингов.\n"     printf "  -m         Маркер модема, из команды lsusb.\n"     printf "  -h         Справка.\n"     printf "\n" }  # Если скрипт запущен без аргументов, открываем справку. if [[ $# = 0 ]]; then     print_help && exit 1 fi while getopts ":s:i:d:n:m:h" opt ; do     case $opt in         s) SITE=$OPTARG;             ;;         i) IF=$OPTARG;             ;;         d) DEV=$OPTARG;             ;;         n) EP=$OPTARG;             ;;         m) MM=$OPTARG;             ;;         h) print_help             exit 1             ;;         *) printf "Неправильный параметр\n";            printf "Для вызова справки запустите %s -h\n" "$SN";             exit 1             ;;         esac done  if [[ "$SITE" == "" ]] || [[ "$IF" == "" ]] || [[ "$DEV" == "" ]] || [[ "$EP" == "" ]] || [[ "$MM" == "" ]] ;  then  printf "\n"  printf "Одна или несколько опций не указаны.\n"  printf "Для справки наберите: %s -h\n" "$SN"  printf "\n"  exit 1 fi  M="$(lsusb | grep -w "$MM")"  #строка модема из lsusb   if [[ "$M" != "" ]]; then   #если модем выбран, можно проверять пинги    if grep -w -q "$IF" /proc/net/dev; then #проверяем наличие сетевого интерфейса    printf "\n"    printf "Проверка доступности %s через интерфейс %s\n" "$SITE" "$IF"    printf "\n"     if [[ "$EP" -ge 6 ]]; then      printf "Число ошибочных пингов должно быть меньше или равно 5\n"      exit 1     else      printf "Делаем пинги...\n"      flag="0"      for i in {1..5}; do #делаем 5 пингов до сервера      timeout -k 2 -s TERM 16 ping -w 14 -s 8 -c 1 -I "$IF" "$SITE" || flag=$((flag+1)) && printf "пинг:%s/5 (ошибок:%s)\n" "$i" "$flag" #пинг не прошел - инкрементируем счетчик       if (("$flag" >= "$EP")); then        break       else        read -r -t 1 > /dev/null       fi      done      printf "потерь пакетов: %s из %s\n" "$flag" "$i"      printf "\n"       if (("$flag" >= "$EP")); then #если потерь пакетов больше 2х       M="$(lsusb | grep "$MM")"   #на всякий случай снова глянем - вдруг модем выдернули       printf "Будет сброшен модем:\n"       printf "%s\n" "$M" | cut -c 34-       if ! [[ -d /sys/bus/usb/drivers/usb/"$DEV" ]]; then        printf "Неверно указаны Bus и Port модема.\n"        exit 1       else       ifdown "$IF" #деактивируем интерфейс       printf "%s" "$DEV" > "/sys/bus/usb/drivers/usb/unbind" && printf "%s" "$DEV" > "/sys/bus/usb/drivers/usb/bind" #перезегрузка модема #      read -r -t 1 > /dev/null       ifup "$IF" #активируем интерфейс       fi      fi     fi   else    printf "\n"    printf "Интерфейс %s не существует\n" "$IF"    printf "\n"    exit 1   fi else   printf "Модем %s не найден.\n" "$MM" fi 

Скрипт располагается в /usr/local/bin/.
Чтобы скрипт запускался автоматически, раз в пять минут, добавим задание в cron.

crontab -e 

*/5 * * * * /usr/local/bin/watchdog -m Huawei -s ya.ru -i wwp6s0u2i1 -n 3 -d 1-1 > /dev/null 2>&1 

Это вывод dmesg, на нем виден сброс модема при выполнении скрипта.

[181709.595498] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0 [181709.595568] option 1-1:1.0: device disconnected [181709.595798] huawei_cdc_ncm 1-1:1.1 wwp6s0u2i1: unregister 'huawei_cdc_ncm' usb-0000:06:00.0-1, Huawei CDC NCM device [181709.615005] option 1-1:1.0: GSM modem (1-port) converter detected [181709.616597] usb 1-1: GSM modem (1-port) converter now attached to ttyUSB0 [181709.623449] usb 1-1: MAC-Address: 0c:5b:8f:27:9a:64 [181709.623958] huawei_cdc_ncm 1-1:1.1: cdc-wdm0: USB WDM device [181709.624341] huawei_cdc_ncm 1-1:1.1 wwan0: register 'huawei_cdc_ncm' at usb-0000:06:00.0-1, Huawei CDC NCM device, 0c:5b:8f:27:9a:64 

Сразу скажу скрипт очень далек от идеала, поэтому с радостью приму советы и обоснованную критику в свой адрес.
Отдельно хочу поблагодарить пользователя с Toster.ru под ником @AlekseyNemiro, за оказанную помощь в оптимизации скрипта.

Будет ли Вам полезен данный скрипт?

Никто ещё не голосовал. Воздержавшихся нет.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

ссылка на оригинал статьи http://habrahabr.ru/post/275551/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *