Artisan Numérique

/système/matos/hibernation/ Hibernatus!!

Je rassure les hostiles, le clin d'oeil à Mr Potter s'arrêtera là :-) A l'origine j'avais écrit ce tutoriel pour le lifebook U810. Mais comme ce chapitre est devenu un véritable parcours du combattant, et comme j'avais aussi envie de bénéficier de l'hibernation sur mon ordinateur de bureau, je me suis dit qu'il ne serait sans doute pas trop crétin d'en faire un tutoriel à part entière. Alors pour mettre une sa Mandriva (ou tout autre GNU/Linux en adaptant le tutoriel) dans la glace, voilà la marche à suivre...

Introduction

Il y a trois types d'extinction disponibles sous Linux. L'extinction complète via la commande shutdown. L'hibernation qui fonctionne comme l'extinction complète mais qui va préalablement sauvegarder l'état de la mémoire et des périphériques et restaurer la mémoire après démarrage du kernel. Et enfin il y a la mise en veille qui consiste à tout éteindre sauf la mémoire et un boût du northbridge qui la rafraîchit.

D'un point de vue énergétique, le mode hibernation est le meilleur car la machine peut être physiquement éteinte. En mode mise en veille, la mémoire et le northbridge continuent de pomper du courant, ainsi que la carte mère elle-même. Une batterie de portable ne tiendra donc pas éternellement sur ce mode, contrairement à l'hibernation.

Pour gérer ces mises en sommeil, nous utilisons ... hibernate qui est n'est autre que le projet Tux On Ice. Contrairement à ce que son nom indique, la commande hibernate que ce paquet met à disposition, permet aussi bien d'effectuer une hibernation qu'une mise en veille en utilisant respectivement s2disk du paquet suspend et s2ram du paquet suspend-s2ram.

Techniquement s2disk et s2ram sont autonomes et seraient utilisables "tout crus". Mais hibernate enrobe le tout dans une série de scripts paramétrables permettant de gérer les différentes étapes préalables à l'extinction et à la finalisation du réveil, notamment l'épineux problèmes des modules qui ne savent pas sauvegarder leur état proprement.

Pour installer tout cela, il suffit de lancer un urpmi hibernate suspend suspend-s2ram et les commandes seront :

# hibernation
hibernate

# mise en veille
hibernate --config-file=/etc/hibernate/ram.conf

Comme vous le voyez, l'hibernation est le comportement par défaut. Pour une mise en veille, il faut fournir en plus un fichier de paramétrage spécifique.

Machine inconnue

Si vous faites un s2ram -n, il y a de forte chances que cela vous renvoie un Machine is unknown qui bloquera la suite du processus. Pour forcer malgré tout la mise en veille, il nous faut donc contourner cette protection en modifiant /etc/hibernate/ususpend-ram.conf pour décommenter la ligne USuspendRamForce yes.

Forcer la mise en veille n'est pas sans risque. L'option n'est pas là pour rien et vous pouvez éventuellement corrompre vos données. A vos risques et périls...

Des modules pas très green

La première raison qui empêche une mise en veille ou hibernation, ce donc sont les modules qui ne savent pas correctement causer "énergie" (ou alors le matériel sous-jacent). Ces modules sans espoir devront donc être déchargés avant extinction et recharger au réveil. Leur état interne sera donc perdu mais ce n'est généralement pas bien grave.

Pour trouver ces modules, je n'ai rien trouvé de mieux que de faire d'un côté tail -f /var/log/messages et de l'autre, de lancer hibernate --config-file=/etc/hibernate/ram.conf --verbosity=3 pour qu'il m'indique les problèmes rencontrés. Par exemple pour le lifebook U810, cela me donne :

...
Jul  8 09:52:40 horus kernel: aes2501 2-2:1.0: no suspend for driver aes2501?
Jul  8 09:52:40 horus kernel: uvcvideo 1-5:1.1: suspend error -22
...

Dés que l'on détecte un module fautif, nous devons le "blacklisté" en ajoutant son nom dans la liste /etc/hibernate/blacklisted-modules.

Si vous obtenez une erreur du genre :

Some modules failed to unload: nvidia
hibernate: Aborting suspend due to errors in ModulesUnloadBlacklist (use --force to override).

Il va falloir aussi forcer hibernate. Pour cela, modifiez /etc/hibernate/common.conf et décommentez AlwaysForce yes.

Relancez la mise en veille autant de fois qu'il est nécessaire en répétant ces opérations de blacklistages jusqu'à ce que la machine s'éteigne. Une fois que c'est fait, une simple pression sur le bouton d'allumage devrait la faire revenir à la vie.

Si elle ne revient pas la pauvrette, un coupable possible est APIC. C'est le cas de l'U810. Tentez donc de le désactiver en modifiant /boot/grub/menu.lst, pour ajouter à ma fin de la bonne ligne kernel, le paramètre noapic. Redémarrez et re-tentez l'expérience.

Si au retour de la mise en veille vous obtenez, et c'est le cas pour l'U810, un écran tout vilain, pas de panique. Pressez CAPS-LOCK pour vérifier que a diode de votre clavier s'allume et donc que la machine n'est pas plantée. Puis alternez les CTRL-ALT-F1 et CTRL-ALT-F7, l'affichage devrait revenir. Ensuite, allez dans /etc/hibernate/ususpend-ram.conf et décommentez la ligne USuspendRamVbeSave yes pour sauvegarder l'état vidéo avant mise en veille et le restaurer au réveil.

Sur l'U810, la mise en veille s'effectue en 8 s à l'allée et 6 s au retour. Sur ma machine de bureau c'est simplement instantané. Vu le gain d'énergie que cela représente, on aurait tord de s'en priver à chaque pause café...

Toujours concernant l'U810, le contrôleur vidéo semble avoir du mal à revenir de sa veille lorsque metacity est me mode composite (fenêtres ombrées et transparence). Pour régler cela, il faut ajouter dans /etc/hibernate/ram.conf le paramétre SwitchToTextModeOnResume yes.

Hibernation

A ce stade la mise en veille devrait fonctionner et du coup l'hibernation aussi. La seule chose à faire avant est de définir l'endroit "physique" où s2disk va sauver l'état de la machine. Le plus simple pour cela est d'utiliser la partition de SWAP qui ne servira pas à grand chose une fois la machine éteinte. Normalement vous devez avoir une partition de swap au moins égale à la taille de votre mémoire. Cependant s2disk a le bon gout de compresser sa sauvegarde, permettant ainsi de dépasser quelque peu cette limitation.

Pour connaître la partition utilisée pour le swap sur votre machine, il suffit d'utiliser swapon :

rootswapon -s
Filename        Type    Size  Used  Priority
/dev/sda5                               partition  4088500  0  -1

Ensuite, éditez le fichier /etc/suspend.conf, le fichier de paramétrage de s2disk, et remplacez la valeur de resume device par ce que swapon -s vous a donné comme partition.

Ceci fait, vous devez aussi indiquer au kernel où trouver ces sauvegardes lorsqu'il démarrera. Pour cela, allez dans /boot/grub/menu.lst, et à la bonne ligne kernel vérifiez la présence d'un paramètre resume=/dev/sda5. S'il n'est pas là ou si le chemin est mauvais, modifiez et sauvez.

Il ne reste maintenant plus qu'à tenter une hibernation

hibernate --verbosity=3

Normalement la machine a passé un temps à afficher la progression d'une sauvegarde d'état, et s'est éteint physiquement. Une pression sur le bouton d'allumage et le kernel Linux démarre puis stoppe sa progression pour recharger la sauvegarde. Et c'est terminé.

Si vous obtenez dans les traces une erreur du genre

roothibernate -v3
...
hibernate: Running /usr/sbin/s2disk ...
suspend: Could not stat the resume device file
...

Il y a de fortes chances que le paramètre resume device soit faux, vérifiez-le et corriger.

Sur l'U810, l'hibernation prend 28 s à l'allée, et 33 secondes au retour. C'est déjà mieux qu'un allumage classique. Notez que la désactivation de la compression ne semble pas entraîner une résurrection plus rapide. Sur une machine de bureau, l'extinction prends 4 seconds et l'allumage 20s.

La colle avec gnome-power-manager

Gnome Power Manager est l'outil standard de gnome pour la gestion de l'énergie. Il dispose d'une petite icône dans la barre de notification permettant la mise en veille et l'hibernation. Il a aussi le bon goût de connecter la touche C-alt-D, sous le lecteur d'empreintes, à la fonction mise en veille.

le problème est qu'il utilise une méthode d'hibernation et de mise en veille qui plante l'U810 ou le laisse sans écran. La solution est aussi simple qu'infernal à trouver. Il faut pour cela parler à .. HAL. Et modifier deux scripts qui se trouvent dans /usr/lib/hal/scripts/linux/. Tout d'abord hal-hal-system-power-suspend-linux où l'on trouve la raison du problème : il ne prends en charge que pm-utils et pas hibernate. Pour régler cela modifiez pour que cela ressemble à ceci :

...
# We only support pm-utils
/usr/sbin/hibernate --config-file=/etc/hibernate/ram.conf

# Refresh devices as a resume can do funny things
...

Maintenant que ce problème est réglé passons à l'hibernation en modifiant hal-system-power-hibernate-linux qui a le même problème que le frèrot :

# We only support pm-utils
/usr/sbin/hibernate

#Refresh devices as a resume can do funny things

Voilà, maintenant tout marche directement par gnome :-) Et il est même possible de télécommander le tout en utilisant DBUS. Par exemple pour hiberner :

dbus-send --session --dest=org.freedesktop.PowerManagement --type=method_call --print-reply --reply-timeout=2000 /org/freedesktop/PowerManagement org.freedesktop.PowerManagement.Hibernate

Conclusion

Bref, vous l'aurez remarqué, ça ne fût pas de tout repos mais le résultat est là, ça fonctionne et même très bien. Si pour un portable ce genre de paramétrage est simplement vitale, pour une machine de bureau, cela permet de gagner énormément sur la consommation énergétique. Car sincèrement, même pour une pause café, 24 secondes auquel il faut rajouter 10s pour le démarrage du BIOS, c'est pas très cher payer. Et moins d'électricité consommé c'est un argument de moins pour certains empaffés de notre connaissance pour nous coller un 3ième EPR...