Caveat : Ceci est un billet à très haute teneur en informatique, très orienté Linux/Ubuntu 7.10 Gutsy.
Mise à jour du 12 juillet 2008 : C’est valable aussi pour la version 8.04 « Hardy ».

Je suis très satisfait de Linux en général, Debian en plus particulier, et d’Ubuntu en très particulier. Si depuis la version 7.04 (Feisty) je pouvais utiliser la mise en veille de mon PC (une machine de bureau de plus d’un an), l’hibernation ne fonctionnait pas. Or seule l’hibernation permet de couper l’alimentation à la multiprise, ce qui supprime aussi quelques watts dus à l’écran ou aux chargeurs situés sur la même multiprise. Les fidèles du présent blog se le rappellent, j’avais fait les mesures avec mon wattmètre.

Et puis mon côté geek ne pouvait laisser passer une fonctionnalité non fonctionnelle. J’ai donc potassé, et réussi. Autant condenser ça pour ceux qui auraient les mêmes problèmes, et surtout pour moi le jour probable où je retomberai sur le même problème en réinstallant cette machine ou une autre...

Une histoire de swap

L’hibernation exige la présence d’une partition de swap, un fichier de swap ne suffit pas. Il se trouve que le swap sous Ubuntu a une fichue tendance à se désactiver tout seul à cause des UUID qui changent spontanément entre deux installations, voire entre deux boots chez certains.

Bref, il faut vérifier la présence dudit swap par la commande swapon -s. Dans mon cas, cela renvoie /dev/sda5, mais rien si aucun swap n’est actif.

Mais comme déjà dit, s’il est absent, il est peut-être juste désactivé, alors qu’à l’installation la partition adéquate a généralement été créée. J’ai eu le problème de la partition qui changeait d’identifiant à chaque migration de version d’Ubuntu, le bug traînait encore en Gutsy.

La démarche dans ce cas est alors :

  • Voir si un swap n’arrive pas à se charger avec la commande swapon -a qui devrait renvoyer un message d’erreur.
  • Chercher la ligne correspondante dans /etc/fstab, vérifier la syntaxe.
  • Dans mon cas, l’UUID était faux. Je n’ai pas compris pourquoi Ubuntu avait laissé tomber la tradition des bons vieux /dev/sxx (peut-être à cause des médias amovibles ?), mais on va faire avec.

    Donc j’ai dû rechercher le bon UUID en regardant la liste de ce qui est existe sur le système : ls -l /dev/disk/by-uuid/ me donne ceci (l’identifiant pointe vers la partition associée dans le classique schéma /dev/xxxx) :

lrwxrwxrwx 1 root root 10 2008-01-13 18:37 29492826-d014-460e-8bdc-61c915f0c032 -> ../../sda5
lrwxrwxrwx 1 root root 10 2008-01-13 18:37 4955dbe1-6f16-4616-b4a7-7bee7644a88c -> ../../sda1

  • Je copie l’UUID dans le /etc/fstab dans la ligne concernant le swap, ce qui donne chez moi une ligne du genre :

UUID=29492826-d014-460e-8bdc-61c915f0c032 none swap sw 0 0

  • Réessayer un swapon -a.
  • Dans mon cas cela a échoué, il a fallu préparer le swap sur la partition en question :

mkswap /dev/sda5 (Ne pas se planter de partition !)

  • Ouf !

Je passe sur la création du swap s’il n’est vraiment pas là et les autres détails ; voir help.ubuntu.com.

Installation

Je ne sais pas pourquoi ils n’étaient pas installés d’entrée : uswsusp (pour Software Suspend) est le paquet nécessaire, et il propose d’installer splashy dans la foulée, donc sous root ou après un sudo :

aptitude install uswsusp splashy

Quoique installer splashy a peut-être été la cause de mes problèmes, voir ci-dessous. Je conseillerais de laisser tomber pour un premier essai. (Mise à jour du 26/8/2008 : Et c’est bien le cas sous Gutsy d’après mes lectures. Voir cette page pour plus de détails sur splashy.)

Uswsusp se plaint si aucun swap n’est disponible, et pose quelques questions accessoires, notamment :

  • Faut-il compresser le fichier d’hibernation ? Je n’en sais rien, je n’ai pas chronométré. Cela dépend évidemment de la puissance du processeur, de la vitesse du disque dur et de la taille de la RAM à sauvegarder.
  • Faut-il crypter le fichier ? Inutile pour des essais.

Il crée son fichier /etc/uswsusp.conf qu’on vérifiera par prudence. Puis les différents ramdisks de boot sont regénérés (c’est assez long).

Congélation

Dans mes souvenirs il n’y avait pas eu besoin de rebooter pour que l’hibernation soit active. Toujours sous root, la commande s2disk a affiché un compteur de compression puis de sauvegarde de la RAM, et éteint la machine. Joie !

Le plus stressant est la rallumage de la bête, et, plus rapidement qu’un boot normal, je me retrouve à nouveau devant mon terminal. Magnifique !

NB : Il existe aussi une commande s2ram, plutôt pour les portables, qui sauvegarde en RAM, et sur disque au cas où la batterie s’épuiserait. J’ai vu ça pour la première fois sur mon Mac, c’est très pratique.

Fignolage

L’essentiel marchait mais je n’étais pas au boot bout de mes peines : la ligne de commande est moyennement conviviale, nécessite les droits de root, et en cas de rallumage il n’y a aucun mot de passe à rentrer. Le bouton « Hiberner » dans KDE ou Gnome est là pour ça, mais il ne fonctionnait pas (pas d’extinction et retour immédiat à l’économiseur d’écran). Il a fallu creuser.

Apparemment KDE (ou plus exactement kdm) utilise un script système du doux nom de /etc/acpi/hibernate.sh (paquet acpi-support). Le lancer à la main directement échoue sur une erreur dans les paramètres envoyés à s2disk (/sbin/s2disk: invalid option -- x).
En fouillant je découvre :

  • qu’il va chercher le nom de la partition à utiliser dans /etc/initramfs-tools/conf.d/resume, qui n’était pas à jour (et je n’ai aucune idée d’où vient ce fichier). J’y ai donc rajouté l’indication de mon swap :

RESUME=UUID=29492826-d014-460e-8bdc-61c915f0c032

  • que des paramètres -x et -y sont envoyées à s2disk (manifestement les dimensions de l’écran dans /etc/usplash.conf), alors que s2disk ne connaît pas de tels paramètres !
    J’ai donc sauvegardé l’original et carrément modifié le script hibernate.sh. Modifier des scripts système soumis à « maintenance extérieure » n’est pas mon genre mais nécessité fait loi. La ligne 34 du script était :
    /sbin/s2disk -x "$xres" -y "$yres" $DEVICE
    et je l’ai transformée en :

/sbin/s2disk $DEVICE

Ce qui en fait revient à court-circuiter tout l’appel à splashy (test du /etc/usplash.conf) et donc pourquoi pas désinstaller splashy si on se contrefiche de l’écran de boot ?

Verdict

Malgré ce premier succès, il n’en reste pas moins que la stabilité de l’hibernation et de la mise en veille est très relative sur ma machine, elle échoue relativement souvent sans cause reconnaissable, et sans laisser de trace dans de quelconques journaux... (ou alors ils sont bien cachés).

Mise à jour de mars 2008 : C’est reproductible : j’ai droit à une seule hibernation ; si je ne reboote pas avant la seconde, la machine ne se réveille pas. C’est toujours mieux que rien… De plus je viens de me faire avoir en bootant sur une Knoppix alors qu’il y avait une session en hibernation « en attente » : pas de problème pour booter sur le live DVD, mais au reboot les partitions étaient remontées en lecture seule, puis fsck du disque au reboot, qui échoue et m’a tendu la tronçonneuse. Pas d’autre choix que de relancer fsck en disant oui aux quelques incohérences détectées. Ça semble remarcher a remarché.

Mise à jour du 12 juillet 2008 : Après mise à jour sous Ubuntu 8.04, tout fonctionne très bien, même sans reboot intermédiaire. La machine a été mise à jour après les manipulations précédentes, certaines ont été écrasées comme mes correctifs de scripts, d’autres non comme le paramétrage. Je ne sais pas si en réinstallant de zéro cela fonctionnerait aussi bien, donc les présentes notes pourraient bien resservir un jour.

Une dernière chose pour fignoler : splashy se configure dans le fichier /etc/default/splashy et les thèmes se gèrent avec splashy-config, je n’ai pas joué avec cela. Un dpkg-reconfigure -pall splashy ne pose aucune question... Je n’ai pas testé, je le virerai peut-être plus tard...