Arrêter/Redémarrer un serveur Linux sans intervention avec Rtcwake
Je suis un p’tit flemmard… Entendre par là que l’heure du dodo venue, je n’ai pas envie de traverser l’appartement pour éteindre mon serveur (il fait nuit, tout le monde dort et personne n’a pas besoin d’y accéder). Sur l’année, cela ne va pas me faire économiser des kWs, c’est sur, mais c’est toujours ça d’économisé.
J’ai donc développé un petit script qui utilise rtcwake (consulter le man rtcwake). Celui-ci est lancé régulièrement (dès lors que je suis dans une plage horaire d’extinction) par un crontab afin d’identifier si le serveur est le dernier équipement éveillé et qui reconfigure le serveur pour démarrer tout seul à l’heure indiquée.
Prérequis
Avant de partir tête baissée, il y a deux choses à faire:
- Avoir un bios compatible avec l’option RTC
- Récupérer rtcwake si vous ne l’avez pas déjà
Rtcwake
Rtcwake ne peut être utilisé qu’en mode root (ou alors il faut donner gérer les droits différemment).
Rtcwake propose plusieurs modes:
- standby – permet de redémarrer rapidement. C’est un mode de veille qui offre peu de réduction énergétique.
- mem – met les données en RAM. Cela permet un redémarrage rapide tout en diminuant la consommation car seul la RAM restera alimentée.
- disk – Les données sont inscrites sur le disque dur et elles seront restaurées lors de la remise sous tension. L’alimentation électrique est coupée.
- off – Stop l’ordinateur (équivalent du bouton arrêt).
- no – Permet simplement de définir l’heure de réveil sans forcer un arrêt.
Pour mon installation, seul l’option disk est pleinement fonctionnelle.
D’autres part, la gestion de l’horloge materielle peut être un peu délicate (jeter un coup d’œil au man hwclock pour avoir plus d’infos). Pour notre cas, nous utiliserons l’option –auto, mais suivant votre configuration (et vos besoins) les options –local ou –utc pourront être utilisées suivant les cas où l’horloge matérielle est en horaire local ou UTC.
Le script
J’ai créé le script stopsrv.sh, que je place dans /usr/sbin avec les droits d’écriture (vous pouvez le placer où vous le souhaitez, pensez à changer l’adresse dans le fichier crontab).
#!/bin/bash
#--------------------------------------------------------
#items de configuration
#--------------------------------------------------------
#Liste les IPs qui sont sous surveillance du serveur
ips="192.168.0.3 192.168.0.2 192.168.0.5"
#heure de réveil
wakeTime="07:45"
#Copyright fly-out.net - V. Detroyat (6/11/2015)
# admin@fly-out.net
#Ce logiciel est un programme informatique servant à éteindre et redémarrer
#un serveur Linux lorsque celui-ci est le dernier ordinateur actif de la liste indiquée.
#Ce logiciel est régi par la licence CeCILL soumise au droit français et
#respectant les principes de diffusion des logiciels libres. Vous pouvez
#utiliser, modifier et/ou redistribuer ce programme sous les conditions
#de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
#sur le site "http://www.cecill.info".
#En contrepartie de l'accessibilité au code source et des droits de copie,
#de modification et de redistribution accordés par cette licence, il n'est
#offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
#seule une responsabilité restreinte pèse sur l'auteur du programme, le
#titulaire des droits patrimoniaux et les concédants successifs.
#A cet égard l'attention de l'utilisateur est attirée sur les risques
#associés au chargement, à l'utilisation, à la modification et/ou au
#développement et à la reproduction du logiciel par l'utilisateur étant
#donné sa spécificité de logiciel libre, qui peut le rendre complexe à
#manipuler et qui le réserve donc à des développeurs et des professionnels
#avertis possédant des connaissances informatiques approfondies. Les
#utilisateurs sont donc invités à charger et tester l'adéquation du
#logiciel à leurs besoins dans des conditions permettant d'assurer la
#sécurité de leurs systèmes et ou de leurs données et, plus généralement,
#à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
#Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
#pris connaissance de la licence CeCILL, et que vous en avez accepté les
#termes.
#--------------------------------------------------------
#Variables
#--------------------------------------------------------
#variable d'état. Initialisée pour que le serveur stop
etat="stopnow"
#Pour logger
echo "Activation Script:" >> /var/log/srvstop.log
date >> /var/log/srvstop.log
#exécution du ping sur les adresses IP afin de savoir si un élément est encore actif
for i in $ips
do
ping -c 1 $i > /dev/null
#si une adresse répond, alors on ne stoppe pas le serveur
if [ $? -eq 0 ] ; then
etat="nostop"
# ping -c 1 $i >> /var/log/srvstop.log
fi
done
#si l'état indique que le serveur doit stopper (="stopnow")
if [ "$etat" = "stopnow" ]; then
#suivant l'heure actuelle et l'heure de reveil on adapte la commande rtcwake
#au jour même ou au lendemain
echo "Server Shall Stop" >> /var/log/srvstop.log
date >> /var/log/srvstop.log
heure=$(date --date "now" +%s)
#jour=$(date --date "now" +%D)
datereveil=$(date --date "today $wakeTime" +%s)
#Heure du réveil déja passée, on met le réveil au lendemain
if [ $heure -ge $datereveil ]; then
timer=$(date --date "tomorrow $wakeTime" +%s)
echo "Reveil demain : " >> /var/log/srvstop.log
echo heure actuelle: $heure >> /var/log/srvstop.log
echo heure reveil: $timer >> /var/log/srvstop.log
else
# fi
#Heure de reveil non encore passée, on garde le reveil pour aujourd'hui
# if [ "$heure" -lt $datereveil ]; then
timer=$(date --date "today $wakeTime" +%s)
echo "reveil tout à l'heure" >> /var/log/srvstop.log
echo heure actuelle: $heure >> /var/log/srvstop.log
echo heure reveil: $timer >> /var/log/srvstop.log
fi
echo "Heure actuelle: " >> /var/log/srvstop.log
date >> /var/log/srvstop.log
rtcwake -a -m disk -t $timer >> /var/log/srvstop.log
fi
L’ajout au crontab
On ajoute les commandes au crontab.
Je n’ai pas identifié de solution permettant de faire ceci en une seule ligne. Le passage de minuit pose soucis.
*/10 20-23 * * * root /usr/sbin/stopsrv.sh >> /dev/null
*/10 00-05 * * * root /usr/sbin/stopsrv.sh >> /dev/null
Tel que le contrab est configuré:
- Si aucune adresse ip indiquée dans le script est trouvée à 20h, le serveur va s’éteindre de lui-même pour se relancer le lendemain.
- Tant qu’une adresse IP est trouvée, on refait un essai toutes les 10min et ce jusqu’à 5h du matin.
PS: Soyez malin, éviter de mettre une heure de réveil (wakeTime dans le script) qui est dans la plage d’extinction du fichier crontab.