Hardwarový watchdog v GNU/Linux na embedded zařízení

watchdog

Watchdog, doslovně přeloženo hlídací pes, je součást elektronických zařízení, která umožňuje detekovat poruchy a následně provést obnovení činnosti. Ve většině případů provede vypnutí nebo restart zařízení. Tím pádem je příslušné zařízení neustále v provozu bez nutnosti zásahu člověka. Pro zjednodušení si tento systém můžeme přirovnat ke strojvedoucímu, který musí v určitých intervalech mačkat tzv. tlačítko bdělosti. Pokud jej nestiskne, ozve se na konci probíhajícího intervalu zvukový signál. Jestliže strojvedoucí opět nereaguje, watchdog provede automatické zastavení vlaku. Obdobně může být watchdog využit např. ve vesmírných sondách, kde při výpadku modulu nebo zacyklení programu provede restart a obnovení činnosti. Aby se zabránilo problémům s tímto systémem samotným, musí být co nejjednodušší. Ve většině případů je řešen na úrovni hardware, a to čipové sadě nebo přímo v procesoru/mikrokontroléru.

Jak bylo uvedeno v příkladu s pravidelným mačkáním tlačítka bdělosti strojvedoucím, watchdog je časovač, který v předem nastavených intervalech provádí kontrolu zařízení. Velmi často je tedy označován jako watchdog timer. Místo strojvedoucího se zpravidla využívá programového kódu, který pravidelně, před uplynutím zmiňovaného intervalu, posílá watchdogu informaci o své funkčnosti (tlačítko bdělosti).

Pokud chceme využít watchdog pro naše projekty, musí být součástí hardware, případně můžeme použít softwarový, který však nebude funkční v případě kompletního zastavení systému.

V každém případě musíme watchdog aktivovat, nastavit příslušný interval a chování, a nastartovat obslužný program (programový uživatelský kód), který bude s watchdogem pravidelně komunikovat. Četnost této komunikace musí být vyšší, nežli nastavený interval watchdogu.

Následující postup se bude týkat zprovoznění v systému GNU/Linux (Arch Linux) na embedded platformách Raspberry Pi a Alix 3D3. Při konfiguraci jaderných modulů jsou patrné rozdíly na obou deskách.

Cíl

Cílem je automatické provedení restartu v případě selhání operačního systému a překročení nastavených limitů využití operační paměti nebo vysoké zátěže.

Nastavení jaderného modulu

Jak bylo uvedeno, pokud chceme využít hardwarový watchdog v GNU/Linux, musí být přítomen příslušný jaderný modul, který slouží pro jeho ovládání.

Pokud naše distribuce tento modul neobsahuje a lze jej nalézt ve stromě zdrojových kódů jádra, např. https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/watchdog, můžeme si jej zkompilovat.

Informace o API a využití vývojáři nalezneme na adrese https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/watchdog.

Pro každý typ hardware se používá jiný jaderný modul. Pokud máme štěstí, je při startu našeho systému automaticky zaveden.

[root@raspberry_pi ~]# dmesg | grep -i watchdog
[   1.508385] bcm2708 watchdog, heartbeat=10 sec (nowayout=0)

V opačném případě je nutné nalézt název správného modulu a nastavit jeho zavádění. Zde nám pomůže internet. Je ale také pravděpodobné, že náš systém hardwarový watchdog nemá, nebo nejsou dostupné jaderné moduly. Je-li to náš případ, použijeme watchdog softwarový, přidáme další hardware, který watchdog emuluje, anebo využijeme jiných možností, viz Závěr.

Pro Alix 3D3 i Rasberry Pi jsou však tyto moduly dostupné. Pro Alix se jmenuje geodewdt, pro Raspberry Pi 1 model B je to bcm2708_wdog.

Různé moduly mohou mít také různé parametry, které je možné zadat při jejich zavádění. Pro jejich zobrazení použíjeme příkaz modinfo.

[root@alix ~]# modinfo geodewdt
filename:       /lib/modules/4.0.4-2-ARCH/kernel/drivers/watchdog/geodewdt.ko.gz
license:        GPL
description:    Geode GX/LX Watchdog Driver
author:         Advanced Micro Devices, Inc
depends:        cs5535-mfgpt
intree:         Y
vermagic:       4.0.4-2-ARCH SMP preempt mod_unload modversions 686
parm:           timeout:Watchdog timeout in seconds. 1<= timeout <=131, default=60. (int)
parm:           nowayout:Watchdog cannot be stopped once started (default=0) (bool)
[root@raspberry_pi ~]# modinfo bcm2708_wdog
filename:       /lib/modules/4.1.6-3-ARCH/kernel/drivers/watchdog/bcm2708_wdog.ko.gz
license:        GPL
alias:          char-major-10-131
alias:          char-major-10-130
description:    Driver for BCM2708 watchdog
author:         Luke Diamand
srcversion:     5EECED7AD08838EF004B7E9
depends:
intree:         Y
vermagic:       4.1.6-3-ARCH preempt mod_unload modversions ARMv6
parm:           heartbeat:Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default=10) (int)
parm:           nowayout:Watchdog cannot be stopped once started (default=0) (int)

Všimněme si zejména parametrů timeout/heartbeat. Oba znamenají to samé – již zmíněný interval, během kterého čeká watchdog na „stisk tlačítka bdělosti“. Každý má přednastaven jinou hodnotu. Tuto hodnotu však můžeme přenastavit, a přenastavíme na 15 sekund. Parametr nowayout můžeme nechat na 0. Informuje modul o tom, že je možné jej zastavit, pokud běží.

[root@alix ~]# cat /etc/modprobe.d/watchdog.conf
options geodewdt nowayout=0 timeout=15
[root@raspberry_pi ~]# cat /etc/modprobe.d/watchdog.conf
options bcm2708_wdog nowayout=0 heartbeat=15

Následně nastavíme automatické zavedení modulů při startu:

[root@alix ~]# cat /etc/modules-load.d/watchdog.conf
geodewdt
[root@raspberry_pi ~]# cat /etc/modules-load.d/watchdog.conf
bcm2708_wdog

Na Alix 3D3 potřebujeme instruovat linuxové jádro, že využíváme tuto platformu. pokud jsme to ještě neudělali, přidáme do souboru /etc/default/grub:

GRUB_CMDLINE_LINUX="acpi_enforce_resources=no alix.force=1"

Následně vytvoříme novou konfiguraci pro Grub (pokud je to nutné):

[root@alix ~]# grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found Intel Microcode image
Found linux image: /boot/vmlinuz-linux
Found initrd image: /boot/initramfs-linux.img
Found fallback initramfs image: /boot/initramfs-linux-fallback.img
done

Poznámka: V mém systému Arch Linux na Alixu 3D3 je poslední funkční verze jádra 4.0.4-2. Vyšší (zkoušel jsem max. 4.0.6) bohužel nebootuje.

Instalace a konfigurace uživatelské služby

Instalace a konfigurace služby v uživatelském prostoru je hardwarově nezávislá.
Nejdříve nainstalujeme balíček watchdog:

[root@linux ~]# pacman -S watchdog
resolving dependencies...
looking for conflicting packages...

Packages (1) watchdog-5.14-1

Total Installed Size:  0.14 MiB

:: Proceed with installation? [Y/n]
(1/1) checking keys in keyring                     [###################] 100%
(1/1) checking package integrity                   [###################] 100%
(1/1) loading package files                        [###################] 100%
(1/1) checking for file conflicts                  [###################] 100%
(1/1) checking available disk space                [###################] 100%
(1/1) installing watchdog                          [###################] 100%

Nastavíme nově nainstalovanou službu. Tato operace se provádí v souboru /etc/watchdog.conf:

#ping                   = 172.31.14.1
#ping                   = 172.26.1.255
#interface              = eth0
#file                   = /var/log/messages
#change                 = 1407

# Uncomment to enable test. Setting one of these values to '0' disables it.
# These values will hopefully never reboot your machine during normal use
# (if your machine is really hung, the loadavg will go much higher than 25)
max-load-1              = 24
max-load-5              = 18
max-load-15             = 12

# Note that this is the number of pages!
# To get the real size, check how large the pagesize is on your machine.
min-memory              = 1

#repair-binary          = /usr/sbin/repair
#repair-timeout         =
#test-binary            =
#test-timeout           =

watchdog-device = /dev/watchdog

# Defaults compiled into the binary
#temperature-device     =
#max-temperature        = 120

# Defaults compiled into the binary
#admin                  = root
interval                = 1
#logtick                = 1
#log-dir                = /var/log/watchdog

# This greatly decreases the chance that watchdog won't be scheduled before
# your machine is really loaded
realtime                = yes
priority                = 1

# Check if rsyslogd is still running by enabling the following line
#pidfile                = /var/run/rsyslogd.pid

watchdog-timeout        = 15

Naším cílem je automatický restart v případě selhání systému a překročení nastavených limitů využití operační paměti nebo vysoké zátěže.

  1. selhání systému: odkomentujeme řádek identifikující přístup k hardwarovému zařízení watchdog-device = /dev/watchdog, nastavíme interval notifikace watchdogu službou (musí být vždy menší hodnota než interval nastavený jaderným modulem) interval = 1, nastavíme interval watchdogu (stejná hodnota jako v případě modulu jádra) watchdog-timeout = 15.
  2. limit využití operační paměti: nastavíme parametr min-memory – viz manuálová stránka man watchdog.conf.
  3. limit zátěže systému: Nastavíme max-load-1, max-load-5max-load-15.

Start služby

Nyní můžeme službu povolit a případně nastartovat:

[root@linux ~]# systemctl enable watchdog
Created symlink from /etc/systemd/system/multi-user.target.wants/watchdog.service to /usr/lib/systemd/system/watchdog.service.

[root@linux ~]# systemctl start watchdog

Pokud mám zaveden příslušný jaderný modul, měli bychom vidět otevřené zařízení /dev/watchdog příkazem watchdog:

[root@linux ~]# lsof /dev/watchdog
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
watchdog 1588 root    1w   CHR 10,130      0t0 6800 /dev/watchdog

Test

Nejjednodušším testem je „zabití“ služby watchdog:

[root@linux ~]# pkill -9 watchdog

Po vypršení intervalu nastaveného jaderným modulem by mělo dojít k restartu systému. Avšak pozor, nedojde k odpojení připojených disků ani k uložení dat v paměti!

Mazáci mohou použít sofistikovanější příkaz, který zahltí paměť a vytíží systém:

[root@linux ~]# : (){ :|:& };:

Korektní testovací skripty jsou součástí zdrojových kódů jádra na adrese https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/watchdog.

Závěr

Při použití watchdogu si musíme uvědomit, že v případě restartu zařízení s disky připojenými v režimu pro zápis, může dojít k nekonzistenci dat nebo dokonce jejich ztrátě.

Pokud bychom chtěli restart iniciovaný jádrem v případě události Kernel Panic, nastavíme:

[root@linux ~]# cat /etc/sysctl.d/panic.conf
kernel.panic_on_oops = 1
kernel.panic = 1

Leave a Reply