Существует интересный механизм — watchdog. Позволяет отслеживать работоспособность системы, а в случае сбоя — произвести перезагрузку.
С помощью программной эмуляции ядром можно вызвать перезагрузку если таймер не будет сброшен в течение определённого времени.
При наличии аппаратной поддержки добавляется возможность мониторинга даже самого ядра (например загрузка системы идёт слишком долго, kernel panic или задержки при перезагрузке).
Мне в руки попался древний сервер HP Proliant ML150 G3 с аппаратным watchdog на борту. Поэтому эксперименты будут проводиться в полном объёме.
Наиболее подходящим вариантом инструментом является sys-apps/ipmiutil
Посмотреть состояние аппаратного watchdog можно следующей командой:
ipmiutil wdt -c
Для systemd поставляются штатные файлы service, которые запускают обычные скрипты инициализации, которые используют cron, создавая и удаляя для него файлы. В общем то ещё порно. Сделаем всё native systemd, раз уж в нём напилили кучу плюшек.
Итак, watchdog для монитора загрузки ОС нуждается в сервисе, который банально отключит обратный отчёт и погаснет:
#/etc/systemd/system/ipmiutil_wdt-os.service
[Unit]
Description=ipmiutil Watchdog Timer Service for OS Boot
Conflicts=ipmiutil_wdt-rt.serviceAfter=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/ipmiutil wdt -d
[Install]
WantedBy=multi-user.target
Для мониторинга работы системы надо периодически сбрасывать счётчик. Итак для запуска сервиса и настройки счётчика на 180 секунд для мягкой перезагрузки и 300 секунд для жёсткой перезагрузки (например, в случае kernel panic):
#/etc/systemd/system/ipmiutil_wdt-rt.service
[Unit]
Description=ipmiutil Watchdog Timer Service for runtime
Conflicts=ipmiutil_wdt-os.service
Requires=ipmiutil_wdt-timer.service ipmiutil_wdt-timer.timer
Before=ipmiutil_wdt-timer.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/ipmiutil wdt -e -p 3 -q 180 -a 1 -t 300
ExecStop=/usr/bin/ipmiutil wdt -d
[Install]
WantedBy=multi-user.target
Для сброса счётчика делаем следующий сервис:
#/etc/systemd/system/ipmiutil_wdt-timer.service
[Unit]
Description=ipmiutil Watchdog Timer Service for runtime timer
[Service]
Type=oneshot
ExecStart=/usr/bin/ipmiutil wdt -r >> /dev/null 2>&1
[Install]
WantedBy=multi-user.target
Ну и для того, чтобы обнуление проходило по таймеру воспользуемся штатным механизмом systemd:
#/etc/systemd/system/ipmiutil_wdt-timer.timer
[Unit]
Description=ipmiutil Watchdog Timer Service for runtime timer
[Timer]
OnUnitActiveSec=60
[Install]
WantedBy=timers.target
Для запуска достаточно набрать: systemctl start ipmiutil_wdt-rt && systemctl enable ipmiutil_wdt-rt
Далее на работу таймера можно посмотреть командой systemctl list-timers
Рыская по интернету так же нашёл ещё один метод собрать watchdog на Python:
#!/usr/bin/python2.7
from time import sleep
from watchdogdev import *
wd = watchdog('/dev/watchdog')
try:
while True:
print "Send Keep alive"
wd.keep_alive()
for j in range(10): #Chage to 15 to see RPi reboot ...
print "... Waiting ",j,", Left :",wd.get_time_left()
sleep(1)
except KeyboardInterrupt:
print
print "Magic Close"
wd.magic_close()
print "Done !"
https://www.freedesktop.org/software/systemd/man/systemd.unit.html https://www.freedesktop.org/software/systemd/man/systemd.service.html https://www.freedesktop.org/software/systemd/man/systemd.timer.html https://wiki.archlinux.org/index.php/Systemd/Timers http://ipmiutil.sourceforge.net/ https://www.kernel.org/doc/Documentation/watchdog/watchdog-api.txt https://www.kernel.org/doc/Documentation/misc-devices/mei/mei.txt http://raspberrypi.werquin.com/post/44890705367/a-hardware-watchdog-to-monitor-a-deamon-running http://www.jann.cc/2013/02/02/linux_watchdog.html