Comment passer automatiquement de Suspend into Hibernate?

53

Est-il possible de faire passer Ubuntu à l'état Hibernate à partir de Suspend, alias "Suspend Sedation"?

Ce que je recherche, c’est ceci:
lorsque je ferme le couvercle, l’ordinateur portable est mis en suspension. Ensuite, après un temps prédéterminé (même si la batterie devient forte), si je ne l'utilise toujours pas, il devrait se mettre dans un système Hibernate pour économiser la batterie.

Par exemple, mon ordinateur portable est configuré pour passer en mode suspension lorsque je ferme le couvercle. Si je ne l'utilise pas pendant toute la journée, la batterie se décharge complètement, car même en mode veille, le matériel continue de consommer une petite quantité d'énergie et la batterie se décharge éventuellement. Ce que je veux, c'est pouvoir dire à Ubuntu que même si elle est suspendue, elle doit quand même entrer dans Hibernate après quelques heures d'inactivité.

Windows peut le faire. Ubuntu peut être programmé pour passer en veille ou en veille prolongée, mais pas les deux.

Sergey Stadnik
la source
Dans mes recherches, j'ai trouvé le même fil Linux Mint, mais "Suspend Sedation" n'est pas un terme officiel Microsoft pour cette fonctionnalité et, autant que je sache, a été inventé par l'utilisateur du forum Linux Mint qui l'a mentionné.
ayan4m1
Existe-t-il un meilleur nom pour cette fonctionnalité?
Sergey Stadnik
Autant que je sache, il n'y a pas de nom universellement accepté pour la fonctionnalité. "Suspension hybride" est utilisé par certains, "suspendre la sédation" est utilisé par cet utilisateur du forum Linux Mint, et j'ai déjà entendu "hibernation et suspension" qui faisait référence au processus auparavant. Microsoft l'appelle officiellement "sommeil hybride", du moins pour Windows 7.
ayan4m1
2
@ ayan4m1 Je réalise que c'est une vieille question, mais je pense qu'il est important de clarifier cela. Le sommeil hybride n’est pas la même chose que "Dormir puis hiberner après une période déterminée". Le sommeil hybride devient tout simplement en veille prolongée lorsque l’électricité est coupée et que la batterie s’épuise. Le comportement décrit par l'OP ne nécessite pas l'activation de la veille hybride.
Paul

Réponses:

20

Dans Ubuntu 18.04, c'est beaucoup plus facile. Dans systemd est disponible un nouveau mode suspend-then-hibernate . 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 avec la commande suivante:

sudo systemctl suspend-then-hibernate

vous pouvez modifier HibernateDelaySecpour réduire le délai en veille prolongée.


Si tout fonctionne correctement, vous pouvez modifier l'action Fermer le couvercle. Pour ce faire, vous devez modifier le fichier /etc/systemd/logind.conf.

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

sudo systemctl restart systemd-logind.service

C'est tout! Maintenant, vous pouvez utiliser cette fonction intéressante.

PRIHLOP
la source
C'était sur place. Utilisation sur Pop! _OS 18.10 (ou Ubuntu 18.10).
eduncan911 le
Brilliant merci! Sleep.conf affecte-t-il également le mode hibernation ou affecte-t-il uniquement suspendre-alors-hiberner?
user2428107
@ user2428107, vous en saurez plus sur les options dans le manuel systutorials.com/docs/linux/man/5-systemd-sleep
PRIHLOP du
35

La solution à cela est simple. Tout d’abord, lors de la suspension et de la reprise, le programme pm-suspend exécute une série de scripts dans /etc/pm/sleep.det /usr/lib/pm-utils/sleep.d. Ma solution consiste donc à ajouter un script qui effectue les tâches suivantes:

  1. Lors de la suspension, enregistrez l'heure actuelle et enregistrez un événement de réveil à l'aide de rtcwake.
  2. À la reprise, vérifiez l’heure actuelle par rapport à l’heure enregistrée d’en haut. Si suffisamment de temps s'est écoulé, nous nous sommes probablement réveillés en raison de l'événement de minuterie rtc. Sinon, nous nous sommes réveillés tôt à cause d'un événement de l'utilisateur (comme l'ouverture de l'écran du portable).
  3. Si nous nous sommes réveillés à cause du minuteur rtc, émettons immédiatement une commande "pm-hibernate" pour passer en veille prolongée.

Voici un script qui fait cela. Nommez-le 0000rtchibernateet placez-le dans le /etc/pm/sleep.drépertoire (la valeur 0000 est importante pour que le script s'exécute en premier lors de la suspension et en dernier lieu 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

Espérons que ce code passe sur ce forum (ceci est mon premier post ici).

Modifiez la valeur du délai d’expiration autohibernate=7200en haut du nombre de secondes avant de passer en veille prolongée. La valeur actuelle ci-dessus est 2 heures. Notez que votre ordinateur portable se réveillera à cette heure pendant quelques secondes pendant l’exécution de la fonction de veille prolongée.

Donc, si vous envisagez de mettre votre ordinateur portable dans une affaire, ne suspendez pas, mais hibernez à la place. Sinon, votre ordinateur portable pourrait surchauffer dans esp. si c'est dans un étui bien ajusté (bien qu'il ne soit allumé que quelques secondes à une minute).

J'utilise cette méthode depuis quelques jours, jusqu'à présent, elle a été un succès (et m'a sauvé d'une batterie morte cet après-midi). Prendre plaisir.

Pour les autres distributions Linux qui utilisent systemdles versions plus récentes d’Ubuntu, cela devrait toujours fonctionner si vous placez le script au /usr/lib/systemd/system-sleeplieu de /etc/pm/sleep.d. Remplacez également la /usr/sbin/pm-hibernatecommande par systemctl hibernate.

Derek Pressnall
la source
Cela a fonctionné ici, mais seulement après avoir modifié le fichier pour ajouter X à tout le monde. Je suis un novice énorme et il m'a fallu 2 jours pour comprendre. Très bon scénario et j'espère que cela aidera tous ceux qui risquent d'avoir des problèmes. Je vous remercie.
2
Cela ferait un paquet utile Ubuntu / Debian!
Petr Pudlák
Je me demandais simplement: cela serait-il encore valable pour Ubuntu 13.04? J'ai exactement besoin de cette solution, mais je ne veux pas me mêler du portable de la femme s'il s'avère que casser des choses sur des versions plus récentes.
Torben Gundtofte-Bruun
Merci pour le script. Fonctionne bien pour moi sur Ubuntu 14.04! Une amélioration serait que si, lorsque l'ordinateur portable se réveille, il pourrait vérifier s'il est branché sur le secteur. Si tel est le cas, je souhaiterais qu'il soit suspendu à nouveau au lieu d'hiberner. La restauration à partir de l'hibernation prend plus de temps et je n'ai pas vraiment besoin d'hiberner quand il est branché ...
maddentim
Merci beaucoup!!!! Ce script est magique je rêvais de !!
Yanpas
12

Pour expliquer comment cela fonctionne (cela ressemble à Windows) en des mots simples: la machine ne se réveille pas lorsque la batterie est faible pour pouvoir enregistrer l'état de la machine sur la partition de swap, elle enregistre tout immédiatement sur la partition de swap. en attente, et lorsque la batterie est épuisée, il récupère l'état en chargeant l'état à partir de la partition d'échange (comme cela se produirait si vous étiez en veille prolongée).

Autant que je sache, linux utilisera / devrait utiliser un mode veille / veille prolongée hybride au lieu du mode veille "normal" s'il sait que cela fonctionne pour votre matériel. Il est également possible que cette option soit désactivée actuellement à cause d'un trop grand nombre de bugs ou de quelque chose ...;)

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

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"
JanC
la source
1
L'apostrophe unique dans votre commande de shell pourrait être trompeuse et déroutante ... veuillez vous en échapper.
ayan4m1
1
Bah, c'est ce qui se passe lorsque vous modifiez une ligne de commande incorporée dans un autre texte, sans la considérer comme une ligne de commande ... Merci.
JanC
Pas de problème, oui, nous avons compris les différents espaces pour les deux processus.
ayan4m1
6

Vous pouvez être intéressé par s2both . Il est fourni par le paquet uswsuspdans Ubuntu 10.10. Il suspend sur le disque, mais au lieu d'arrêter le système, il le place en S3, qui est le mode d'alimentation généralement associé à l'option "Suspendre" dans Ubuntu. pm-suspend-hybrid est un autre outil censé faire la même chose.

Pour automatiser la fermeture du couvercle, consultez le guide suivant, qui vous permet d'exécuter un script arbitraire lorsqu'un événement de couvercle est intercepté:

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

Si vous possédez un ThinkPad, la page de manuel for tpctlfait référence à un argument --pm-sedation-hibernate-from-suspend-timer, ce qui semble fournir la fonctionnalité que vous recherchez. Je vous prie de ne pas essayer ceci avec du matériel autre que ThinkPad.

Pour référence, j'ai parcouru la page de manuel pour hibernate.conf ; il ne semblait pas y avoir d’options pertinentes, mais méritait peut-être une seconde lecture.

ayan4m1
la source
5

Ubuntu 16.04 - de suspendre / dormir 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, les mesures que j’ai prises pour que cela fonctionne sont les suivantes:

  1. Assurez-vous que le mode veille prolongée fonctionne comme prévu lors de l'exécution

    systemctl hibernate
    
  2. Copiez le suspend.targetfichier d' origine :

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

    Puis éditez le fichier /etc/systemd/system/suspend.targetet ajoutez la ligne:

    Requires=delayed-hibernation.service
    

    à la [Unit]section de ce fichier.

  3. Créez le fichier /etc/systemd/system/delayed-hibernation.serviceavec le contenu suivant:

[Unité]
Description = Déclenchement d'hibernation retardée
Avant = suspend.target
Conflicts = hibernate.target hybrid-suspend.target
StopWhenUnneeded = true

[Un service]
Type = coup unique
RemainAfterExit = yes
ExecStart = / usr / local / bin / delay-hibernation.sh pre suspend
ExecStop = / usr / local / bin / delay-hibernation.sh post suspend

[Installer]
WantedBy = sleep.target
  1. Créez le fichier de configuration /etc/delayed-hibernation.confdu script avec le contenu suivant:
# Fichier de configuration pour le script 'delay-hibernation.sh'

# Spécifiez le temps en secondes à passer en mode veille avant que l'ordinateur ne soit en veille prolongée
TIMEOUT = 1200 #in secondes, donne 20 minutes
  1. Créez le script qui fera réellement le travail difficile.

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

#! / bin / bash
# Nom du script: delay-hibernation.sh
# Objectif: Hibernation automatique après une période de sommeil
# Editez la variable `TIMEOUT` dans le fichier` $ hibernation_conf` pour définir le nombre de secondes de veille.

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

# Vérification du fichier de configuration
si [ ! -f $ hibernation_conf]; ensuite
    echo "Fichier de configuration manquant ('$ hibernation_conf'), abandon."
    sortie 1
Fi
hibernation_timeout = $ (grep "^ [^ #]" $ hibernation_conf | grep "TIMEOUT =" | awk -F '=' '{print $ 2}' | awk -F '#' '{print $ 1}' | tr -d '[[\ t]]')
if ["$ hibernation_timeout" = ""]; ensuite
    echo "Paramètre 'TIMEOUT' manquant dans le fichier de configuration ('$ hibernation_conf'), abandon."
    sortie 1
elif [[! "$ hibernation_timeout" = ~ ^ [0-9] + $]]; ensuite
    echo "Mauvais paramètre 'TIMEOUT' ('$ hibernation_timeout') dans le fichier de configuration ('$ hibernation_conf'), nombre de secondes attendu, abandon."
    sortie 1
Fi

# Traitement des paramètres donnés
if ["$ 2" = "suspendre"]; ensuite
    curtime = $ (date +% s)
    if ["$ 1" = "pre"]; ensuite
        if [-f $ hibernation_fail]; ensuite
            echo "Echec de l'hibernation détecté, saut de réglage du minuteur de réveil RTC."
        autre
            echo "Suspension détectée. Durée d'enregistrement, régler la minuterie RTC"
            echo "$ curtime"> $ hibernation_lock
            rtcwake -m no -s $ hibernation_timeout
        Fi
    elif ["$ 1" = "post"]; ensuite
        if [-f $ hibernation_fail]; ensuite
            rm $ hibernation_fail
        Fi
        if [-f $ hibernation_lock]; ensuite
            Sustime = $ (cat $ hibernation_lock)
            rm $ hibernation_lock
            if [$ (($ curtime - $ sustime)) -ge $ hibernation_timeout]; ensuite
                echo "La reprise automatique de la suspension a été détectée. Hibernation ..."
                systemctl hiberner
                si [$? -ne 0]; ensuite
                    echo "Echec de l'hibernation automatique. Tentative de suspension à la place."
                    touchez $ hibernation_fail
                    systemctl suspendre
                    si [$? -ne 0]; ensuite
                        echo "Échec de l'hibernation et de la suspension automatique. Rien d'autre à essayer."
                    Fi
                Fi
            autre
                echo "Une reprise manuelle de la suspension a été détectée. Effacement du minuteur RTC"
                rtcwake -m désactiver
            Fi
        autre
            echo "Le fichier '$ hibernation_lock' n'a pas été trouvé, rien à faire"
        Fi
    autre
        echo "Premier paramètre non reconnu: '$ 1', attendu 'pre' ou 'post'"
    Fi
autre
    echo "Ce script est destiné à être exécuté par systemctl delay-hibernation.service (second paramètre attendu: 'suspendre')"
Fi
  1. Rendre le script exécutable:
chmod 755 /usr/local/bin/delayed-hibernation.sh

Il m'a fallu beaucoup de temps avant d'écrire ce script à partir d'autres réponses de 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 résoudre de nombreux problèmes, tels que la mise en suspension à nouveau si le mode Veille prolongée échoue, mais ne vous réveillez pas à nouveau après l'heure prédéterminée.

  1. La dernière étape que je suppose serait de simplement exécuter

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

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

Pour consulter le journal de service, vous pouvez utiliser:

sudo systemctl status delay-hibernation.service

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

sudo journalctl -u delay-hibernation.service

Un journal normal que je reçois du service en cours d'exécution est:

mile @ mile-ThinkPad: ~ $ sudo systemctl status delay-hibernation.service 
● delay-hibernation.service - Déclenchement de l'hibernation retardée
   Chargé: chargé (/etc/systemd/system/delayed-hibernation.service; activé; préréglage du vendeur: activé)
   Actif: inactif (mort)

Jun 09 20:35:42 mile-ThinkPad systemd [1]: déclenchement d'hibernation retardée ...
Juin 09 20:35:42 mile-ThinkPad delay-hibernation.sh [2933]: Suspension détectée. Durée d'enregistrement, régler la minuterie RTC
Juin 09 20:35:42 mile-ThinkPad delay-hibernation.sh [2933]: rtcwake: en supposant que RTC utilise UTC ...
Juin 09 20:35:42 mile-ThinkPad retardé-hibernation.sh [2933]: rtcwake: réveil à l'aide de / dev / rtc0 le jeu. 9 juin à 18:55:43 2016
Juin 09 20:55:44 mile-ThinkPad systemd [1]: déclenchement du déclenchement d'hibernation retardée.
Juin 09 20:55:44 mile-ThinkPad systemd [1]: delay-hibernation.service: unité n'est plus nécessaire. Arrêt.
Juin 09 20:55:44 mile-ThinkPad systemd [1]: Arrêt du déclenchement de l'hibernation retardée ...
Juin 09 20:55:44 mile-ThinkPad delay-hibernation.sh [3093]: reprise automatique de la suspension détectée. En hibernation ...
Juin 09 20:55:44 mile-ThinkPad systemd [1]: arrêt du déclenchement de l'hibernation retardée.
mile @ mile-ThinkPad: ~ $ 

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 que cette fonctionnalité pratique fonctionne.

mihai.ile
la source
Merci pour la réponse, cela fonctionne toujours comme un charme sur Ubuntu 18.04. Je ne pouvais pas obtenir les réponses ci-dessus au travail, l'exécution /bin/systemctl hibernateretournerait toujours 1 lorsqu'elle est exécutée dans le script systemd, même si cela fonctionne très bien sur la ligne de commande.
eugenhu
4

Juste au cas où quelque chose se passerait mal pendant que pm-hibernateje préférerais mettre l'ordinateur en suspension plutôt que de le laisser fonctionner. Pour que vous puissiez utiliser:

   ...
/usr/sbin/pm-hibernate || /usr/sbin/pm-suspend
   ...
iiegn
la source
3

Voici une version mise à jour de la réponse de Derek Pressnall qui fonctionne avec systemd et inclut la suggestion d'Eliah Kagan . Il suffit de la déposer dans /usr/lib/systemd/system-sleep/delayed_hibernation.sh et de la rendre exécutable:

#!/bin/bash

hibernation_timeout=1800  #30 minutes

if [ "$2" = "suspend" ]; then
    curtime=$(date +%s)
    if [ "$1" = "pre" ]; then
        echo -e "[($curtime) $@]\nExecuting pre-suspend hook..." >> /tmp/delayed_hibernation.log
        echo "$curtime" > /var/run/delayed_hibernation.lock
        rtcwake -m no -s $hibernation_timeout
    elif [ "$1" = "post" ]; then
        echo -e "[($curtime) $@]\nExecuting post-suspend hook..." >> /tmp/delayed_hibernation.log
        sustime=$(cat /var/run/delayed_hibernation.lock)
        if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then
            echo -e "Automatic resume detected, hibernating.\n" >> /tmp/delayed_hibernation.log
            systemctl hibernate || systemctl suspend
        else
            echo -e "Manual resume detected, clearing RTC alarm.\n" >> /tmp/delayed_hibernation.log
            rtcwake -m no -s 1
        fi
        rm /var/run/delayed_hibernation.lock
    fi
fi
Niccolò Maggioni
la source
Cela fonctionnait bien pendant plusieurs mois le 15.10, mais quelque chose à propos de 16.04 l'empêche d'hiberner bien que le script continue à s'exécuter.
Sean
@Sean avez-vous essayé la solution de contournement dans ce fil ?
Niccolò Maggioni
Merci de m'avoir orienté dans la bonne direction. J'ai créé un service systemd (/etc/systemd/system/delayed-hibernation.service) qui a référencé le script ci-dessus, puis modifié /etc/systemd/system/suspend.target afin d'exiger le retardement-hibernation.service.
Sean
2

Voici ma recette (testée sur deux ordinateurs portables Ubuntu 16.04):

Mettez ce script où vous voulez (je le mets à la racine /syspend.sh) et rendez-le exécutable ( chmod +x /suspend.sh)

TIMELOG=/tmp/autohibernate.log
ALARM=$(tail -n 1 $TIMELOG)
SLEEPTIME=5000 #edit this line to change timer, e.g. 2 hours "$((2*60*60))"
if [[ $1 == "resume" ]]
then
    if [[ $(date +%s) -ge $(( $ALARM + $SLEEPTIME )) ]]
    then
        echo "hibernate triggered $(date +%H:%M:%S)">>$TIMELOG
        systemctl hibernate 2>> $TIMELOG
    else
        echo "normal wakeup $(date +%H:%M:%S)">>$TIMELOG
    fi
elif [[ $1 == "suspend" ]]
then
    echo "$(date +%s)" >> $TIMELOG
    rtcwake -m no -s $SLEEPTIME
fi

Créez ensuite la cible systemd: # touch /etc/systemd/system/suspend-to-sleep.target collez ce contenu:

#/etc/systemd/system/suspend-to-hibernate.service
[Unit]
Description=Delayed hibernation trigger
Before=suspend.target
Conflicts=hibernate.target hybrid-suspend.target
StopWhenUnneeded=true

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash /suspend.sh suspend
ExecStop=/bin/bash /suspend.sh wakeup

[Install]
WantedBy=sleep.target
RequiredBy=suspend.target

Puis activez-le # systemctl enable suspend-to-sleep.target.

J'ai eu un problème avec celui des ordinateurs portables: la fermeture du couvercle n'a pas déclenché cette cible. Cela était dû à xfce4-power-manager. Il existe deux manières de contourner ce problème. La première consiste à modifier le /etc/systemd/logind.conffichier et à le remplacer HandleLidSwitch=ignorepar HandleLidSwitch=suspend. Mais ce sera à l'échelle du système, alors je viens d'ajouter un lien symbolique à mon script# ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate

Yanpa
la source
1

Une autre solution de contournement plus courante que vous pouvez utiliser hybrid-sleep(comme le fait Mac OS). Si votre ordinateur prend en charge l'hibernation, vous pouvez utiliser cette fonctionnalité:

systemctl hybrid-sleep

Cette commande devrait suspendre et envoyer sur le disque (veille prolongée) l'ordinateur. Après un certain temps, l’ordinateur s’éteindra (il utilisera les fichiers de veille prolongée pour s’activer).

ps: Je sais que ce n'est pas exactement ce que le PO a posté, mais c'est assez proche

morhook
la source
0

N'oubliez pas de chmod + x ce fichier, rendez-le exécutable.

Il existe une autre solution sans rtcwake, en utilisant wakealarm dans / sys / class / rtc / rtc0. Utilisez du code obsolète dans pm-functions (/ usr / lib / pm-utils) après les commentaires # depuis que le noyau ne supporte pas directement ..., (car le noyau actuel (quelque chose après la version 3.6) le supporte directement). Retournez ce code et insérez la partie do_suspend () à la place de do_suspend_hybrid ().

Code obsolète (suspendre puis hiberner lorsque susp_hybrid est appelé):

# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
    check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
    then
    SUSPEND_HYBRID_MODULE="kernel"
    do_suspend_hybrid() {
    WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
    echo >"$PM_RTC/wakealarm"
    echo $WAKETIME > "$PM_RTC/wakealarm"
    if do_suspend; then
        NOW=$(cat "$PM_RTC/since_epoch")
        if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
        log "Woken by RTC alarm, hibernating."
        # if hibernate fails for any reason, go back to suspend.
        do_hibernate || do_suspend
        else
        echo > "$PM_RTC/wakealarm"
        fi
    else
        # if we cannot suspend, just try to hibernate.
        do_hibernate
    fi
    }
fi

Conseillé. Encore plus facile à utiliser uswsusp tout en maximisant les avantages de s2both, c’est-à-dire s2both lorsqu’il est suspendu. Placez le code inversé dans la partie do_suspend () du module uswsusp (/usr/lib/pm-utils/module.d).

Code inversé (suspend_hybrid lorsque la suspension est appelée):

WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
    NOW=$(cat "$PM_RTC/since_epoch")
    if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
    log "Woken by RTC alarm, hibernating."
    # if hibernate fails for any reason, go back to suspend_hybrid.
    do_hibernate || do_suspend_hybrid
    else
    echo > "$PM_RTC/wakealarm"
    fi
else
    # when do_suspend is being called, convert to suspend_hybrid.
    do_suspend_hybrid
fi      

Avec uswsusp, nous pouvons voir l’avancement de la suspension / hibernation et le processus inverse affichés en texte, même si nous pouvons l’abandonner en appuyant sur la touche retour arrière. Sans uswsusp, suspendre / hibernate semble juste disparaître de manière ennuyeuse, surtout lorsque wakealarm est déclenché et exécuter hibernate (s2disk in uswsusp). Définissez la période de sommeil avant l'hibernation à l'emplacement habituel du fichier pm-functions.

# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900  # 15 minutes
PM_RTC=/sys/class/rtc/rtc0

Voici le mod uswsusp: (rappelez-vous, ce module est appelé depuis pm-functions, donc les variables insérées sont les mêmes)

#!/bin/sh

# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
uswsusp_hooks()
{
    disablehook 99video "disabled by uswsusp"
}

# Since we disabled 99video, we need to take responsibility for proper
# quirk handling.  s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
uswsusp_get_quirks()
{
    OPTS=""
    ACPI_SLEEP=0
    for opt in $PM_CMDLINE; do
        case "${opt##--quirk-}" in # just quirks, please
            dpms-on)       ;; # no-op
            dpms-suspend)      ;; # no-op
            radeon-off)        OPTS="$OPTS --radeontool" ;;
            reset-brightness)  ;; # no-op
            s3-bios)       ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
            s3-mode)       ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
            vbe-post)      OPTS="$OPTS --vbe_post" ;;
            vbemode-restore)   OPTS="$OPTS --vbe_mode" ;;
            vbestate-restore)  OPTS="$OPTS --vbe_save" ;;
            vga-mode-3)        ;; # no-op
            save-pci)          OPTS="$OPTS --pci_save" ;;
            none)          QUIRK_NONE="true" ;;
            *) continue ;;
        esac
    done
    [ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
    # if we were told to ignore quirks, do so.
    # This is arguably not the best way to do things, but...
    [ "$QUIRK_NONE" = "true" ] && OPTS=""
}

# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
uswsusp_help()
{
    echo  # first echo makes it look nicer.
    echo "s2ram video quirk handler options:"
    echo
    echo "  --quirk-radeon-off"
    echo "  --quirk-s3-bios"
    echo "  --quirk-s3-mode"
    echo "  --quirk-vbe-post"
    echo "  --quirk-vbemode-restore"
    echo "  --quirk-vbestate-restore"
    echo "  --quirk-save-pci"
    echo "  --quirk-none"
}

# This idiom is used for all sleep methods.  Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
#
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend.  We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
    ( grep -q mem /sys/power/state || \
        ( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
    SUSPEND_MODULE="uswsusp"
    do_suspend()
    {
        WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
        echo >"$PM_RTC/wakealarm"
        echo $WAKETIME > "$PM_RTC/wakealarm"
        if do_suspend_hybrid; then
            NOW=$(cat "$PM_RTC/since_epoch")
            if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
            log "Woken by RTC alarm, hibernating."
            # if hibernate fails for any reason, go back to suspend_hybrid.
            do_hibernate || do_suspend_hybrid
            else
            echo > "$PM_RTC/wakealarm"
            fi
        else
            # when do_suspend is being called, convert to suspend_hybrid.
            do_suspend_hybrid
        fi      
    }
fi

if [ -z "$HIBERNATE_MODULE" ] && \
    [ -f /sys/power/disk ] && \
    grep -q disk /sys/power/state && \
    [ -c /dev/snapshot ] &&
    command_exists s2disk; then
    HIBERNATE_MODULE="uswsusp"
    do_hibernate()
    {
        s2disk
    }
fi

if [ -z "$SUSPEND_HYBRID_MODULE" ] && 
    grep -q mem /sys/power/state && \
    command_exists s2both && \
    check_hibernate; then
    SUSPEND_HYBRID_MODULE="uswsusp"
    do_suspend_hybrid()
    {   
        uswsusp_get_quirks
        s2both --force $OPTS 
    }
    if [ "$METHOD" = "suspend_hybrid" ]; then
        add_before_hooks uswsusp_hooks
        add_module_help uswsusp_help
    fi
fi  
marque
la source