Sources principales
- https://docs.kernel.org/admin-guide/pm/sleep-states.html
- https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate
- https://wiki.archlinux.org/title/Power_management#ACPI_events
- https://www.malekal.com/acpi-advanced-configuration-and-power-interface/
- https://www.kernel.org/doc/html/latest/power/swsusp.html
Ce que j’ai appris
Les différents modes
Il y a trois grands types de veilles dans l’ordre de consommation d’énergie :
- Suspend to idle
- Standby
- Suspend to RAM (veille)
- Hibernation
A titre personnel je ne suis pas certain d’avoir déjà utilisé les deux premiers qui semblent être des économies toutes relatives d’énergie. Je suppose que l’immense majorité du temps les personnes veulent 3. ou 4.
L’hibernation est documentée comme étant un mode radicalement différent des autres. Il implique beaucoup plus d’étapes et de complexité. Cela explique certainement en partie pourquoi c’est un mode qui semble être moins fiable.
Savoir ce qui notre système supporte
La documentation
linux nous apprend
qu’il existe dans /sys/power
des fichiers dont le contenu détermine l’état du
noyau :
/sys/power/state
contient la liste des états disponibles. Sur mon pc j’aifreeze mem disk
.freeze
est le mode Suspend to idle,mem
est configurable mais sera généralement la veille RAM et disk l’hibernation.mem_sleep
contient les différents mode de veille disponibles. Sur mon pc j’ais2idle [deep]
. Le mode entre crochet est celui sélectionné, il sera activé si l’on déclenche le modemem
du fichier précédent. Ici sélectionners2idle
serait à priori redondant avec lefreeze
du fichier précédent mais je ne suis pas certain.disk
contient les différentes actions que le noyau peut lancer après avoir créé l’image d’hibernation. Sur mon pc j’ai[platform] shutdown reboot suspend test_resume
. Comme pour le fichier précédent l’action sélectionnée est entre crochets. Les modesreboot
ettest_resume
sont là pour des besoins de diagnostics.platform
mettra l’ordi dans un état spécial s’il supporte ACPI1.shutdown
éteindra l’ordinateur etsuspend
le mettra en veille RAM. C’est une hibernation dite hybride.image_size
contient, en octet, la taille maximale des images d’hibernation. Cette taille n’est pas absolue mais le système fera de son mieux pour la respecter. S’il n’y parvient pas il prendra plus de place.
Changer de mode
Directement par le noyau
Dans l’esprit “tout est fichier” le noyau linux permet de déclencher ces états
en interagissant avec des fichiers2. Pour déclencher un mode il faut écrire
son nom dans /sys/power/state
. Pour mem
et disk
le comportement sera
modifié selon le mode ou l’action choisie dans mem_sleep
et disk
. Pour
changer de sélection dans l’un de ces deux fichiers il faut également écrire le
nom de ce que l’on veut sélectionner. Avant de donner des exemples une petite
explication de l’erreur suivante :
$ sudo printf "freeze" > /sys/power/stat
sh: 1: cannot create /sys/power/stat: Permission denied
Bien que le printf
ait été exécuté avec les bons droits la redirection est
elle effectuée par le shell courant. Trois solutions :
- Se logger en tant que root
Ces commandes font toutes des choses différentes mais pour notre besoin passons sur les détails :
$ sudo -i
$ sudo -s
$ su -
Passer la commande en argument d’un shell
$ sudo sh -c ‘printf “freeze” > /sys/power/stat
Utiliser
tee
tee
prend dans stdin des données et les écrit dans dans lefichier qui lui est
passé en argument. Puisque cela permet d’écrire dans un fichier sans redirection
ça fonctionne :
$ printf "freeze" | sudo tee /sys/power/state
BONUS : vim (
c$freezeZZ
)$ sudo vim /sys/power/state
Après ce petit détour, des exemples de mise en veille :
Déclencher le mode suspend to idle
$ cat /sys/power/mem_sleep
s2idle [deep]
$ sudo sh -c 'printf "freeze" > /sys/power/state'
S’assurer que le mode mem
soit de la veille RAM et l’activer :
$ cat /sys/power/mem_sleep
[s2idle] deep
$ sudo sh -c 'printf "deep" > /sys/power/mem_sleep'
$ cat /sys/power/mem_sleep
s2idle [deep]
$ sudo sh -c 'printf "mem" > /sys/power/state'
Avec systemd (brrrr)
Beaucoup de distributions linux viennent dorénavant avec systemd
. J’aime pas
trop, j’ai le sentiment que ça rajoute pleins de niveaux de complexité
supplémentaires qui, lorsqu’ils fonctionnent bien sont super mais lorsqu’ils
fonctionnent mal rendent plus difficile le débogage. La quantité de choses que
fait systemd rend sa documentation également plus difficile. Peu importe,
l’utilisation est ici simple :
# RAM
$ systemctl suspend
# Hibernation
$ systemctl hibernate
# Hybride
$ systemctl hybrid-sleep
Alors pourquoi passer par systemd plutôt que le noyau directement ?
Principalement parce que systemd
offre un peu plus de garantie que tout se
passe bien au retour (wifi, session etc). Par exemple sur mon pc un retour de
veille RAM déclenchée via le noyau ne me demande pas de mot de passe de session.
Pour cause, le noyau n’a pas à savoir qu’il aurait du verrouiller ma session. Un
retour d’une veille déclenchée par systemd lui le fait parce que systemd estime
qu’il est pertinent de verrouiller la session avant de mettre le système en
veille.
Les problèmes d’hibernation
Personnellement quand j’essaye d’hiberner j’ai soit :
$ sudo sh -c 'echo "disk" >> /sys/power/state'
sh: 1: echo: echo: I/O error
soit
$ sudo systemctl hibernate
Call to Hibernate failed: Not enough swap space for hibernation
Le souci étant que mon disque est déjà complètement rempli d’une seule partition prenant toute la place. Je ne peux pas agrandir la partition de swap à chaud, il faudrait que je boot sur une clef usb pour. J’arrête donc l’écriture de l’article ici pour aujourd’hui.
Disque chiffré avec LVM
Il faudrait à priori :
vérifier quelle partition héberge le swap
$ swapon –output-all NAME TYPE SIZE USED PRIO UUID LABEL /dev/dm-2 partition 980M 16K -2 40cdc190-2bb5-4a76-bab5-46aaaeb3dcd3 $ lvdisplay — Logical volume — LV Path /dev/arthur-dnum-vg/root LV Name root VG Name arthur-dnum-vg LV UUID xEJcr2-RIcA-EcaA-MvAQ-ZO2f-nFdj-lLyrQj LV Write Access read/write LV Creation host, time arthur-dnum, 2023-12-09 14:03:58 +0100 LV Status available # open 1 LV Size 236,52 GiB Current LE 60550 Segments 1 Allocation inherit Read ahead sectors auto
currently set to 256 Block device 254:1
— Logical volume — LV Path /dev/arthur-dnum-vg/swap1 LV Name swap1 VG Name arthur-dnum-vg LV UUID wWcepR-TPnV-D2Xo-YRYY-6Zjl-n8aC-ZcYhdN LV Write Access read/write LV Creation host, time arthur-dnum, 2023-12-09 14:03:58 +0100 LV Status available
open 2
LV Size 980,00 MiB Current LE 245 Segments 1 Allocation inherit Read ahead sectors auto
currently set to 256 Block device 254:2
ou alternativement :
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 238,5G 0 disk
├─sda1 8:1 0 512M 0 part /boot/efi
├─sda2 8:2 0 488M 0 part /boot
└─sda3 8:3 0 237,5G 0 part
└─sda3_crypt 254:0 0 237,5G 0 crypt
├─arthur--dnum--vg-root 254:1 0 236,5G 0 lvm /
└─arthur--dnum--vg-swap_1 254:2 0 980M 0 lvm [SWAP]
Ici la réponse est assez évidente puisque l’une des deux volume logique s’appelle swap mais vérifions tout de même
$ realpath /dev/arthur-dnum-vg/swap_1
/dev/dm-2
Pour redimensionner le swap il faudra éventuellement faire de la place en rendant plus petit les autres LVM :
$ lvresize -L-3G /dev/arthur-dnum-vg/root
Puis agrandir le swap :
$ lvresize -L+3G /dev/arthur-dnum-vg/swap_1