Como ir automaticamente do Suspend para o Hibernate?

45

É possível fazer com que o Ubuntu entre no estado de hibernação do Suspend, também conhecido como "Suspender sedação"?

Por exemplo, meu laptop está configurado para entrar em suspensão quando eu fechar a tampa. Se então eu não usá-lo para o dia inteiro, a bateria fica vazia, porque mesmo no modo de suspensão o hardware ainda consome uma pequena quantidade de energia, e a bateria eventualmente descarrega. O que eu quero é poder dizer ao Ubuntu que mesmo que ele seja suspenso, ele ainda precisa entrar no Hibernate após algumas horas de inatividade.

O Windows pode fazer isso. O Ubuntu pode ser programado para entrar em Standby ou Hibernar no temporizador, mas não em ambos.

Atualização:

Eu acho que preciso ser mais específico. O que estou procurando é isto:
Quando fecho a tampa, o laptop é colocado em Suspender. Então, depois de um tempo pré-determinado (mesmo se a bateria estiver strong) se eu ainda não usá-lo, ele deve se colocar em um modo de hibernação para economizar bateria.

    
por Sergey Stadnik 10.11.2010 / 01:39

10 respostas

4

No Ubuntu 18.04 , é muito mais fácil. Em systemd está disponível um novo modo suspend-then-hibernate . Para começar a usar essa função, você precisa criar um arquivo /etc/systemd/sleep.conf com o próximo conteúdo:

[Sleep]
HibernateDelaySec=3600

Então você pode testá-lo por comando:

sudo systemctl suspend-then-hibernate

(você pode editar o HibernateDelaySec para reduzir o atraso para hibernar). Se tudo funcionar bem você pode mudar o Lid Close Action, para isso você precisa editar o arquivo /etc/systemd/logind.conf

Você precisa encontrar a opção HandleLidSwitch = , descomente-a e mude para HandleLidSwitch = suspend-then-hibernate . Então você precisa reiniciar o serviço logind (aviso! Sua sessão de usuário será reiniciada) pelo próximo comando:

sudo systemctl restart systemd-logind.service

Isso é tudo! Agora você pode usar essa função legal.

    
por 17.09.2018 / 00:11
33

A solução para isso é simples. Primeiro, após a suspensão e retomada, o programa pm-suspend executa uma série de scripts em /etc/pm/sleep.d e /usr/lib/pm-utils/sleep.d . Então, minha solução é adicionar um script que faça o seguinte:

  1. Após a suspensão, registre a hora atual e registre um evento de ativação usando o rtcwake.
  2. Ao reiniciar, verifique a hora atual em relação ao tempo gravado acima. Se tiver decorrido tempo suficiente, provavelmente acordamos devido ao evento do temporizador do rtc. Caso contrário, acordamos cedo devido a um evento do usuário (como abrir a tela do laptop).
  3. Se acordarmos devido ao temporizador do rtc, emita imediatamente um comando "pm-hibernate" para entrar em hibernação.

Aqui está um script que faz isso. Nomeie-o como 0000rtchibernate e coloque-o no diretório /etc/pm/sleep.d (o 0000 é importante, para que o script seja executado primeiro na suspensão e último no currículo).

#!/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

Espero que este código apareça neste quadro de mensagens (este é meu primeiro post aqui).

Edite o valor de tempo limite autohibernate=7200 na parte superior, para quantos segundos você durar antes de entrar em hibernação. O valor atual acima é de 2 horas. Note que o seu laptop despertará durante alguns segundos enquanto executa a função de hibernação.

Portanto, se você planeja colocar seu laptop em um caso, não suspenda, mas sim hiberne. Caso contrário, seu laptop pode superaquecer em esp. se estiver em um estojo rígido apertado (embora ele só seja ligado por alguns segundos a um minuto).

Eu tenho usado esse método nos últimos dois dias, até agora ele foi bem sucedido (e me salvou de uma bateria sem bateria nesta tarde). Aproveite.

Para outras distribuições Linux que usam systemd e versões mais recentes do Ubuntu, isso ainda funcionará se você colocar o script em /usr/lib/systemd/system-sleep em vez de /etc/pm/sleep.d . Além disso, substitua o comando /usr/sbin/pm-hibernate por systemctl hibernate .

    
por Derek Pressnall 02.04.2011 / 23:16
12

Para explicar como isso funciona (isso é semelhante ao Windows) em palavras simples: a máquina não acorda do modo de espera quando a bateria fica fraca para salvar o estado da máquina na partição de troca, salva tudo no Troque a partição imediatamente no modo de espera e, quando a bateria acabar, ela será recuperada, carregando o estado da partição swap (como faria no caso de você hibernar).

O AFAIK linux deverá / deverá usar o modo de espera / hibernação híbrida em vez do modo de espera "normal" se souber que funciona para o seu hardware. Também é possível que isso esteja desativado atualmente devido a muitos erros ou algo assim ...;)

Se você gosta de experimentar, talvez possa ver se consegue obter bons resultados com pm-suspend-hybrid .

Se o seguinte diz que você tem sorte, então, em teoria, a suspensão híbrida é suportada em seu sistema:

pm-is-supported --suspend-hybrid && echo "you're lucky"
    
por JanC 10.11.2010 / 02:14
6

Você pode estar interessado em s2both . É fornecido pelo pacote uswsusp no Ubuntu 10.10. Ele suspende para o disco, mas em vez de desligar o sistema, coloca-o no S3, que é o modo de energia normalmente associado à opção "Suspender" no Ubuntu. pm-suspend-hybrid é outra ferramenta que pretende fazer o mesmo coisa.

Para automatizar o fechamento da tampa, dê uma olhada no guia a seguir, que permite executar um script arbitrário quando um evento de tampa for capturado:

link

Se você tiver um ThinkPad, a página de manual de tpctl faz referência a um argumento, --pm-sedation-hibernate-from-suspend-timer , que parece fornecer o recurso que você está procurando. Eu o aconselharia a não tentar isso em hardware que não seja do ThinkPad.

Para referência, procurei na manpage hibernate.conf ; não parece ter nenhuma opção relevante, mas pode valer a pena uma segunda leitura.

    
por ayan4m1 10.11.2010 / 02:21
5

Ubuntu 16.04 - de suspender / dormir em hibernação após um tempo pré-determinado

Parece que no Ubuntu 16.04 as coisas são um pouco diferentes, então os passos que tomei para fazer o trabalho foram:

  1. Certifique-se de que o modo de hibernação está funcionando como esperado ao executar

    systemctl hibernate
    
  2. Copie o arquivo suspend.target original:

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

    Em seguida, edite o arquivo /etc/systemd/system/suspend.target e adicione a linha:

    Requires=delayed-hibernation.service
    

    para a seção [Unit] desse arquivo.

  3. Crie o arquivo /etc/systemd/system/delayed-hibernation.service com o seguinte conteúdo:

[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
  1. Crie o arquivo de configuração /etc/delayed-hibernation.conf para o script com o seguinte conteúdo:
# 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
  1. Crie o script que realmente fará o trabalho pesado.

    Crie o arquivo /usr/local/bin/delayed-hibernation.sh com o conteúdo:

#!/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
  1. Torne o script executável:
chmod 755 /usr/local/bin/delayed-hibernation.sh

Demorei bastante até escrever este script baseado em outras respostas neste tópico, coisas que encontrei na internet como link

Minha versão do script tenta lidar com muitos problemas, como entrar em suspensão novamente se o hibernate não tiver sido bem-sucedido, mas não acorde novamente depois do tempo predeterminado várias vezes.

  1. O passo final, suponho, seria apenas executar

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

    para garantir que novos serviços / configurações estejam sendo usados.

Para verificar o log de serviço, você pode usar:

sudo systemctl status delayed-hibernation.service

ou para um log completo do uso do serviço:

sudo journalctl -u delayed-hibernation.service

Um log normal que recebo do serviço em execução é:

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:~$ 

Então, é isso, espero que realmente ajude alguém desde que passei dias tentando descobrir a combinação certa de configurações e versões de script para fazer esse recurso útil funcionar.

    
por mihai.ile 10.06.2016 / 19:41
4

Apenas no caso de algo dar errado durante pm-hibernate eu prefiro colocar o computador para suspender do que deixá-lo rodar. Então você pode usar:

   ...
/usr/sbin/pm-hibernate || /usr/sbin/pm-suspend
   ...
    
por iiegn 28.02.2013 / 22:24
3

Aqui está uma versão atualizada da resposta de Derek Pressnall que funciona com o systemd e inclui sugestão de Eliah Kagan , simplesmente solte-o em /usr/lib/systemd/system-sleep/delayed_hibernation.sh e torne-o executável:

#!/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
    
por Niccolò Maggioni 17.08.2015 / 23:13
2

Aqui está minha receita (testei em dois notebooks Ubuntu 16.04):

Coloque este script onde quiser (eu coloquei na raiz, /syspend.sh ) e torne-o executável ( 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

Em seguida, crie um destino systemd: %código% Cole este conteúdo:

#/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

Em seguida, ative # touch /etc/systemd/system/suspend-to-sleep.target .

Eu enfrentei um problema no caderno: o fechamento da tampa não acionou esse alvo. Isto foi devido ao xfce4-power-manager. Há duas maneiras de solucionar esse problema. A primeira é editar o arquivo # systemctl enable suspend-to-sleep.target e substituir /etc/systemd/logind.conf por HandleLidSwitch=ignore . Mas será em todo o sistema, então eu adicionei o link simbólico ao meu script HandleLidSwitch=suspend

    
por yanpas 04.10.2016 / 21:39
1

Outra solução mais comum é usar hybrid-sleep (como o Mac OS faz). Se o seu computador suportar a hibernação, você poderá usar este recurso:

systemctl hybrid-sleep

Esse comando deve suspender e enviar para o disco (hibernar) o computador. Após algum tempo, o computador será desligado (ao ligar, ele usará os arquivos de hibernação para ativar).

p.s .: Eu sei que não é exatamente o que o OP postou, mas está bem próximo

    
por morhook 10.07.2017 / 12:58
0

Não esqueça de chmod + x esse arquivo, torne-o executável.

Existe outra solução sem o rtcwake, usando o wakealarm em / sys / class / rtc / rtc0. Use código obsoleto em pm-functions (/ usr / lib / pm-utils) após os comentários #desde que o kernel não suporta diretamente ... (porque o kernel atual (após 3.6 algo) suporta diretamente). Reverta o código e coloque a parte do_suspend () em vez de do_suspend_hybrid ().

Código obsoleto (suspender e depois hibernar quando o suspend_hybrid for chamado):

# 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

Recomendado. Ainda mais fácil de usar uswsusp, enquanto o mesmo tempo maximizar o benefício de s2both, ou seja, s2both quando suspender. Coloque o código revertido na parte do_suspend () do módulo uswsusp (/usr/lib/pm-utils/module.d).

Código revertido (suspend_hybrid quando a suspensão é chamada):

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      

Com uswsusp, podemos ver o progresso de suspend / hibernate e o processo reverso exibido no texto, até mesmo podemos abortá-lo pressionando backspace. Sem uswsusp, suspender / hibernar apenas aparecer - desaparecer irritantemente, especialmente quando o wakealarm é acionado e executar o hibernate (s2disk no uswsusp). Defina o período de suspensão antes do modo de hibernação no local habitual no arquivo pm-functions.

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

Aqui está o mod uswsusp: (lembre-se, este módulo é chamado de pm-functions, então as variáveis inseridas são as mesmas)

#!/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  
    
por mark 31.10.2013 / 14:04