如何自动从挂起进入休眠状态?


53

是否可以使Ubuntu从Suspend(也称为“ Suspend Sedation”)进入休眠状态?

我要寻找的是:
当我合上盖子时,笔记本电脑被放入Suspend。然后,在预定的时间后(即使电池变强),如果我仍然不使用它,则应将其置于休眠状态以节省电池电量。

例如,我的笔记本电脑设置为在我关闭机盖后进入“挂起”状态。如果那样的话我一整天都不用,则电池电量会耗尽,因为即使在挂起模式下,硬件仍会消耗少量电量,并且电池最终会放电。我想要的是能够告诉Ubuntu,即使它已被挂起,经过几个小时的不活动之后,它仍需要进入Hibernate。

Windows可以做到这一点。可以将Ubuntu编程为按时进入待机休眠状态,但不能同时进入两者。


在我的研究中,我发现了相同的Linux Mint线程,但是“ Suspend Sedation”不是Microsoft对该功能的正式名词,据我所知,它是由提到它的Linux Mint论坛用户发明的。
ayan4m1 2010年

该功能有更好的名称吗?
谢尔盖·斯塔德尼克

据我所知,该功能没有通用名称。某些Linux Mint论坛用户使用了“ Hybridsuspend”,“悬浮镇静”是一个Linux Mint论坛用户使用的,并且我之前听说过“ hibernate andsuspend”是指该过程。微软正式将其称为“混合睡眠”,至少适用于Windows 7。
ayan4m1 2010年

2
@ ayan4m1我意识到这是一个老问题,但我认为澄清这一点很重要。混合睡眠与“睡眠并在指定时间后进入休眠状态”不同。断电时,混合动力睡眠会因电池电量耗尽而进入休眠状态。OP所描述的行为不需要启用混合睡眠。
保罗

Answers:


20

Ubuntu 18.04中,它要容易得多。在systemd中可以使用新模式suspend-then-hibernate。要开始使用此功能,您需要使用以下内容创建文件/etc/systemd/sleep.conf

[Sleep]
HibernateDelaySec=3600

然后您可以通过命令对其进行测试:

sudo systemctl suspend-then-hibernate

您可以进行编辑HibernateDelaySec以减少休眠时间。


如果一切正常,您可以更改盖子关闭操作,为此,您需要编辑文件/etc/systemd/logind.conf

您需要找到选项HandleLidSwitch=,取消注释并更改为HandleLidSwitch=suspend-then-hibernate。然后,您需要通过以下命令重新启动systemd-logind服务(警告!您的用户会话将重新启动):

sudo systemctl restart systemd-logind.service

就这样!现在,您可以使用此功能了。


这是现场。在Pop!_OS 18.10(又名Ubuntu 18.10)上使用它。
eduncan911

辉煌的谢谢!sleep.conf是否也会以某种方式影响休眠模式,还是只影响suspend-then-hibernate?
user2428107


35

解决方案很简单。首先,在暂停和恢复后,pm-suspend程序在/etc/pm/sleep.d和中执行一系列脚本/usr/lib/pm-utils/sleep.d。所以我的解决方案是添加一个执行以下操作的脚本:

  1. 挂起时,记录当前时间并使用rtcwake注册唤醒事件。
  2. 恢复后,从上方检查当前时间与记录的时间。如果经过了足够的时间,那么我们可能会由于rtc计时器事件而醒来。否则,由于用户事件(例如打开笔记本电脑屏幕),我们会提早醒来。
  3. 如果由于rtc计时器而醒来,请立即发出“ pm-hibernate”命令进入休眠状态。

这是执行此操作的脚本。对其进行命名并将其0000rtchibernate放置在/etc/pm/sleep.d目录中(0000很重要,因此脚本在挂起时首先执行,在恢复时最后执行)。

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

希望这段代码可以在此留言板上找到(这是我的第一篇文章)。

编辑autohibernate=7200顶部的超时值,以使您进入休眠状态之前要休眠的秒数。上面的当前值为2小时。请注意,您的笔记本电脑在执行休眠功能时会在此时唤醒几秒钟。

因此,如果您打算将笔记本电脑放入盒中,请不要暂停,而要使其休眠。否则您的笔记本电脑可能会过热,特别是。如果它装在紧身的滑盖盒中(尽管只能打开几秒钟到一分钟)。

在过去的几天中,我一直在使用这种方法,到目前为止,它已经成功了(并让我免于今天下午没电了)。请享用。

对于使用systemd更高版本Ubuntu的其他Linux发行版,如果您将脚本放置在/usr/lib/systemd/system-sleep而不是中,则该版本仍然可以使用/etc/pm/sleep.d。另外,将/usr/sbin/pm-hibernate命令替换为systemctl hibernate


它在这里有效,但是只有在我将文件修改为将X添加到每个人之后才起作用。我是一个新手,花了我两天的时间才弄清楚。非常好的脚本,希望这对可能遇到问题的人有所帮助。谢谢。

2
这将成为有用的Ubuntu / Debian软件包!
PetrPudlák'12

只是想知道:这对于Ubuntu 13.04仍然有效吗?我完全需要这种解决方案,但是如果发现在较新的版本上有问题,我不希望与妻子的笔记本电脑混为一谈。
Torben Gundtofte-Bruun

感谢您的脚本。在Ubuntu 14.04上对我来说工作正常!一种改进是,当笔记本电脑醒来进入休眠状态时,它可以检查是否已将其插入交流电源。如果是这样,我希望它再次暂停而不是休眠。从休眠状态恢复需要更长的时间,插入
电源

非常感谢!!!!这个脚本是我梦of以求的魔法!
yanpas 2015年

12

用简单的话来解释它是如何工作的(类似于Windows):当电池电量不足以将机器状态保存到交换分区时,计算机不会从待机状态唤醒,而是将所有内容立即保存到交换分区在待机状态下,当电池用尽时,它将通过从交换分区加载状态来恢复电池状态(就像在休眠状态下那样)。

如果AFAIK Linux知道适用于您的硬件,则将/应该使用混合备用/休眠而不是“普通”备用。由于有太多的错误或其他原因,目前有可能禁用此功能。

如果您喜欢实验,也许您可​​以看看pm-suspend-hybrid是否可以获得任何良好的结果。

如果以下内容表示您很幸运,那么理论上系统将支持混合暂停:

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

1
您的shell命令中的单撇号可能会引起误解和混乱,请逃避它。
ayan4m1 2010年

1
ah,这就是您编辑嵌入在其他文本中的命令行时发生的情况,而没有将其视为命令行...感谢和固定。
2010年

没问题,是的,您了解这两个过程的不同顶空。
ayan4m1 2010年

6

您可能对s2both感兴趣。它由uswsuspUbuntu 10.10中的软件包提供。它挂在磁盘上,但不是关闭系统,而是将其放在S3中,这是电源模式,通常与Ubuntu中的“ Suspend”选项相关。pm-suspend-hybrid是另一个声称可以做相同事情的工具。

要自动关闭盖子,请查看以下指南,该指南使您可以在捕获盖子事件时运行任意脚本:

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

如果您碰巧有ThinkPad,则手册页中tpctl会引用参数,该参数--pm-sedation-hibernate-from-suspend-timer似乎提供了您要查找的功能。我警告您不要在非ThinkPad硬件上尝试此操作。

作为参考,我浏览了hibernate.conf的联机帮助页;它似乎没有任何相关选项,但可能值得二读。


5

Ubuntu 16.04-在预定时间后从暂停/睡眠状态进入休眠状态

似乎在Ubuntu 16.04上有些不同,所以我采取了一些措施使其工作:

  1. 确保休眠运行时按预期运行

    systemctl hibernate
    
  2. 复制原始suspend.target文件:

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

    然后编辑文件/etc/systemd/system/suspend.target并添加以下行:

    Requires=delayed-hibernation.service
    

    到该[Unit]文件的部分。

  3. 创建/etc/systemd/system/delayed-hibernation.service具有以下内容的文件:

[单元]
描述=延迟休眠触发器
之前= suspend.target
Conflicts = hibernate.target hybrid-suspend.target
StopWhenUnneeded = true

[服务]
类型=单发
RemainAfterExit =是
ExecStart = / usr / local / bin / delayed-hibernation.sh预先挂起
ExecStop = / usr / local / bin / delayed-hibernation.sh挂起后

[安装]
WantedBy = sleep.target
  1. /etc/delayed-hibernation.conf使用以下内容为脚本创建配置文件:
#'delayed-hibernation.sh'脚本的配置文件

#指定计算机进入休眠模式之前要花费的时间(以秒为单位)
超时= 1200 #in秒,给出20分钟
  1. 创建实际将完成艰苦工作的脚本。

    创建/usr/local/bin/delayed-hibernation.sh内容如下的文件:

#!/ bin / bash
#脚本名称:delay-hibernation.sh
#目的:一段时间睡眠后自动进入休眠状态
#在`$ hibernation_conf`文件中编辑`TIMEOUT`变量以设置睡眠秒数。

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

#检查配置文件
如果[!-f $ hibernation_conf]; 然后
    echo“缺少配置文件('$ hibernation_conf'),正在中止。”
    1号出口
科幻
hibernation_timeout = $(grep“ ^ [^#]” $ hibernation_conf | grep“ TIMEOUT =” | awk -F'=''{print $ 2}'| awk -F'#''{print $ 1}'| tr -d '[[\ t]]')
如果[“ $ hibernation_timeout” =“”]; 然后
    “在配置文件('$ hibernation_conf')中缺少'TIMEOUT'参数,正在中止。
    1号出口
小精灵[[!“ $ hibernation_timeout” =〜^ [0-9] + $]]; 然后
    “ echo”配置文件('$ hibernation_conf')中错误的'TIMEOUT'参数('$ hibernation_timeout'),预期的秒数,正在中止。
    1号出口
科幻

#处理给定参数
如果[“ $ 2” =“暂停”]; 然后
    curtime = $(日期+%s)
    如果[“ $ 1” =“ pre”]; 然后
        如果[-f $ hibernation_fail]; 然后
            echo“检测到休眠失败,跳过设置RTC唤醒计时器。”
        其他
            回声“检测到挂起。录制时间,设置RTC计时器”
            echo“ $ curtime”> $ hibernation_lock
            rtcwake -m no -s $ hibernation_timeout
        科幻
    elif [“ $ 1” =“ post”]; 然后
        如果[-f $ hibernation_fail]; 然后
            rm $ hibernation_fail
        科幻
        如果[-f $ hibernation_lock]; 然后
            sustime = $(cat $ hibernation_lock)
            rm $ hibernation_lock
            如果[$(($ curtime-$ sustime))-ge $ hibernation_timeout]; 然后
                echo“检测到从挂起自动恢复。正在休眠...”
                systemctl休眠
                如果[$?-ne 0]; 然后
                    echo“自动休眠失败。尝试暂停。”
                    触摸$ hibernation_fail
                    systemctl暂停
                    如果[$?-ne 0]; 然后
                        “自动休眠和挂起故障转移失败。没有其他尝试。
                    科幻
                科幻
            其他
                echo“检测到从暂停中手动恢复。清除RTC计时器”
                rtcwake -m禁用
            科幻
        其他
            回声“找不到文件'$ hibernation_lock',无所事事”
        科幻
    其他
        回声“无法识别的第一个参数:'$ 1',预期为'pre'或'post'”
    科幻
其他
    echo“此脚本旨在由systemctl delay-hibernation.service运行(预期的第二个参数:'suspend')”
科幻
  1. 使脚本可执行:
chmod 755 /usr/local/bin/delayed-hibernation.sh

我花了很多时间才根据该线程中的其他答复编写了此脚本,我在互联网上找到的东西如https://bbs.archlinux.org/viewtopic.php?pid=1554259

我的脚本版本尝试处理许多问题,例如,如果休眠不成功,则再次进入挂起状态,但是在预定的时间后一遍又一遍不唤醒。

  1. 我认为最后一步就是执行

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

    确保使用新的服务/配置。

要检查服务日志,可以使用:

sudo systemctl status延迟休眠服务

或完整的服务使用日志:

sudo journalctl -u延迟休眠服务

我从运行的服务中获得的普通日志是:

mile @ mile-ThinkPad:〜$ sudo systemctl状态延迟-休眠。服务 
●延迟休眠服务-延迟休眠触发
   已加载:已加载(/etc/systemd/system/delayed-hibernation.service;已启用;供应商预设:已启用)
   有效:无效(无效)

Jun 09 20:35:42 mile-ThinkPad systemd [1]:启动延迟的休眠触发...
Jun 09 20:35:42 mile-ThinkPad delay-hibernation.sh [2933]:检测到挂起。记录时间,设置RTC计时器
Jun 09 20:35:42 mile-ThinkPad delay-hibernation.sh [2933]:rtcwake:假设RTC使用UTC ...
Jun 09 20:35:42 mile-ThinkPad delay-hibernation.sh [2933]:rtcwake:使用/ dev / rtc0在2016年6月9日星期四进行唤醒
Jun 09 20:55:44 mile-ThinkPad systemd [1]:启动了延迟的休眠触发。
Jun 09 20:55:44 mile-ThinkPad systemd [1]:延迟休眠。服务:不再需要该装置。停下来
Jun 09 20:55:44 mile-ThinkPad systemd [1]:正在停止延迟的休眠触发...
Jun 09 20:55:44 mile-ThinkPad delay-hibernation.sh [3093]:检测到从挂起自动恢复。冬眠中...
Jun 09 20:55:44 mile-ThinkPad systemd [1]:已停止延迟的休眠触发。
mile @ mile-ThinkPad:〜$ 

就是这样,我希望这确实对某人有帮助,因为我花了几天的时间来弄清楚配置和脚本版本的正确组合,以使此便捷功能正常工作。


感谢您的回答,这在Ubuntu 18.04上仍然像魅力一样起作用。我无法获得上述答案/bin/systemctl hibernate,即使在命令行上运行正常,执行在systemd脚本中运行时始终返回1。
eugenhu

4

以防万一在pm-hibernate我出现问题的时候我宁愿让计算机挂起而不是让它运行。因此,您可以使用:

   ...
/usr/sbin/pm-hibernate || /usr/sbin/pm-suspend
   ...

3

这是与systemd一起使用的Derek Pressnall答案的更新版本,其中包括Eliah Kagan的建议,只需将其放在/usr/lib/systemd/system-sleep/delayed_hibernation.sh中并使其可执行即可:

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

在15.10上,它运行了好几个月,但是即使脚本仍在运行,大约16.04的设置也可以使其休眠。
肖恩

@Sean您是否尝试过此线程中的解决方法?
尼可罗马基马焦尼

感谢您指出正确的方向。我创建了一个系统服务(/etc/systemd/system/delayed-hibernation.service),该服务引用了上面的脚本,然后修改了/etc/systemd/system/suspend.target来要求delay-hibernation.service。
肖恩

2

这是我的食谱(在两台笔记本电脑Ubuntu 16.04上进行了测试):

将此脚本放到您喜欢的位置(我放到根目录下/syspend.sh)并使其可执行(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

然后创建systemd目标: # touch /etc/systemd/system/suspend-to-sleep.target 粘贴以下内容:

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

然后启用它# systemctl enable suspend-to-sleep.target

我在一个笔记本电脑上遇到了一个问题:合上盖子并没有触发这个目标。这是由于xfce4-power-manager。有两种方法可以解决此问题。第一个是编辑/etc/systemd/logind.conf文件并替换HandleLidSwitch=ignoreHandleLidSwitch=suspend。但这将是系统范围的,因此我只在脚本中添加了符号链接# ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate


1

您可以使用另一个更常见的解决方法hybrid-sleep(例如Mac OS)。如果您的计算机支持休眠模式,则可以使用此功能:

systemctl hybrid-sleep

该命令应挂起并将计算机发送到磁盘(休眠)。一段时间后,计算机将关闭(打开电源时,它将使用休眠文件来唤醒)。

ps:我知道这并非OP发布的内容,但相当接近


0

不要忘记chmod + x该文件,使其可执行。

还有一个没有rtcwake的解决方案,在/ sys / class / rtc / rtc0中使用了akealarm。#注释之后,请在pm-functions(/ usr / lib / pm-utils)中使用过时的代码,因为内核不直接支持...,('cos当前内核(在3.6之后)直接支持)。还原该代码,并放入do_suspend()部分而不是do_suspend_hybrid()。

过时的代码(调用suspend_hybrid时,挂起然后休眠):

# 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

推荐的。使用uswsusp更容易,而同时最大化s2both的好处,即挂起时s2both。将还原后的代码放入uswsusp模块(/usr/lib/pm-utils/module.d)的do_suspend()部分。

恢复的代码(调用suspend时的suspend_hybrid):

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      

使用uswsusp,我们可以看到挂起/休眠的进度以及文本中显示的反向过程,甚至我们可以通过按退格键中止它。如果没有uswsusp,则挂起/休眠只会烦人地消失-烦人,特别是在唤醒唤醒警报并执行休眠状态时(uswsusp中的s2disk)。在pm-functions文件中的通常位置设置休眠之前的睡眠时间。

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

这是uswsusp mod :(请记住,该模块是从pm函数调用的,因此插入的变量相同)

#!/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  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.