lalahop

OpenWRT : watchdog – en voilà un bon toutou !

Table des matières

Je vous propose un court billet afin de vous familiariser avec la notion de watchdog et à son utilisation sous OpenWRT. Les personnes connaissant ce concept peuvent zapper ce billet car elles n'apprendront rien de nouveau car je ne vais pas approfondir le sujet.

Définition

Je ne saurai pas mieux expliquer le concept de watchdog que Wikipédia : Chien de garde (informatique).

Implémentation sous OpenWRT

Le watchdog n'est disponible que dans la déclinaison brcm47xx de Backfire, pas dans la brcm-2.4. Peut-être est-il disponible sous les autres versions d'OpenWRT, Kamikaze brcm-2.4 par exemple, je ne les ai pas essayées. Je ne sais pas non plus s'il est disponible sur tous les routeurs mais dans le cas d'un WRT54GL v1.1, il l'est.

Sous OpenWRT, le watchdog est fourni par busybox et il se matérialise par un fichier /dev/watchdog et un démon. Par défaut, si rien n'a été écrit durant 60 secondes dans le fichier spécial /dev/watchdog, alors le routeur redémarre. C'est pour cela que le démon watchdog doit écrire dans ce fichier pour réinitialiser le compteur. Par défaut, il le fait toutes les 5 secondes. En temps normal, seul un blocage complet du système peut empêcher l'écriture dans le watchdog pendant 60 secondes.

Le watchdog permet donc d'accroitre la stabilité du système. Si vous utilisez votre routeur à distance et qu'une fausse manipulation (ex. : lancer 2 fois tcpdump) fige le système et qu'aucun watchdog n'est présent, vous ne pourrez pas réinitialiser le système ni vous en servir. Avec le watchdog, il vous suffit d'attendre que celui-ci agisse selon le timeout défini. La problématique est la même lorsqu'un logiciel fige le système (ex. sous OpenWRT : knockd peut parfois planter le système lors de son lancement).

Il n'y a pas de fonctions supplémentaires du genre redémarrage dans le cas où la charge système devient trop importante ou bien encore redémarrage dans le cas où un processus ne tourne plus comme c'est le cas sur d'autres systèmes : Watchdog sur Gentoo Wiki Archives.

Provoquer le chien

Si vous voulez tester le watchdog, plusieurs solutions s'offrent à vous selon votre niveau de sadisme (niark niark).

Tuer le démon

Lancez la commande :

killall watchdog

et attendez 60 secondes 🙂 .

Source : Watchdog - ArmadeusWiki

Utilisez une fork bomb

Pour ceux qui ne connaissent pas le principe : Fork bomb - Wikipédia FR.

Lancez la commande

bomb() {
 bomb | bomb &
}; bomb

et attendez une minute 🙂

Source : Understanding Bash fork() bomb ~ :(){ :|:& };: - NixCraft

Écrire un code dans le watchdog

On trouve également des sites qui nous disent qu'on peut écrire des données dans le watchdog avec echo. Exemples :

Ces commandes ne fonctionnent pas. Si vous ne tuez pas le démon watchdog, vous obtiendrez une erreur "-ash: can't create /dev/watchdog: Device or resource busy" qui est tout à fait normale. Si vous tuez le démon et que vous lancez une des commandes sus-citées, vous n'obtiendrez aucun résultat. En tout cas, c'est ce que j'ai observé.

Désactiver le watchdog

Il suffit de lancer les commandes suivantes :

/etc/init.d/watchdog disable
reboot

Et si vous voulez le réactiver un jour, ce seront les commandes :

/etc/init.d/watchdog enable
reboot

Régler plus finement le watchdog

Comme nous l'avons déjà dit, le démon watchdog est minimaliste. Il suffit de lancer le démon sans argument pour se rendre compte du peu d'options disponibles :

Options:
        -T N    Reboot after N seconds if not reset (default 60)
        -t N    Reset every N seconds (default 30)
        -F      Run in foreground

Régler le timing

Par défaut, le démon réinitialise le watchdog toutes les 5 secondes et si il n'a pas été réinitialisé durant 60 secondes, le système redémarre.

Vous pouvez néanmoins changer le timing. À titre d'exemple, la commande suivante permet de réinitialiser le watchdog toutes les 2 secondes et de redémarrer le routeur si le watchdog n'a pas été réinitialisé au bout de 30 secondes :

watchdog -T 30 -t 2

Pour appliquer ce changement, cela se passe dans le fichier /etc/init.d/watchdog . Il suffit de remplacer la 7e ligne ("watchdog -t 5 /dev/watchdog") par la ligne que vous aurez décidée ("watchdog -T 30 -t 2" dans notre cas). Toujours dans notre cas, voici ce que cela donnerai (fichier /etc/init.d/watchdog) :

#!/bin/sh /etc/rc.common
# Copyright (C) 2008 OpenWrt.org
 
START=97

start() {
        [ -c /dev/watchdog ] && [ -x /sbin/watchdog ] && \
                watchdog -T 30 -t 2
}

Personnellement, je recommande de ne pas modifier les valeurs par défaut ou alors de bien les tester tant que vous avez un accès local. Cela dépend bien évidemment des usages. Vous vous demandez peut-être ce qui peut bien arriver. Voici deux exemples :

  • Mettre une valeur de réinitialisation trop haute par rapport à la valeur de redémarrage (ex. : reset = 15 et reboot = 30) car dans ce cas, un plantage temporaire provoquera le redémarrage du système. Dans mon exemple, vous conviendrez qu'il n'y a qu'un ou deux essai(s) possible(s) avant un redémarrage. Il suffit que le routeur soit débordé alors que l’écriture devait être effectuée et c'est le drame alors que si ça se trouve, le système était occupé à charger un programme gourmand et que cela aurait pris 15 secondes maximum ...
  • Mettre une valeur de redémarrage trop faible peut entrainer une boucle infinie. Supposons un logiciel qui démarre durant le processus de boot et peut parfois mettre plus de temps à démarrer (qui a dit knockd ?) sans pour autant faire planter le système durablement. Si le watchdog est trop sensible, le système redémarrera. Le chargement sera a nouveau effectué et n'aura pas le temps de se faire et on repart donc pour un redémarrage, etc. .

Avoir des fonctionnalités avancées

Si vous avez besoin de fonctions plus avancées (ex. : redémarrer en fonction de la charge ou redémarrer un processus si celui-ci n'est plus en cours d’exécution), vous pouvez les implémenter à travers des scripts. Quelques exemples (à vous de leur chercher un intérêt dans votre situation et de vérifier si le script est optimisé pour la version stable actuelle d'OpenWRT) :

Conclusion - mais que fait donc la variable nvram watchdog ?

Pour les plus attentifs, une variable watchdog (de valeur 5000 par défaut) existe dans la nvram du WRT54GL :

nvram show | grep watchdog
watchdog=5000

Je ne sais pas à quoi elle correspond et Google n'est pas bavard sur le sujet.

J'ai tenté de la descendre à 1000 (nvram set watchdog=1000 && nvram commit && reboot) en croyant qu'elle indique un temps en millisecondes puis j'ai lancé une fork bomb en ayant pris le soin de désactiver le démon watchdog avant. Résultat : il ne s'est rien passé.

J'ai tenté de passer la valeur de cette variable à 10 en me disant qu'elle représente un temps en secondes, sans trop y croire. Après avoir renouvelé l’expérience que je viens de décrire, je ne suis pas plus avancé.

Ma dernière hypothèse est qu'elle concerne le démarrage du système. Si les premières couches qui se chargent au boot plantent, il faut bien relancer le système. Je ne suis pas en mesure de tester cette hypothèse.

Si quelqu'un a une information sur ce sujet, qu'il n'hésite pas 🙂 .