66 votes

Comment passer automatiquement de Suspend à Hibernate ?

Est-il possible de faire en sorte qu'Ubuntu passe en état d'hibernation à partir de la suspension, alias "sédation de la suspension" ?

Ce que je cherche, c'est ça :
Lorsque je ferme le couvercle, l'ordinateur portable est mis en veille. Ensuite, après un temps prédéterminé (même si la batterie est forte), si je ne l'utilise toujours pas, il se met en veille prolongée pour économiser la batterie.

Par exemple, mon ordinateur portable est configuré pour se mettre en veille lorsque je ferme le couvercle. Si je ne l'utilise pas pendant toute une journée, la batterie se vide, car même en mode suspension, le matériel consomme toujours une petite quantité d'énergie, et la batterie finit par se décharger. Ce que je veux, c'est pouvoir dire à Ubuntu que même s'il est suspendu, il doit passer en Hibernation après quelques heures d'inactivité.

Windows peut le faire. Ubuntu peut être programmé pour se mettre en veille. oder Hibernation sur minuterie, mais pas les deux.

43voto

PRIHLOP Points 1439

Sur Ubuntu 18.04 et plus récent c'est beaucoup plus facile. Sur systemd est disponible un nouveau mode suspendre-les-hibernations . Pour commencer à utiliser cette fonction, vous devez créer un fichier /etc/systemd/sleep.conf avec le contenu suivant :

[Sleep]
HibernateDelaySec=3600

Ensuite, vous pouvez le tester par commande :

sudo systemctl suspend-then-hibernate

vous pouvez modifier HibernateDelaySec pour réduire le délai d'hibernation.


Si tout fonctionne bien, vous pouvez changer l'action de fermeture du couvercle, pour cela vous devez modifier le fichier /etc/systemd/logind.conf

Vous devez trouver une option HandleLidSwitch= décommentez-le et changez-le en HandleLidSwitch=suspend-then-hibernate . Ensuite, vous devez redémarrer le service systemd-logind (attention ! votre session utilisateur sera redémarrée) par la commande suivante :

sudo systemctl restart systemd-logind.service

C'est tout ! Vous pouvez maintenant utiliser cette belle fonction.

37voto

Derek Pressnall Points 526

La solution à ce problème est simple. D'abord, lors de la suspension et de la reprise, le programme pm-suspend exécute une série de scripts en /etc/pm/sleep.d y /usr/lib/pm-utils/sleep.d . Ma solution est donc d'ajouter un script qui fait ce qui suit :

  1. Lors de la suspension, enregistrez l'heure actuelle et enregistrez un événement de réveil en utilisant rtcwake.

  2. Au moment de la reprise, vérifiez l'heure actuelle par rapport à l'heure enregistrée ci-dessus. Si suffisamment de temps s'est écoulé, alors nous nous sommes probablement réveillés à cause de l'événement du minuteur rtc. Sinon, nous nous sommes réveillés tôt en raison d'un événement utilisateur (comme l'ouverture de l'écran de l'ordinateur portable).

  3. Si nous nous sommes réveillés à cause de la minuterie rtc, alors émettez immédiatement une commande "pm-hibernate" pour entrer en hibernation.

Voici un script qui fait cela. Nommez-le 0000rtchibernate et le placer dans le /etc/pm/sleep.d (le 0000 est important, afin que le script s'exécute en premier lors de la suspension, et en dernier lors de la reprise).

#!/bin/bash
# Script name: /etc/pm/sleep.d/0000rtchibernate
# Purpose: Auto hibernates after a period of sleep
# Edit the "autohibernate" variable below to set the number of seconds to sleep.
curtime=$(date +%s)
autohibernate=7200
echo "$curtime $1" >>/tmp/autohibernate.log
if [ "$1" = "suspend" ]
then
    # Suspending.  Record current time, and set a wake up timer.
    echo "$curtime" >/var/run/pm-utils/locks/rtchibernate.lock
    rtcwake -m no -s $autohibernate
fi

if [ "$1" = "resume" ]
then
    # Coming out of sleep
    sustime=$(cat /var/run/pm-utils/locks/rtchibernate.lock)
    rm /var/run/pm-utils/locks/rtchibernate.lock
    # Did we wake up due to the rtc timer above?
    if [ $(($curtime - $sustime)) -ge $autohibernate ]
    then
        # Then hibernate
        rm /var/run/pm-utils/locks/pm-suspend.lock
        /usr/sbin/pm-hibernate
    else
        # Otherwise cancel the rtc timer and wake up normally.
        rtcwake -m no -s 1
    fi
fi

J'espère que ce code se retrouvera sur ce forum (c'est mon premier message ici).

Modifier la valeur du délai d'attente autohibernate=7200 en haut, jusqu'au nombre de secondes que vous avez choisi pour dormir avant de passer en hibernation. La valeur actuelle ci-dessus est de 2 heures. Notez que votre ordinateur portable se réveillera à ce moment-là pendant quelques secondes, pendant qu'il exécute la fonction d'hibernation.

Donc, si vous prévoyez de mettre votre ordinateur portable dans une mallette, ne le suspendez pas, mais mettez-le en veille prolongée. Sinon, votre ordinateur portable risque de surchauffer, surtout s'il se trouve dans un étui étroit (même s'il ne reste allumé que quelques secondes à une minute).

J'ai utilisé cette méthode ces deux derniers jours, avec succès jusqu'à présent (et m'a évité une batterie à plat cet après-midi). Profitez-en.

Pour les autres distributions Linux qui utilisent systemd et les versions Ubuntu plus récentes, cela devrait encore fonctionner si vous placez le script en /usr/lib/systemd/system-sleep au lieu de /etc/pm/sleep.d . Remplacez également le /usr/sbin/pm-hibernate avec systemctl hibernate .

13voto

Eric Points 266

Pour expliquer comment cela fonctionne (c'est similaire à Windows) en termes simples : la machine ne se réveille pas de la veille lorsque la batterie devient faible pour être en mesure de sauvegarder l'état de la machine sur la partition d'échange, il enregistre tout sur la partition d'échange immédiatement en veille, et lorsque la batterie se vide, il va récupérer de cela en chargeant l'état de la partition d'échange (comme il le ferait en cas d'hibernation).

AFAIK linux utilisera/devrait utiliser la mise en veille hybride/hibernate au lieu de la mise en veille "normale" s'il sait que cela fonctionne pour votre matériel. Il est également possible que cela soit désactivé actuellement à cause de trop de bogues ou autre... ;)

Si vous aimez expérimenter, vous pouvez peut-être voir si vous pouvez obtenir de bons résultats avec pm-suspend-hybride .

Si ce qui suit indique que vous avez de la chance, alors en théorie la suspension hybride est prise en charge sur votre système :

pm-is-supported --suspend-hybrid && echo "you're lucky"

6voto

ayan4m1 Points 905

Vous pourriez être intéressé par s2both . Il est fourni par le paquet uswsusp dans Ubuntu 10.10. Il effectue une suspension sur disque, mais au lieu d'arrêter le système, il le met en S3, qui est le mode d'alimentation généralement associé à l'option "Suspend" dans Ubuntu. pm-suspend-hybride est un autre outil qui prétend faire la même chose.

Pour automatiser cette opération à la fermeture du couvercle, consultez le guide suivant qui vous permet d'exécuter un script arbitraire lorsqu'un événement du couvercle est attrapé :

http://ubuntuforums.org/showthread.php?t=1076486

Si vous avez un ThinkPad, la page de manuel de tpctl fait référence à un argument, --pm-sedation-hibernate-from-suspend-timer qui semble fournir la fonctionnalité que vous recherchez. Je vous déconseille d'essayer cela sur du matériel autre que le ThinkPad.

Pour référence, j'ai regardé la page de manuel de hibernate.conf Il ne semblait pas y avoir d'options pertinentes, mais cela pourrait valoir la peine de le relire.

5voto

mihai.ile Points 51

Ubuntu 16.04 - passer de la suspension/sommeil à la mise en veille prolongée après un temps prédéterminé

Il semble que sur Ubuntu 16.04 les choses soient un peu différentes, alors les étapes que j'ai suivies pour le faire fonctionner étaient les suivantes :

  1. Assurez-vous qu'hibernate fonctionne comme prévu lorsque vous exécutez

    systemctl hibernate
  2. Copier l'original suspend.target fichier :

    sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target

    Puis modifiez le fichier /etc/systemd/system/suspend.target et ajoutez la ligne :

    Requires=delayed-hibernation.service

    à la [Unit] de ce fichier.

  3. Créer le fichier /etc/systemd/system/delayed-hibernation.service avec le contenu suivant :

    [Unit] Description=Delayed hibernation trigger Before=suspend.target Conflicts=hibernate.target hybrid-suspend.target StopWhenUnneeded=true

    [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/delayed-hibernation.sh pre suspend ExecStop=/usr/local/bin/delayed-hibernation.sh post suspend

    [Install] WantedBy=sleep.target

  4. Créer le fichier de configuration /etc/delayed-hibernation.conf pour le script avec le contenu suivant :

    # Configuration file for 'delayed-hibernation.sh' script

    Specify the time in seconds to spend in sleep mode before the computer hibernates

    TIMEOUT=1200 #in seconds, gives 20 minutes

  5. Créez le script qui fera réellement le travail difficile.

    Créer un fichier /usr/local/bin/delayed-hibernation.sh avec le contenu :

    !/bin/bash

    Script name: delayed-hibernation.sh

    Purpose: Auto hibernates after a period of sleep

    Edit the `TIMEOUT` variable in the `$hibernation_conf` file to set the number of seconds to sleep.

    hibernation_lock='/var/run/delayed-hibernation.lock' hibernation_fail='/var/run/delayed-hibernation.fail' hibernation_conf='/etc/delayed-hibernation.conf'

    Checking the configuration file

    if [ ! -f $hibernation_conf ]; then echo "Missing configuration file ('$hibernation_conf'), aborting." exit 1 fi hibernation_timeout=$(grep "^[^#]" $hibernation_conf | grep "TIMEOUT=" | awk -F'=' '{ print $2 }' | awk -F'#' '{print $1}' | tr -d '[[ \t]]') if [ "$hibernation_timeout" = "" ]; then echo "Missing 'TIMEOUT' parameter from configuration file ('$hibernation_conf'), aborting." exit 1 elif [[ ! "$hibernation_timeout" =~ ^[0-9]+$ ]]; then echo "Bad 'TIMEOUT' parameter ('$hibernation_timeout') in configuration file ('$hibernation_conf'), expected number of seconds, aborting." exit 1 fi

    Processing given parameters

    if [ "$2" = "suspend" ]; then curtime=$(date +%s) if [ "$1" = "pre" ]; then if [ -f $hibernation_fail ]; then echo "Failed hibernation detected, skipping setting RTC wakeup timer." else echo "Suspend detected. Recording time, set RTC timer" echo "$curtime" > $hibernation_lock rtcwake -m no -s $hibernation_timeout fi elif [ "$1" = "post" ]; then if [ -f $hibernation_fail ]; then rm $hibernation_fail fi if [ -f $hibernation_lock ]; then sustime=$(cat $hibernation_lock) rm $hibernation_lock if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then echo "Automatic resume from suspend detected. Hibernating..." systemctl hibernate if [ $? -ne 0 ]; then echo "Automatic hibernation failed. Trying to suspend instead." touch $hibernation_fail systemctl suspend if [ $? -ne 0 ]; then echo "Automatic hibernation and suspend failover failed. Nothing else to try." fi fi else echo "Manual resume from suspend detected. Clearing RTC timer" rtcwake -m disable fi else echo "File '$hibernation_lock' was not found, nothing to do" fi else echo "Unrecognised first parameter: '$1', expected 'pre' or 'post'" fi else echo "This script is intended to be run by systemctl delayed-hibernation.service (expected second parameter: 'suspend')" fi

  6. Rend le script exécutable :

    chmod 755 /usr/local/bin/delayed-hibernation.sh

Cela m'a pris pas mal de temps avant d'écrire ce script basé sur d'autres réponses dans ce fil, des choses que j'ai trouvées sur internet comme https://bbs.archlinux.org/viewtopic.php?pid=1554259

Ma version du script essaie de traiter de nombreux problèmes comme se remettre en suspension si l'hibernation n'a pas réussi mais ne pas se réveiller après le temps prédéterminé, encore et encore.

  1. L'étape finale, je suppose, serait de simplement exécuter

    sudo systemctl daemon-reload
    sudo systemctl enable delayed-hibernation.service 

    pour s'assurer que les nouveaux services/configurations sont utilisés.

Pour vérifier le journal de service, vous pouvez utiliser :

sudo systemctl status delayed-hibernation.service

ou pour un journal complet de l'utilisation du service :

sudo journalctl -u delayed-hibernation.service

Un journal normal que j'obtiens du service en cours d'exécution est :

mile@mile-ThinkPad:~$ sudo systemctl status delayed-hibernation.service 
 delayed-hibernation.service - Delayed hibernation trigger
   Loaded: loaded (/etc/systemd/system/delayed-hibernation.service; enabled; vendor preset: enabled)
   Active: inactive (dead)

Jun 09 20:35:42 mile-ThinkPad systemd\[1\]: Starting Delayed hibernation trigger...
Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh\[2933\]: Suspend detected. Recording time, set RTC timer
Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh\[2933\]: rtcwake: assuming RTC uses UTC ...
Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh\[2933\]: rtcwake: wakeup using /dev/rtc0 at Thu Jun  9 18:55:43 2016
Jun 09 20:55:44 mile-ThinkPad systemd\[1\]: Started Delayed hibernation trigger.
Jun 09 20:55:44 mile-ThinkPad systemd\[1\]: delayed-hibernation.service: Unit not needed anymore. Stopping.
Jun 09 20:55:44 mile-ThinkPad systemd\[1\]: Stopping Delayed hibernation trigger...
Jun 09 20:55:44 mile-ThinkPad delayed-hibernation.sh\[3093\]: Automatic resume from suspend detected. Hibernating...
Jun 09 20:55:44 mile-ThinkPad systemd\[1\]: Stopped Delayed hibernation trigger.
mile@mile-ThinkPad:~$ 

Donc Ce serait ça, j'espère que cela aidera vraiment quelqu'un puisque j'ai passé des jours à essayer de trouver la bonne combinaison de configurations et de versions de script pour faire fonctionner cette fonctionnalité pratique.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X