Назад | Перейти на главную страницу

Задание безопасной перезагрузки cron с откатом на проблему сброса SysRq

Я пытаюсь настроить задание cron для ежедневной перезагрузки устройств. С безопасным обратным вызовом для сброса SysRq, если по какой-то причине перезагрузка зависает (проблема в том, что SSH отключен, а устройство никогда не перезагружается, поэтому оно потеряно и требует дорогостоящего вмешательства человека для перезапуска).

Скрипт, который некоторое время работал:

5 5 * * * root /sbin/reboot -f; sleep 30; /bin/echo `date -u +'\%Y-\%m-\%dT\%H:\%M:\%SZ'` >> /var/log/player-reboot.error.log; echo 1 > /proc/sys/kernel/sysrq; sync; echo b > /proc/sysrq-trigger

Однако это довольно жестоко (жесткая перезагрузка -f), и некоторые из наших устройств в последнее время не восстанавливаются (пара тысяч каждый день).

Не уверен, что зависает (похоже, что файл никогда не записывается, поэтому я бы сказал, что либо сама перезагрузка, либо эхо зависает?

Хотел использовать амперсанды и никогда не «блокировать» и быть уверенным, что в конечном итоге произойдет правильный сброс, однако он, похоже, вообще не работает (больше никаких перезагрузок):

5 5 * * * root /sbin/shutdown -r +2 &; sleep 240; /bin/echo `date -u +'\%Y-\%m-\%dT\%H:\%M:\%SZ'` >> /var/log/player-reboot.error.log &; echo 1 > /proc/sys/kernel/sysrq; sleep 1; echo b > /proc/sysrq-trigger

Могу ли я использовать амперсанд в скрипте cron? Знаете ли вы еще один более умный способ достичь желаемых результатов? Спасибо!

Более простой подход - запланировать другой процесс, чтобы проверить время безотказной работы более 24 часов (т. е. 25 часов). Если проверка вернула истину, очевидно, что с перезагрузкой что-то пошло не так, поэтому компьютер необходимо перезагрузить через SysRq.

Для максимальной надежности ваша периодическая проверка не должна зависеть от crond (который может быть убит повешением shutdown обработать). Скорее используйте схему опроса; что-то такое:

#!/bin/bash
max_uptime=$((25*3600)) #max 25h
sleep_time=3600 #1h sleeps
while true; do
    current_uptime=`grep -o "^[[:digit:]]\+" /proc/uptime`
    echo "current uptime: $current_uptime seconds"
    if [ $current_uptime -gt $max_uptime ]; then
        echo "reboot!"
        echo 1 > /proc/sys/kernel/sysrq; sync; echo b > /proc/sysrq-trigger
    else
        echo "not now!"
    fi
    echo "sleeping..."
    sleep $sleep_time
done

Вы можете сначала запустить приведенный выше сценарий с помощью @reboot crond вход, или с rc.local и друзья.