我如何默认使用pm-suspend-hybrid而不是pm-suspend?


41

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

我可以想象将pm-suspend脚本更改为自动执行,但是可能会有更可维护/更容易的方法。

Answers:


44

间接混合睡眠

这是较旧的方法:先挂起,然后经过延迟(默认为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
一个小注释,而不是'sudo pm-is-supported --suspend-hybrid && echo $?',请使用'sudo pm-is-supported --suspend-hybrid; 回声$?因为pm-is-supported的返回值为0表示支持,不支持1表示。
James Caccese 2012年

1
@JamesCaccese:在shellscript世界中,0表示“ true”,其他表示“ false”。您的脚本可以工作,但是原始海报的脚本也可以按预期工作,在受支持的位置打印'0',在不受支持的位置打印任何内容。如果您想要一律表示支持或不支持的内容,请尝试使用'sudo pm-is-supported --suspend-hybrid && echo“ supported” || 回声“不支持”'
zanfur 2012年

@zanfur-尽管我喜欢您随后提供的用于同时打印两种状态的解决方案(并且无论出于什么意外原因pm-is-supported均未按预期执行,但这不会对错误状态产生影响),但我还是感谢James Caccese提到的出于上述原因,请注意。
user66001 2013年

如果您使用的是16.04,请参见以下答案。
kapad

对我而言,唯一缺少的就是在resume争论/etc/default/grub.conf。同样作为nvidia用户,我必须设置nomodeset。因此,在我的情况下,生成的grub条目为:GRUB_CMDLINE_LINUX_DEFAULT="nomodeset resume=UUID=uuidofswappartition"。别忘了grub-update。并且还必须卸载某些模块,以便/etc/pm/config.d/00-unload_modules使用行创建文件,SUSPEND_MODULES="ath5k r8169"并确保我也将00-use-suspend-hybrid重命名为10-use-suspend-hybrid
mauron85 '16

31

Ubuntu 18.04定时选项

Ubuntu 18.04中有一个新的定时选项。在systemd是availiable一种新的模式suspend-then-hibernate。这将从睡眠模式开始,然后在固定时间后过渡到休眠模式。

在此hybrid-sleep模式下,休眠部分仅在电池电量严重不足且系统关闭时才有效。

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

[Sleep]
HibernateDelaySec=3600

睡眠1小时后,它将从睡眠变为冬眠。您可以编辑HibernateDelaySec以将延迟更改为休眠状态。

首先,使用systemd测试暂停然后休眠状态

通过按Ctrl+ Alt+ 打开终端,T然后输入:

sudo systemctl suspend-then-hibernate

如果可行,请将其永久保存。

  • 以下工作,当我合上盖子

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

找到两行:

#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及更高版本

解决方案通过blueyed 为真正的混合使用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使用您喜欢的编辑器打开文件。您将需要通过调用您的管理权限sudogksudopkexec编辑此文件。

找到两行:

#HandleSuspendKey=suspend
#HandleLidSwitch=suspend

注意,这些行在其#前面带有注释。这suspend是默认操作。删除#和更改suspendhybrid-sleep这两行,以使它们看起来像这样:

HandleSuspendKey=hybrid-sleep
HandleLidSwitch=hybrid-sleep

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

注意:

  • 除了suspendhybrid-sleep还有第三种选择,hibernate
  • 我的笔记本电脑没有物理睡眠按钮。所以我无法测试。
  • Suspend从齿轮菜单上单击,可使计算机正常暂停而不是混合睡眠。

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

我希望这有帮助


2
这个答案需要更多的投票。在16.04中修复了我的问题。谢谢。
kapad

别客气。现在我已经从14.04升级到16.04,随着时间的推移,我正在寻找一种新的系统化的工作方式。
user68186

1
也可用于Ubuntu GNOME 16.04.1
HarlemSquirrel,2017年

4

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

超时设置为-1,等待用户选择。我猜想这需要对中的脚本进行一些编辑/etc/pm/sleep.d/10_grub-common。我是新手,所以我没有涉足确切的变化。


1
如果它可以在12.10以上版本中运行,则可能值得进行错误报告和/或测试。
2012年

我在12.10
MDCore

3

这个问题在Google中经常出现,我认为值得一提。这里描述的方法不是(imo)混合暂停。它是“暂停X分钟后进入休眠状态”。真正的混合挂起会将您的RAM写入磁盘,然后进入低功耗状态(睡眠模式)。虽然需要更长的时间,但机器剩余电池时可以立即恢复,否则可以从硬盘恢复。大多数人都将这种行为称为混合睡眠,默认情况下,这种行为在更新的Windows和Mac笔记本电脑中使用。

以下是启用真正的混合暂停的方法:

  • 遵循最佳答案的第一部分。这将覆盖在pm-utils中执行“ hybrid_suspend”的“ suspend”调用。
    %cat /etc/pm/config.d/00-use-suspend-hybrid
    #始终使用suspend_hybrid而不是suspend
    如果[“ $ METHOD” =“暂停”]; 然后
        方法= suspend_hybrid
    科幻
  • 备份/ usr / lib / pm-utils / pm-functions
  • 从此处获取补丁:https : //bugs.freedesktop.org/attachment.cgi?id=68712
    • 此补丁启用了混合挂起(如果可用)(即在内核3.6+上)
  • 使用'patch -p0'应用它,或者如果失败则手动合并

这种方法对我的Sony Vaio SVS很有效。

PS:如果将来将来删除文件,请在此处复制补丁:

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“磁盘”> / sys / power / state
+ RET = $?
+ echo -n“ $ HIBERNATE_MODE_SAVE”> / sys / power / disk
+返回“ $ RET”
+}
+ fi
+
+#对于同时支持暂停(即混合暂停)的内核
+#自内核3.6起
+ if [-z“ $ SUSPEND_HYBRID_MODULE”] && \
+ [-f / sys / power / disk] && \
+ grep -q磁盘/ sys / power / state && \
+ grep -q挂起/ sys / power / disk; 然后
+ SUSPEND_HYBRID_MODULE =“内核”
+ do_suspend_hybrid()
+ {
+ HIBERNATE_MODE =“ suspend”
+ do_hibernate
    }
 科幻

资料来源:


1
您对混合暂停是正确的。我最近自己更改了代码段。您可以通过使用METHOD = hibernate和HIBERNATE_MODE = suspend获得(相当)相同的结果。我将HIBERNATE_MODE = platform设置在文件顶部,而不是保存和还原以前的版本(补丁所做的事情)。我将在上面更新我的答案。
2013年

看起来不错,感谢您的编辑@blueyed
Rohan Dhruva

1

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

过时的代码(调用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  

0

user68186对于Ubuntu 16.04的回答对我不起作用。但是,这里的解决方案确实可以。

首先,确保休眠状态。然后

在Ubuntu软件中搜索并安装dconf编辑器。然后启动它,并导航到org-> gnome-> settings守护程序->插件-> power。

更改“合上盖动作”和“合上盖电池动作”的值。

在我的电源设置中,这些选项显示为空白,但它们按预期方式工作。


0

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。然后,您需要通过下一个命令重新启动已登录的服务(警告!您的用户会话将重新启动):

systemctl restart systemd-logind.service

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

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.