关于如何在 Linux Mint 20 Cinnamon (Ubuntu 20) 上启用休眠并防止意外唤醒的指南

Tex*_*xno 8 swap acpi hibernate linux-mint systemd

更新:我在第 4 节中遇到了一些与我的脚本不一致的地方,该脚本旨在在每次唤醒时执行。事实证明,/proc/acpi/wakeup设置只是有时会重置。不是每次关机/重启/休眠/挂起。因此,有时,我的脚本会启用唤醒功能。我已经更新了脚本。现在它检查它是否在任何地方启用,/proc/acpi/wakeup然后才输出给它。

从某种意义上说,这是我未来的备忘录。我不明白为什么 linux 上的休眠不是一个简单的功能,为什么启用它必须如此复杂。我希望它也能帮助那些对冬眠有疑问的人。


  1. 首先,您需要确保您有足够大的交换文件。交换是您休眠时将 RAM 保存在磁盘上的位置。
  • 通过System Monitor -> Resources或运行sudo swapon --show. 你可能没有足够的。您的交换大小应该比 RAM 大小稍大。网上有一些指南。我在我的 4GB RAM 机器上进行 5GB 交换。
  • 如何使您的交换更大取决于您如何设置它。也许您需要创建一个更大的交换文件,也许您需要打开GParted并在那里简单地调整分区大小。我有一个加密的 LVM/dev/vgmint/root/dev/vgmint/swap卷。LVM 挂载时无法调整大小,因此您可以从带有 Linux Mint 的 U 盘启动。在那里你可以使用磁盘应用程序来解锁你的加密 LVM 并使用这个漂亮的指南来安全地减小/dev/vgmint/root卷的大小:
    • 强制检查文件系统 sudo e2fsck -f /dev/vgmint/root
    • 缩小您的文件系统sudo resize2fs /dev/vgmint/root 180G。将 180G 替换为您希望最终卷大小的 90%。
    • 将卷减小到最终大小sudo lvreduce -L 200G /dev/vgmint/root,其中 200G 是卷的最终大小。
    • 扩大文件系统以占用卷的其余可用空间 sudo resize2fs /dev/vgmint/root
  • 然后,您可以运行sudo lvextend -l 100%FREE /dev/vgmint/swap_1以使用刚刚创建的可用空间扩展交换卷。
  • 现在,我们需要更新交换。我们完成了一个 U 盘直播系统,启动到您的常规系统。如果你再次检查你的交换区的大小,你会发现它的大小没有改变,即使我们只是给了它更多的空间。我们需要创建一个新的交换。运行sudo swapoff -a以禁用所有交换并运行sudo mkswap /dev/vgmint/swap_1以创建一个新交换。
  1. 现在,通过阅读这篇可爱的文章来测试您的硬件是否支持休眠添加休眠按钮
    • 打开终端,运行sudo pm-hibernate。您的计算机应该休眠。再次启动它并确保它恢复了一切。如果是这样,那么您的硬件支持休眠。
    • 现在,我们将启用休眠图标。创建文件:
      sudo -i
      cd /var/lib/polkit-1/localauthority/50-local.d/
      nano com.ubuntu.enable-hibernate.pkla
      
      Run Code Online (Sandbox Code Playgroud)
    • 将以下内容粘贴到该文件中:
      [Re-enable hibernate by default in upower]
      Identity=unix-user:*
      Action=org.freedesktop.upower.hibernate
      ResultActive=yes
      
      [Re-enable hibernate by default in logind]
      Identity=unix-user:*
      Action=org.freedesktop.login1.hibernate
      ResultActive=yes
      
      Run Code Online (Sandbox Code Playgroud)
    • 保存,重启。现在,当您按下电源按钮时,您应该有“休眠”选项。
  2. 电源管理。这可能是 Linux Mint with Cinnamon 特有的。我希望我的笔记本电脑在一段时间不活动后休眠,但无法使用电源管理应用程序进行设置。要编辑内部 Cinnamon 设置,我使用 dconf 编辑器 ( sudo apt install dconf-editor)。打开它,转到/org/cinnamon/settings-daemon/plugins/power/或搜索powersleep-inactive-battery-type就是我所追求的 - 将其设置为“休眠”。在这里,我喜欢关闭use-time-for-policy并使用电池百分比而不是剩余时间来确定“电池电量低”、“电池严重”和“电池动作”状态。电池百分比是实际值,而剩余时间是估计值,可能会有很大差异。percentage-lowpercentage-criticalpercentage-action。环顾四周,此选项卡中有一些有趣的设置。不过要小心。
  3. 现在,最后一块拼图可以防止从 suspend/hibernation 中意外唤醒。写sudo cat /proc/acpi/wakeup。您将看到哪些设备已启用,并可能导致从休眠状态中意外唤醒。需要在启动和从挂起/休眠状态返回时禁用导致您出现问题的设备。
  • 以下是禁用设备的方法:echo DEVICE_NAME | sudo tee /proc/acpi/wakeup. (感谢这个线程。)
  • 找出哪些设备会导致您出现问题(我已禁用所有设备)并编写一个 bash 脚本来禁用它们。(文件可能需要归 root 所有,因为 root 将执行它。)它看起来像:
#!/bin/bash

filename='/proc/acpi/wakeup'
n=0
fix=false
while read line; do
if [[ "$line" == *"enabled"* ]]; then
  fix=true
  #break
fi
n=$((n))
done < $filename

if [[ "$fix" == "true" ]]; then
  echo RP01 | tee /proc/acpi/wakeup
  echo RP02 | tee /proc/acpi/wakeup
  echo RP03 | tee /proc/acpi/wakeup
  echo RP05 | tee /proc/acpi/wakeup
  echo RP06 | tee /proc/acpi/wakeup
  echo XHC1 | tee /proc/acpi/wakeup
  echo LID0 | tee /proc/acpi/wakeup
fi
Run Code Online (Sandbox Code Playgroud)

不要忘记为 root 设置可执行脚本。sudo su进而chmod +x /your-script.sh

  • 现在,我们需要创建一个将调用脚本的 systemctl 服务。(感谢这篇文章和本网站上的许多其他帖子的灵感)。我叫服务唤醒。使用sudo nano /etc/systemd/system/wakeups.service. 文件内容:
[Unit]
Description=Fix unwanted wakeups from suspend

[Service]
Type=oneshot
TimeoutSec=0
StandardOutput=syslog
User=root
ExecStart=/path-to-your-script/script.sh

[Install]
WantedBy=multi-user.target suspend.target hibernate.target
Run Code Online (Sandbox Code Playgroud)
  • 通过运行启用服务 systemctl enable wakeups.service
  1. 好的,这就是让休眠正常运行所需的全部内容!测试并确保在定期启动和从休眠/挂起返回时一切正常。

ter*_*don 3

The following was originally posted as part of the question, so I (terdon) am reproducing it here.


UPDATE: I have encountered some inconsistencies with my script in section 4 that is meant to be executed on every wake-up. Turns out, /proc/acpi/wakeup settings are only reset sometimes. Not on every shutdown/restart/hibernate/suspend. So, from time to time, my script would enable wakeups. I have updated the script. Now it checks if it says enabled anywhere in /proc/acpi/wakeup and only then outputs to it.

This is, in a way, a memo for myself in the future. I do not understand why hibernation on linux is not a simple feature that just works and why enabling it has to be so complicated. I hope it also helps people having questions about hibernation.


  1. First, you need to make sure you have a large enough swap file. Swap is where your RAM is saved on disk when you hibernate.
  • Check the size of your swap either through System Monitor -> Resources or by running sudo swapon --show. You probably do not have enough. Your swap size should be somewhat larger than you RAM size. There are some guides online. I go for 5GB swap on my 4GB RAM machine.
  • How to make your swap larger depends on how you have it set up. Maybe you need to create a larger swap file, maybe you need to open GParted and simply resize partitions there. I have an encrypted LVM with /dev/vgmint/root and /dev/vgmint/swap volumes. You cannot resize LVM while it is mounted, so you boot from a USB stick with Linux Mint. There you can use Disks app to unlock your encrypted LVM and use this beautiful guide to safely reduce the size of your /dev/vgmint/root volume:
    • Force check file system sudo e2fsck -f /dev/vgmint/root
    • Shrink your file system sudo resize2fs /dev/vgmint/root 180G. Replace 180G with about 90% of the size you want the final volume to be.
    • Reduce your volume to its final size sudo lvreduce -L 200G /dev/vgmint/root, where 200G is your volume's final size.
    • Grow your file system to take up the rest of the free space of your volume sudo resize2fs /dev/vgmint/root
  • Then you can run sudo lvextend -l 100%FREE /dev/vgmint/swap_1 to extend your swap volume with the free space you have just created.
  • Now, we need to update swap. We are done with a USB stick live system, boot into your regular system. If you check the size of your swap again, you will see that the size of it has not changed, even though we just gave it more space. We need to create a new swap. Run sudo swapoff -a to disable all swaps and run sudo mkswap /dev/vgmint/swap_1 to create a new one.
  1. Now, test if your hardware supports hibernation and add hibernation button back by reading this lovely article:
    • Open terminal, run sudo pm-hibernate. Your computer should hibernate. Boot it up again and make sure it restores everything. If it does, then your hardware supports hibernation.
    • Now, we will enable hibernation icon. Create file:
      sudo -i
      cd /var/lib/polkit-1/localauthority/50-local.d/
      nano com.ubuntu.enable-hibernate.pkla
      
      Run Code Online (Sandbox Code Playgroud)
    • Paste the following content into that file:
      [Re-enable hibernate by default in upower]
      Identity=unix-user:*
      Action=org.freedesktop.upower.hibernate
      ResultActive=yes
      
      [Re-enable hibernate by default in logind]
      Identity=unix-user:*
      Action=org.freedesktop.login1.hibernate
      ResultActive=yes
      
      Run Code Online (Sandbox Code Playgroud)
    • Save, restart. Now you should have "Hibernate" option when you press your power button.
  2. 能源管理。这可能是 Linux Mint with Cinnamon 特有的。我希望我的笔记本电脑在闲置一段时间后休眠,但无法使用电源管理应用程序进行设置。要编辑内部 Cinnamon 设置,我使用 dconf 编辑器 ( sudo apt install dconf-editor)。打开它,转到/org/cinnamon/settings-daemon/plugins/power/或只搜索powersleep-inactive-battery-type这就是我所追求的 - 将其设置为“休眠”。在这里,我喜欢关闭use-time-for-policy并使用电池百分比而不是剩余时间来确定“电池电量低”、“电池电量严重不足”和“电池操作”状态。电池百分比是实际值,而剩余时间是估计值,可能会有很大差异。您还可以使用percentage-lowpercentage-critical和来设置百分比阈值percentage-action。环顾四周,这个选项卡中有一些有趣的设置。不过要小心。
  3. 现在,最后一个难题是防止挂起/休眠中不必要的唤醒。写sudo cat /proc/acpi/wakeup。您将看到哪些设备已启用并且可能导致从休眠状态中意外唤醒。给您带来麻烦的设备需要在启动时和从挂起/休眠状态返回时禁用。
  • 以下是禁用设备的方法:echo DEVICE_NAME | sudo tee /proc/acpi/wakeup。(感谢这个线程。)
  • 找出哪些设备给您带来问题(我已禁用所有设备)并编写一个 bash 脚本来禁用它们。(文件可能需要由 root 拥有,因为 root 将执行它。)它看起来像:
#!/bin/bash

filename='/proc/acpi/wakeup'
n=0
fix=false
while read line; do
if [[ "$line" == *"enabled"* ]]; then
  fix=true
  #break
fi
n=$((n))
done < $filename

if [[ "$fix" == "true" ]]; then
  echo RP01 | tee /proc/acpi/wakeup
  echo RP02 | tee /proc/acpi/wakeup
  echo RP03 | tee /proc/acpi/wakeup
  echo RP05 | tee /proc/acpi/wakeup
  echo RP06 | tee /proc/acpi/wakeup
  echo XHC1 | tee /proc/acpi/wakeup
  echo LID0 | tee /proc/acpi/wakeup
fi
Run Code Online (Sandbox Code Playgroud)

不要忘记让您的脚本对 root 可执行。sudo su进而chmod +x /your-script.sh

  • 现在,我们需要创建一个将调用脚本的 systemctl 服务。(感谢这篇文章和本网站上许多其他帖子的启发)。我称该服务为唤醒。使用创建文件sudo nano /etc/systemd/system/wakeups.service。文件内容:
[Unit]
Description=Fix unwanted wakeups from suspend

[Service]
Type=oneshot
TimeoutSec=0
StandardOutput=syslog
User=root
ExecStart=/path-to-your-script/script.sh

[Install]
WantedBy=multi-user.target suspend.target hibernate.target
Run Code Online (Sandbox Code Playgroud)
  • 通过运行启用该服务systemctl enable wakeups.service
  1. 好了,这就是休眠功能正常运行所需的全部内容!测试并确保定期启动和从休眠/挂起返回时一切正常。