间接混合睡眠

间接混合睡眠

我想在关闭盖子或从菜单中选择“暂停”时使用混合暂停方法,而不是暂停。

我可以想象改变 pm-suspend 脚本以自动执行此操作,但可能有更易于维护/更简单的方法。

答案1

间接混合睡眠

这是较旧的方法:首先挂起,然后在延迟(默认为 15 分钟)后唤醒进入休眠状态。将此方法用于 3.6 之前的 Linux 内核,或者如果您喜欢它在 15 分钟后不再消耗任何电量。

添加文件/etc/pm/config.d/00-use-suspend-hybrid

# Always use suspend_hybrid instead of suspend
if [ "$METHOD" = "suspend" ]; then
  METHOD=suspend_hybrid
fi
# The delay after which hibernation gets triggered (default: 900 seconds, 15 minutes):
PM_HIBERNATE_DELAY=900

您可能需要通过以下代码确保您的系统支持混合方法。如果它显示“0”,它应该可以工作:

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

Linux 3.6+ 的真正混合暂停

如果您有 Linux 3.6 内核,您可以使用以下命令,它将从一开始就暂停到磁盘和 RAM。

添加文件/etc/pm/config.d/00-use-suspend-hybrid

# WORKAROUND: always set the default hibernate mode first (normal mode)
# (not required if you have the patch mentioned by Rohan below (http://askubuntu.com/a/344879/169))
HIBERNATE_MODE=platform

# Always use hibernate instead of suspend, but with "suspend to both"
if [ "$METHOD" = "suspend" ]; then
  METHOD=hibernate
  HIBERNATE_MODE=suspend
fi

# Make sure to use the kernel's method, in case uswsusp is installed etc.
SLEEP_MODULE=kernel

这将始终将图像写入磁盘,然后暂停到 RAM,其优点是恢复速度始终很快(只要电池不耗尽),并且机器不会在短时间内(PM_HIBERNATE_DELAY 之后)唤醒以真正进入休眠状态。

缺点是该过程需要更长的时间(因为它始终休眠到磁盘),并且您的电池可能会在长期内耗尽(例如 12 小时后)。

答案2

Ubuntu 18.04 有一个定时选项

Ubuntu 18.04有一个新的定时选项。在 中systemd,有一个新模式可用suspend-then-hibernate。这将从睡眠模式开始,然后在固定时间后转换到休眠模式。

在该hybrid-sleep模式下,仅当电池电量极低且系统关闭时,休眠部分才会有效。

要开始使用此功能,您需要创建一个/etc/systemd/sleep.conf包含以下内容的文件:

[Sleep]
HibernateDelaySec=3600

睡眠 1 小时后,系统将从睡眠状态转为休眠状态。您可以编辑HibernateDelaySec以更改休眠延迟时间。

首先,使用 systemd 测试 suspend-then-hibernate 是否有效

Ctrl按+ Alt+打开终端T并输入:

sudo systemctl suspend-then-hibernate

如果有效则使其永久生效。

  • 以下作品当我合上盖子时

使用您喜欢的编辑器打开文件/etc/systemd/logind.conf。您需要通过或sudo调用您的管理权限gksudopkexec编辑此文件。

找到以下两行:

#HandleSuspendKey=suspend
#HandleLidSwitch=suspend

注意,这些行被注释掉了#在它们前面。这suspend是默认操作。删除并将这两行中的#更改为suspendsuspend-then-hibernate使它们看起来像这样:

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

保存文件。注销并重新登录或logind通过以下命令重新启动服务:

systemctl restart systemd-logind.service

警告!您的用户会话将重新启动

来源:盖子关闭暂停然后休眠

Ubuntu 16.04 及以上版本

解决方案经过蓝眼睛的 Linux 3.6+ 上的真正混合暂停对我来说不起作用。我怀疑这是因为 Ubuntu 16.04 使用systemd和不使用文件/etc/pm/config.d/00-use-suspend-hybrid

首先,使用 systemd 测试休眠和混合睡眠是否有效

Ctrl按+ Alt+打开终端T并输入:

sudo systemctl hibernate

这应该会使您的计算机进入休眠状态。要尝试混合睡眠,请输入:

sudo systemctl hybrid-sleep

如果有效则使其永久生效。

  • 以下作品当我合上盖子时

使用您喜欢的编辑器打开文件/etc/systemd/logind.conf。您需要通过或sudo调用您的管理权限gksudopkexec编辑此文件。

找到以下两行:

#HandleSuspendKey=suspend
#HandleLidSwitch=suspend

注意,这些行被注释掉了#在它们前面。这suspend是默认操作。删除并将这两行中的#更改为suspendhybrid-sleep使它们看起来像这样:

HandleSuspendKey=hybrid-sleep
HandleLidSwitch=hybrid-sleep

保存文件。注销并重新登录。

笔记:

  • 或者suspend还有hybrid-sleep第三种选择,hibernate
  • 我的笔记本电脑没有物理睡眠按钮。所以我无法测试它。
  • 单击Suspend齿轮菜单中的可使计算机进入正常挂起状态而不是混合睡眠状态。

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

我希望这有帮助

答案3

在 12.04 中,我注意到当触发休眠时(使用PM_HIBERNATE_DELAY=XX),恢复/解冻 shell 脚本不会取消设置 grub recordfail 变量。因此 grub 不会自动启动。

超时设置为 -1,等待用户选择。我猜这需要编辑一些脚本/etc/pm/sleep.d/10_grub-common。我是新手,所以不幸的是我还没有弄清楚确切的变化。

答案4

还有另一种解决方案,无需在 config.d 中添加任何文件,只需在 /sys/class/rtc/rtc0 中使用 wakealarm。在注释 #since the kernel does not directly support ... 后使用 pm-functions (/usr/lib/pm-utils) 中的过时代码(因为当前内核(3.6 之后)直接支持)。恢复该代码并放入 do_suspend() 部分而不是 do_suspend_hybrid(),并使用 pm-functions 补丁(直到他们修复它)。

过时的代码(当调用 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-functions 调用的,所以插入的变量是相同的)

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

相关内容