我应该如何成功休眠 Ubuntu 16.04?
我尝试了网上几乎所有的解决方案,但没有一个真正有用。我发现我的问题几乎完全类似于这个
答案1
休眠的使用systemctl
以及在困难情况下如何使其发挥作用
对我来说,pm-hibernate
总是失败。经过一些调整后,我能够使用 systemd 的接口(16.04 及更高版本中的初始化系统)休眠。我还设法使用交换文件在 17.04 上使其运行。此案例研究可能对遇到问题的其他用户有用。
第一次尝试:
sudo systemctl hibernate
如果失败,请开始排除故障:在休眠状态(HTD 或 ACPI S4)下,机器状态将写入磁盘,因此无需电源即可保存。状态将写入交换分区或交换文件。注意:如果使用 Btrfs,请勿尝试使用交换文件,因为这可能会导致文件系统损坏
您的交换分区或交换文件可能需要与 RAM 大小相同才能允许休眠,但根据这Arch 维基页面,因此在增加交换大小之前,请先尝试其他步骤。
如果你遇到的问题是干净启动而不是预期的恢复,那么至少你很可能需要设置启动参数来查找磁盘映像
找到您的交换分区:
grep swap /etc/fstab
对我来说这返回(部分输出)
# swap was on /dev/mmcblk0p3 during installation
/dev/mmcblk0p3
要指定的分区在哪里
添加启动参数:
sudoedit /etc/default/grub
在行首GRUB_CMDLINE_LINUX_DEFAULT
添加resume=/dev/YourSwapPartition
引号中的部分(替换为您之前确定的分区)。使用我的示例:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=/dev/mmcblk0p3"
每当您更改此文件时,都必须运行sudo update-grub
,否则更改将不起作用。
现在您需要重新启动。然后您可以尝试休眠,方法是发出以下命令:
sudo systemctl hibernate
要恢复,请按下电源按钮,系统将启动。
如果仍然有问题,请开始调试。
下面我将以我的情况为例,但可以找到有关调试 S 状态的详细信息在这篇博客中和还有这个。
设置更多启动参数以捕获更多信息。删除quiet
和splash
并添加initcall_debug
和,no_console_suspend
这将导致 init 系统调用打印到控制台,以便您可以观察出了什么问题。我设置了以下内容:
GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/mmcblk0p3 no_console_suspend initcall_debug"
这帮助我了解了从休眠状态恢复时出了什么问题。您也可以尝试使用dmesg
。
就我的情况而言,恢复后,我失去了 WiFi,内核显然很不正常,因为大多数命令(例如从 读取任何内容/sys
、重新加载模块或任何systemctl
命令)都不起作用 - 进程似乎启动了,然后就挂起了(当然,重启后所有这些都会恢复正常)。看着系统非常缓慢地关闭并阅读所有调试消息,我注意到“brcm”有很多问题,所以我猜是我的 Broadcom 无线驱动程序模块出了问题。果然,我调整了休眠程序,先卸载模块:
sudo modprobe -r brcmfmac
sudo systemctl hibernate
在恢复时我重新插入模块
sudo modprobe brcmfmac
一切都很顺利。我还必须将btsdio
似乎与以下模块不兼容的模块列入黑名单:brcmfmac
更新:在 17.04 上使用交换文件进行休眠。
再次借助 Arch wiki 页面的帮助和一些额外的修改,我设法使用交换文件在 17.04 上实现了休眠功能。这需要一个额外的启动参数,其中 n 是输出中的resume_offset=n
第一个数字:physical_offset
sudo filefrag -v /swapfile
$ sudo filefrag -v /swapfile
Filesystem type is: ef53
File size of /swapfile is 1425873920 (348114 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 32767: 34816.. 67583: 32768:
1: 32768.. 63487: 67584.. 98303: 30720:
....
因此,我的情况中的附加引导参数是resume_offset=34816
。您仍然需要为要从中恢复的分区设置引导参数。这将是根分区(或交换文件所在的任何分区)我的参数现在是:
GRUB_CMDLINE_LINUX_DEFAULT="no_console_suspend initcall_debug resume=/dev/mmcblk1p2 resume_offset=34816"
我的根分区在哪里/dev/mmcblk1p2
(你的更可能是这样的/dev/sda2
)。
在恢复过程中,我看到图像加载成功,但就我的情况而言(仅举个例子 - YMMVAPD),然后一些驱动程序(i2c_designware
)抛出了一些错误,导致我在恢复时系统完全冻结。如果我卸载这些模块,休眠功能就会起作用brcmfmac
,但如果没有这些模块,系统很快就会变得无法使用。因此,我编写了一种脚本来卸载有问题的模块,并在恢复时立即重新插入它们:
# remove buggy modules
modprobe -r brcmfmac i2c_designware_platform i2c_designware_core &&
# hibernate
echo disk > /sys/power/state
# reinsert
modprobe i2c_designware_core i2c_designware_platform brcmfmac
当我想休眠时,我会运行sudo bash script
。这个方法很有效。
总结
使用 systemd,设置从交换中恢复的启动参数,识别有问题的驱动程序并在启动休眠之前卸载它们。如果系统在没有这些模块的情况下无法长时间工作,或者您需要卸载多个模块,使用简单的脚本来启动休眠可能会更容易。
答案2
您可以使用
sudo pm-hibernate
检查休眠模式是否在你的系统上运行(这将使你的计算机进入休眠状态)。
如果它不起作用,请检查你的交换大小是否至少与你的 RAM 一样大。
要将选项添加到设置菜单,您可以创建一个配置文件。打开终端窗口并运行以下命令:
sudo nano /etc/polkit-1/localauthority/50-local.d/com.ubuntu.enable-hibernate.pkla
它打开一个空文件。复制下面的几行并将其粘贴到 nano 窗口中。
[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;org.freedesktop.login1.handle-hibernate-key;org.freedesktop.login1;org.freedesktop.login1.hibernate-multiple-sessions;org.freedesktop.login1.hibernate-ignore-inhibit
ResultActive=yes
然后保存更改并关闭 nano,重新启动系统以使休眠模式出现在“电源选项”中。
参考:如何使计算机休眠?在 Ubuntu 16.04 的官方文档中。
希望它有效。在我尝试了所有其他选项后,这个对我有用。
答案3
我认为,如何为 16.04 启用休眠模式答案是众所周知的,如Ubuntu 维基(如果您需要这些步骤,请参见下文)。但我认为需要检查的内容不够彻底。至少,这是我发现的。
检查事项
从我自己的测试来看,我至少发现了一个你应该执行的额外检查。但我在互联网上没有找到关于它的任何地方。
以下是一些检查 -
检查你没有使用任何文件系统分区。是的。从我的测试中,我发现如果你有文件系统分区,休眠将无法工作。删除或更改分区类型对
ext4
我没有帮助。我需要删除该btrfs-tools
包。sudo apt-get purge btrfs-tools
您可能想检查其他未经充分测试的新分区类型。如果不删除软件包,将驱动程序列入黑名单也可能有效,但我还没有测试过。
您还需要检查交换分区是否足够大,可以容纳 RAM 的内容。如果您的 RAM 是 4 GB,则交换分区至少应为 4 GB(您应该分配更多 MB 以确保安全)。
启用休眠模式的步骤
它涉及以下步骤
以 root 身份创建文件
/etc/polkit-1/localauthority/50-local.d/enable-hibernate.pkla
sudo -i nano /etc/polkit-1/localauthority/50-local.d/enable-hibernate.pkla
将这些内容放在该文件上
[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;org.freedesktop.login1.handle-hibernate-key;org.freedesktop.login1;org.freedesktop.login1.hibernate-multiple-sessions;org.freedesktop.login1.hibernate-ignore-inhibit ResultActive=yes
Ctrl按-保存文件。按-O退出CtrlX
重启
polkitd
守护进程sudo systemctl restart polkitd.service
它应该启用休眠模式。
答案4
尝试让系统进入休眠状态(深度睡眠,其中 RAM 被写入磁盘),产生以下错误
$ sudo systemctl hibernate
Failed to hibernate system via logind: Sleep verb not supported
以下步骤可解决此问题(在 Thinkpad X1 Carbon 7th Gen、Ubuntu 19.10 上测试)。其中大部分内容来自这里。
- 在 BIOS 中关闭安全启动。
- 在 BIOS 中将“睡眠状态”设置为 Linux。此选项最初在我的 BIOS 中名为“现代待机”,我必须将其关闭,但在 BIOS 名称之后,名称更改为“睡眠状态”。
创建一个等于或大于 RAM 的交换文件。这里涉及几个步骤,如下所示。
a. 关闭交换。
$ sudo swapoff -a
b. 创建一个大于或等于 RAM 的文件。我的是 16GB,所以:
$ sudo dd if=/dev/zero of=/swapfile bs=1G count=16 16+0 records in 16+0 records out 17179869184 bytes (17 GB, 16 GiB) copied, 19.3685 s, 887 MB/s
c. 为文件设置正确的权限:
$ sudo chmod 600 /swapfile
d. 将文件设为交换文件:
$ sudo mkswap /swapfile Setting up swapspace version 1, size = 16 GiB (17179865088 bytes) no label, UUID=3b2e6f0c-ce12-4a84-9044-d99bfba059ea
e. 打开交换并检查其是否设置正确:
$ sudo swapon /swapfile $ cat /proc/swaps Filename Type Size Used Priority /swapfile file 16777212 0 -2
f. 为了让 swap 在重启后被加载,我们必须将其添加到
/etc/fstab
。因此运行以下命令打开文件:$ sudo gedit /etc/fstab
并通过添加如下所示的最后一行来更新它。请注意,我还注释了我原来的交换,因为我不需要它。
/dev/mapper/vgubuntu-root / ext4 errors=remount-ro 0 1 # /boot was on /dev/nvme0n1p2 during installation UUID=d265e7c4-1a4f-49c4-af29-fea2543490d7 /boot ext4 defaults 0 2 # /boot/efi was on /dev/nvme0n1p1 during installation UUID=0004-FB5F /boot/efi vfat umask=0077 0 1 #/dev/mapper/vgubuntu-swap_1 none swap sw 0 0 /swapfile none swap sw 0 0
g. 重新启动并运行此命令以查看交换是否出现:
cat /proc/swaps Filename Type Size Used Priority /swapfile file 16777212 0 -2
现在,是时候更新 grub 了。a. 运行此命令打开 grub:
$ sudoedit /etc/default/grub
b. 通过运行以下命令查找 root 的挂载位置。
$ mount | grep " / " /dev/mapper/vgubuntu-root on / type ext4 (rw,relatime,errors=remount-ro)
c. 因此,将注意力集中在 上
/dev/mapper/vgubuntu-root
。通过运行以下命令查找此位置的 UUID:$ sudo blkid /dev/mapper/nvme0n1p3_crypt: UUID="AZrE57-dlNc-BiUr-RrTF-SdT2-luVK-vrliNq" TYPE="LVM2_member" /dev/mapper/vgubuntu-root: UUID="2331fe68-3e7a-4937-9cfa-74fc7a4b79f6" TYPE="ext4" /dev/nvme0n1p1: UUID="0004-FB5F" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="09813156-6b7a-4fc2-b644-a8c6b7d40abf" /dev/nvme0n1p2: UUID="d265e7c4-1a4f-49c4-af29-fea2543490d7" TYPE="ext4" PARTUUID="64f5da2f-71d3-4f02-9b1e-3e12d7f6c445" /dev/nvme0n1p3: UUID="201acba5-ff20-46ee-9000-34efefef3fbe" TYPE="crypto_LUKS" PARTUUID="16858e70-eb08-4de8-b944-50689cad9d9f" /dev/sda1: LABEL="ST64GB" UUID="624AB7B308FE9F38" TYPE="ntfs" PTTYPE="dos" /dev/mapper/vgubuntu-swap_1: UUID="af3b29a2-ba6b-44de-89dd-072f4233aaf9" TYPE="swap"
本例中的 UUID 是
2331fe68-3e7a-4937-9cfa-74fc7a4b79f6
。保留此 UUID。d. 接下来,我们需要找到交换文件的偏移量。运行以下命令:$ sudo filefrag -v /swapfile Filesystem type is: ef53 File size of /swapfile is 17179869184 (4194304 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 32767: 835584.. 868351: 32768: 1: 32768.. 49151: 868352.. 884735: 16384: 2: 49152.. 81919: 886784.. 919551: 32768: ...
我们查找第一个块的 pysical_offset。在上面的例子中,它将是
835584
。也保留这个数字。e. 我们现在需要更新 grub。运行以下命令:$ sudoedit /etc/default/grub
更新以下内容。我们更新
GRUB_CMDLINE_LINUX_DEFAULT
并添加GRUB_RECORDFAIL_TIMEOUT=0
。# If you change this file, run 'update-grub' afterwards to update # /boot/grub/grub.cfg. # For full documentation of the options in this file, see: # info -f grub -n 'Simple configuration' GRUB_DEFAULT=0 GRUB_TIMEOUT_STYLE=hidden GRUB_TIMEOUT=0 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=2331fe68-3e7a-4937-9cfa-74fc7a4b79f6 resume_offset=835584" GRUB_CMDLINE_LINUX="" # Avoiding grub to show up in boot when resuming from hibernation GRUB_RECORDFAIL_TIMEOUT=0
f. 更新 grub 文件后,运行以下命令:
$ sudo update-grub
就是这样。现在,您可以通过运行以下命令让系统进入休眠状态:
$ sudo systemctl hibernate