43 votes

Comment puis-je utiliser pm-suspend-hybrid par défaut au lieu de pm-suspend?

Je voudrais utiliser la méthode de suspension hybride plutôt que la suspension lorsque je ferme le couvercle ou sélectionne "Suspendre" dans le menu.

Je peux imaginer modifier le script pm-suspend pour le faire automatiquement, mais il pourrait y avoir un moyen plus maintenable / plus facile.

44voto

Arnold Zokas Points 4086

Sommeil hybride indirect

Ceci est la méthode plus ancienne : suspendre d'abord puis se réveiller pour hiberner après un délai (15 minutes par défaut). Utilisez ceci avec un noyau Linux antérieur à 3.6, ou si vous aimez qu'il n'utilise plus d'énergie après 15 minutes.

Ajoutez le fichier /etc/pm/config.d/00-use-suspend-hybrid:

# Utiliser toujours suspend_hybrid au lieu de suspend
if [ "$METHOD" = "suspend" ]; then
  METHOD=suspend_hybrid
fi
# Le délai après lequel l'hibernation est déclenchée (par défaut : 900 secondes, 15 minutes) :
PM_HIBERNATE_DELAY=900

Vous voudrez peut-être vous assurer que la méthode hybride est prise en charge sur votre système via le code suivant. Si cela dit "0", cela devrait fonctionner :

sudo pm-is-supported --suspend-hybrid && echo $?

Suspension hybride réelle avec Linux 3.6+

Si vous avez un noyau Linux 3.6, vous pouvez utiliser ce qui suit, qui suspendra à la fois sur le disque et dans la RAM dès le début.

Ajoutez le fichier /etc/pm/config.d/00-use-suspend-hybrid:

# SOLUTION DE CONTOURNEMENT : définir d'abord toujours le mode d'hibernation par défaut (mode normal)
# (pas nécessaire si vous avez le correctif mentionné par Rohan ci-dessous (http://askubuntu.com/a/344879/169))
HIBERNATE_MODE=plateforme

# Utiliser toujours l'hibernation au lieu de la suspension, mais avec "suspension à la fois"
if [ "$METHOD" = "suspend" ]; then
  METHOD=hibernate
  HIBERNATE_MODE=suspend
fi

# Assurez-vous d'utiliser la méthode du noyau, au cas où uswsusp est installé etc.
SLEEP_MODULE=kernel

Cela écrira toujours l'image sur le disque et puis suspendra dans la RAM, ayant pour avantage que la reprise sera toujours rapide (tant que la batterie ne s'épuise pas) et que la machine ne se réveillera pas pendant un court laps de temps (après PM_HIBERNATE_DELAY) pour hiberner vraiment.

L'inconvénient est que le processus prend plus de temps (car il hiberne toujours sur le disque), et que votre batterie pourrait s'épuiser à long terme (par exemple, après 12 heures).

38voto

user68186 Points 25067

Ubuntu 18.04 une option chronométrée

Dans Ubuntu 18.04, il existe une nouvelle option chronométrée. Dans systemd, un nouveau mode est disponible suspend-then-hibernate. Cela commencera par le mode veille puis passera au mode hibernation après un certain temps.

Dans le mode hybrid-sleep, la partie hibernation devient effective uniquement lorsque la batterie est critique et que le système s'éteint.

Pour commencer à utiliser cette fonction, vous devez créer un fichier /etc/systemd/sleep.conf avec le contenu suivant :

[Sleep]
HibernateDelaySec=3600

Cela passera de la veille à l'hibernation après 1 heure de veille. Vous pouvez modifier HibernateDelaySec pour changer le délai jusqu'à l'hibernation.

Tout d'abord, testez si la suspension-puis-hibernation fonctionne avec systemd

Ouvrez un terminal en appuyant sur Ctrl+Alt+T et entrez :

sudo systemctl suspend-then-hibernate

Si cela fonctionne, rendez-le permanent.

  • Le suivant fonctionne lorsque je ferme le couvercle.

Ouvrez le fichier /etc/systemd/logind.conf à l'aide de votre éditeur préféré. Vous devrez invoquer votre pouvoir administratif avec sudo, gksudo ou pkexec pour éditer ce fichier.

Recherchez les deux lignes :

#HandleSuspendKey=suspend
#HandleLidSwitch=suspend

Remarquez, Ces lignes sont commentées avec # devant elles. La suspend est l'action par défaut. Supprimez le # et changez suspend en suspend-then-hibernate dans ces deux lignes afin qu'elles ressemblent à ceci :

HandleSuspendKey=suspend-then-hibernate
HandleLidSwitch=suspend-then-hibernate

Enregistrez le fichier. Déconnectez-vous puis reconnectez-vous ou redémarrez le service logind en utilisant la commande :

systemctl restart systemd-logind.service

attention ! votre session utilisateur sera redémarrée

Source : Lid Closed Suspend then Hibernate

Ubuntu 16.04 et supérieurs

La solution de blueyed pour une véritable mise en veille hybride avec Linux 3.6+ n'a pas fonctionné pour moi. Je suspecte que cela est dû au fait qu'Ubuntu 16.04 utilise systemd et ne utilise pas le fichier /etc/pm/config.d/00-use-suspend-hybrid.

Tout d'abord, testez si l'hibernation et la mise en veille hybride fonctionnent avec systemd

Ouvrez un terminal en appuyant sur Ctrl+Alt+T et entrez :

sudo systemctl hibernate

Cela devrait mettre votre ordinateur en hibernation. Pour essayer la mise en veille hybride, entrez :

sudo systemctl hybrid-sleep

Si cela fonctionne, rendez-le permanent.

  • Le suivant fonctionne lorsque je ferme le couvercle.

Ouvrez le fichier /etc/systemd/logind.conf à l'aide de votre éditeur préféré. Vous devrez invoquer votre pouvoir administratif avec sudo, gksudo ou pkexec pour éditer ce fichier.

Recherchez les deux lignes :

#HandleSuspendKey=suspend
#HandleLidSwitch=suspend

Remarquez, Ces lignes sont commentées avec # devant elles. La suspend est l'action par défaut. Supprimez le # et changez suspend en hybrid-sleep dans ces deux lignes afin qu'elles ressemblent à ceci :

HandleSuspendKey=hybrid-sleep
HandleLidSwitch=hybrid-sleep

Enregistrez le fichier. Déconnectez-vous puis reconnectez-vous.

Remarque :

  • Autre que suspend ou hybrid-sleep, il y a une troisième option, hibernate.
  • Mon ordinateur portable n'a pas de bouton de mise en veille physique. Ainsi, je n'ai pas pu le tester.
  • En cliquant sur Suspendre dans le menu de la cog, l'ordinateur passe en mise en veille normale et non en mise en veille hybride.

Source : https://superuser.com/questions/719447/how-to-use-systemd-hybrid-sleep-instead-of-suspend-under-gnome-in-linux

J'espère que cela vous aidera

4voto

bo what Points 51

En 12.04, j'ai remarqué que lorsque l'hibernation est déclenchée (en utilisant PM_HIBERNATE_DELAY=XX), les scripts shell de reprise/sortie du sommeil ne réinitialisent pas la variable de recordfail de grub. Par conséquent, grub ne démarre pas automatiquement.

Le délai est réglé sur -1 et il attend la sélection de l'utilisateur. Je suppose que cela nécessite une certaine édition des scripts dans /etc/pm/sleep.d/10_grub-common. Je suis novice donc je n'ai pas osé essayer de trouver le changement exact malheureusement.

3voto

Rohan Dhruva Points 460

Cette question revient assez fréquemment sur Google, au point que je pense qu'il vaut la peine d'être remontée. La méthode décrite ici n'est (à mon avis) pas de la mise en veille hybride. C'est plutôt une "hibernation après X minutes en veille". La véritable mise en veille hybride enregistre les données de votre RAM sur le disque avant de passer en mode basse consommation (mode veille). Bien que cela prenne plus de temps, la reprise est instantanée tant que la batterie de la machine est suffisante, sinon elle reprend du disque dur. Ce comportement est ce que la plupart des gens connaissent sous le nom de veille hybride, et c'est celui utilisé par défaut dans les nouveaux ordinateurs portables Windows et Mac.

Voici comment activer la vraie mise en veille hybride :

  • Suivez la première partie de la réponse principale. Cela remplace l'appel "suspend" par un appel à "suspend_hybrid" dans pm-utils.

    % cat /etc/pm/config.d/00-use-suspend-hybrid
    # Toujours utiliser suspend\_hybrid au lieu de suspend
    if \[ "$METHOD" = "suspend" \]; then
        METHOD=suspend\_hybrid
    fi
  • Faites une sauvegarde de /usr/lib/pm-utils/pm-functions

  • Téléchargez le patch à partir d'ici : https://bugs.freedesktop.org/attachment.cgi?id=68712

    • Ce patch active la mise en veille hybride si disponible (c'est-à-dire sur les noyaux 3.6+)
  • Appliquez-le à l'aide de 'patch -p0' ou fusionnez-le manuellement s'il échoue

Cette méthode fonctionne pour moi sur mon Sony Vaio SVS.

PS : Je reproduis ici le patch au cas où le fichier serait supprimé à l'avenir :

diff --git a/pm/pm-functions.in b/pm/pm-functions.in
--- a/pm/pm-functions.in
+++ b/pm/pm-functions.in
@@ -316,8 +316,28 @@ if \[ -z "$HIBERNATE\_MODULE" \] && \\
    {
        \[ -n "${HIBERNATE\_MODE}" \] && \\
        grep -qw "${HIBERNATE\_MODE}" /sys/power/disk && \\
+       HIBERNATE\_MODE\_SAVE=$(cat /sys/power/disk) && \\
+       HIBERNATE\_MODE\_SAVE="${HIBERNATE\_MODE\_SAVE##\*\[}" && \\
+       HIBERNATE\_MODE\_SAVE="${HIBERNATE\_MODE\_SAVE%%\]\*}" && \\
        echo -n "${HIBERNATE\_MODE}" > /sys/power/disk
        echo -n "disk" > /sys/power/state
+       RET=$?
+       echo -n "$HIBERNATE\_MODE\_SAVE" > /sys/power/disk
+       return "$RET"
+   }
+fi
+
+# pour les noyaux qui prennent en charge la mise en veille des deux modes (c'est-à-dire la mise en veille hybride)
+# depuis le noyau 3.6
+if \[ -z "$SUSPEND\_HYBRID\_MODULE" \] && \\
+   \[ -f /sys/power/disk \] && \\
+   grep -q disk /sys/power/state && \\
+   grep -q suspend /sys/power/disk; then
+   SUSPEND\_HYBRID\_MODULE="kernel"
+   do\_suspend\_hybrid()
+   {
+       HIBERNATE\_MODE="suspend"
+       do\_hibernate
    }
 fi

Sources :

1voto

mark Points 19

Il existe une autre solution sans ajouter de fichier dans config.d, en utilisant simplement wakealarm dans /sys/class/rtc/rtc0. Utilisez le code obsolète dans pm-functions (/usr/lib/pm-utils) après les commentaires #since the kernel does not directly support ... ('car le noyau actuel ne le prend pas en charge directement après 3.6 quelque chose). Revenez sur ce code et placez-le dans la partie do_suspend() au lieu de do_suspend_hybrid(), et utilisez le correctif pour pm-functions (jusqu'à ce qu'ils le corrigent).

Code obsolète (suspendre puis hiberner lorsque suspend_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

Recommandé. Encore plus facile d'utiliser uswsusp tout en maximisant l'avantage de s2both, c'est-à-dire s2both lorsque suspendu. Mettez le code inversé dans la partie do_suspend() du module uswsusp (/usr/lib/pm-utils/module.d).

Code inversé (suspend_hybrid lorsque suspend est appelé) :

        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 la progression de la mise en veille/hibernation et le processus inverse affiché en texte, même nous pouvons l'annuler en appuyant sur la touche retour arrière. Sans uswsusp, la mise en veille/hibernation apparaît-disparaît de manière agaçante, surtout lorsque wakealarm est déclenché et exécute l'hibernation (s2disk dans uswsusp). Définissez la période de veille avant l'hibernation à l'endroit habituel dans le fichier pm-functions.

# variables pour gérer la prise en charge de l'hibernation après la mise en veille
PM_HIBERNATE_DELAY=900  # 15 minutes
PM_RTC=/sys/class/rtc/rtc0

Voici le module uswsusp : (n'oubliez pas, ce module est appelé depuis pm-functions donc les variables insérées sont les mêmes)

#!/bin/sh

# désactiver le traitement de 90chvt et 99video.
# s2ram et s2disk gèrent toutes ces choses en interne.
uswsusp_hooks()
{
    disablehook 99video "désactivé par uswsusp"
}

# Étant donné que nous avons désactivé 99video, nous devons prendre en charge le traitement des particularités.
# s2ram gère toutes les particularités vidéo courantes en interne,
# donc tout ce que nous avons à faire est de traduire les options standard du HAL en options s2ram.
uswsusp_get_quirks()
{
    OPTS=""
    ACPI_SLEEP=0
    for opt in $PM_CMDLINE; do
        case "${opt##--quirk-}" in # juste les particularités, s'il vous plaît
            dpms-on)       ;; # ne rien faire
            dpms-suspend)      ;; # ne rien faire
            radeon-off)        OPTS="$OPTS --radeontool" ;;
            reset-brightness)  ;; # ne rien faire
            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)        ;; # ne rien faire
            save-pci)          OPTS="$OPTS --pci_save" ;;
            none)          QUIRK_NONE="true" ;;
            *) continue ;;
        esac
    done
    [ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
    # si on nous dit d'ignorer les particularités, faisons-le.
    # C'est discutablement pas la meilleure façon de faire les choses, mais...
    [ "$QUIRK_NONE" = "true" ] && OPTS=""
}

# Étant donné que nous avons désactivé 99video, nous devons également gérer l'affichage
# des informations d'aide pour les particularités que nous gérons.
uswsusp_help()
{
    echo  # le premier echo rend le tout plus lisible.
    echo "options du gestionnaire de particularités vidéo s2ram :"
    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"
}

# Cet idiome est utilisé pour toutes les méthodes de mise en veille. Déclarez uniquement la méthode réelle si :
# 1: un autre module de mise en veille ne l'a pas déjà fait, et
# 2: cette méthode de mise en veille peut réellement fonctionner sur ce système.
#
# Pour suspendre, si SUSPEND_MODULE est défini alors quelque chose d'autre a déjà
# implémenté do_suspend. On pourrait simplement vérifier si do_suspend a
# déjà été déclaré en utilisant command_exists, mais l'utilisation d'une variable
# d'environnement dédiée facilite le débogage lorsque l'on doit savoir quel module de mise en veille
# a finalement revendiqué la propriété d'une méthode de mise en veille donnée.
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 "Réveillé par l'alarme RTC, hibernation."
            # si l'hibernation échoue pour une raison quelconque, revenir à la mise en veille hybride.
            do_hibernate || do_suspend_hybrid
            else
            echo > "$PM_RTC/wakealarm"
            fi
        else
            # lorsque do_suspend est appelé, convertir en mise en veille hybride.
            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

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