前言
我犯了一个错误并安装带有加密 ZFS / OpenZFSroot
分区的Ubuntu 20.04 LTS在我的双启动配置中,我的工作效率很高的桌面上(见下面的分区表)。但我没有认真听我所遵循的教程,现在看来,虽然我有 32G 的 RAM,但我有一个 4G 的交换分区(编辑: 我找到了如何增加交换的方法,但仍然无法进入休眠状态 — 见下文)因此我无法让这台机器进入休眠状态。
解决这个问题的最佳方法是什么,以便我可以让这台机器进入休眠状态?
当前状态
$ sudo fdisk -l /dev/nvme0n1
Disk /dev/nvme0n1: 1.88 TiB, 2048408248320 bytes, 4000797360 sectors
Disk model: KXG60PNV2T04 NVMe KIOXIA 2048GB
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1FCA11ED-9263-4C06-A8DF-594C0DE84AFA
Device Start End Sectors Size Type
/dev/nvme0n1p1 2048 1085439 1083392 529M Windows recovery environment
/dev/nvme0n1p2 1085440 1290239 204800 100M EFI System
/dev/nvme0n1p3 1290240 1323007 32768 16M Microsoft reserved
/dev/nvme0n1p4 1323008 409420488 408097481 194.6G Microsoft basic data
/dev/nvme0n1p5 409421824 410920959 1499136 732M Windows recovery environment
/dev/nvme0n1p6 410923008 415117311 4194304 2G Linux filesystem
/dev/nvme0n1p7 415117312 4000797326 3585680015 1.7T Linux filesystem
$ sudo swapon --show --output all
NAME TYPE SIZE USED PRIO UUID LABEL
/dev/zd0 partition 4G 0B -2 1e1fb013-69d9-4878-b358-6b8ee53d5b09
$ sudo zpool list -v
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
Root 1.66T 535G 1.13T - - 2% 31% 1.00x ONLINE -
nvme0n1p7 1.66T 535G 1.13T - - 2% 31.5% - ONLINE
$ sudo zpool status -v
pool: Root
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
Root ONLINE 0 0 0
nvme0n1p7 ONLINE 0 0 0
errors: No known data errors
$ sudo zfs list
NAME USED AVAIL REFER MOUNTPOINT
Root 539G 1.08T 192K none
Root/root 534G 1.08T 530G /
Root/root/00a891589b00cebc55cb6767e266ca38ac201daf3a6048c1f33d7d55c0710533 544K 1.08T 143M legacy
[…] # many other legacy mount points
Root/root/ffe52d35c873e6a417ee12c7025d848dac1f269b8078266f00a8d8088fd34384 396K 1.08T 607M legacy
Root/swap 4.25G 1.08T 172M -
$ sudo zfs get all Root/swap
NAME PROPERTY VALUE SOURCE
Root/swap type volume -
Root/swap creation So Aug 2 15:36 2020 -
Root/swap used 4.25G -
Root/swap available 1.08T -
Root/swap referenced 172M -
Root/swap compressratio 1.00x -
Root/swap reservation none default
Root/swap volsize 4G local
Root/swap volblocksize 4K -
Root/swap checksum on default
Root/swap compression off local
Root/swap readonly off default
Root/swap createtxg 3746 -
Root/swap copies 1 default
Root/swap refreservation 4.25G local
Root/swap guid 12379969387189982956 -
Root/swap primarycache metadata local
Root/swap secondarycache none local
Root/swap usedbysnapshots 0B -
Root/swap usedbydataset 172M -
Root/swap usedbychildren 0B -
Root/swap usedbyrefreservation 4.08G -
Root/swap logbias throughput local
Root/swap objsetid 278 -
Root/swap dedup off default
Root/swap mlslabel none default
Root/swap sync always local
Root/swap refcompressratio 1.00x -
Root/swap written 172M -
Root/swap logicalused 169M -
Root/swap logicalreferenced 169M -
Root/swap volmode default default
Root/swap snapshot_limit none default
Root/swap snapshot_count none default
Root/swap snapdev hidden default
Root/swap context none default
Root/swap fscontext none default
Root/swap defcontext none default
Root/swap rootcontext none default
Root/swap redundant_metadata all default
Root/swap encryption aes-256-gcm -
Root/swap keylocation none default
Root/swap keyformat passphrase -
Root/swap pbkdf2iters 342K -
Root/swap encryptionroot Root -
Root/swap keystatus available -
我尝试过
创建交换文件
我以为交换文件可能是一个简单的修复但我显然错了:
$ sudo dd if=/dev/zero of=/swapfile bs=1MiB count=$((32*1024))
32768+0 records in
32768+0 records out
34359738368 bytes (34 GB, 32 GiB) copied, 14.5783 s, 2.4 GB/s
$ sudo chmod 600 /swapfile
$ sudo swapon /swapfile
swapon: /swapfile: skipping - it appears to have holes.
所以我想我应该增加交换分区。我也不清楚为什么swapon
声称交换分区有,4G
尽管zfs get all Root/swap
说1.08T
可用。
任何带有 GParted 的东西
GParted 无法识别太多内容。这可能与os-prober
(GParted 问题 14,Debian 错误 888114,os-prober 问题 1848496、openzfs 问题9801和9069)
替换小的交换分区(=增加 ZFS 上的交换分区)
创建命令的灵感来自于GitHub 上的评论但你应该记住不是使用-o sync=always
。
$ sudo zfs create -V 32G -b $(getconf PAGESIZE) -o logbias=throughput -o primarycache=metadata -o secondarycache=none -o com.sun:auto-snapshot=false -o compression=zle Root/swap_two
$ sudo zfs rename Root/swap Root/swap_bak
$ sudo zfs rename Root/swap_two Root/swap
$ sudo mkswap -f /dev/zvol/Root/swap
$ sudo swapon /dev/zvol/Root/swap
确保此条目位于/etc/fstab
:
/dev/zvol/Root/swap none swap discard 0 0
然后重新启动并删除微小的遗留交换:
$ sudo zfs destroy Root/swap_bak
虽然这似乎有效,但我仍然无法休眠:
$ sudo systemctl hibernate
Failed to hibernate system via logind: Sleep verb "hibernate" not supported
因此我仍然愿意听取任何建议。也许它需要一个专用的resume
参数GRUB_CMDLINE_LINUX_DEFAULT
?
答案1
最终原因与 ZFS 无关。即使调整交换大小后,它仍然不起作用,因为它在较新的 Ubuntu 版本上被禁用了(但会重新考虑)。
为了解决这个问题,您必须激活休眠模式。
com.ubuntu.desktop.pkla
在编辑器中打开:
$ sudo vim /var/lib/polkit-1/localauthority/10-vendor.d/com.ubuntu.desktop.pkla
# or on some machines
$ sudo vim /etc/polkit-1/localauthority/10-vendor.d/com.ubuntu.desktop.pkla
搜索条目Disable hibernate by default in upower
并将每个值Disable hibernate by default in logind
更改为。ResultActive
yes
重新启动并测试结果
$ sudo systemctl hibernate
# or
$ sudo pm-hibernate
如果仍然不起作用,你可能必须在 BIOS 中停用Fast boot
和等功能(Secure boot
注意力:这是非常您可能必须在较新的机器上执行此操作)。
如果测试不再导致错误,您还可以在 Ubuntu 设置中将休眠分配给某些操作。例如按下电源按钮。
答案2
使用 ZFS 进行交换(文件系统上的文件或整个 zvol)已经一个坏主意更不用说冬眠了。我唯一的建议是彻底放弃,ZFS 不是为此目的而构建的。
ZFS 是一个日志结构文件系统,其中文件的块(范围)不是随时固定的,而是每次写入时都会发生变化(无覆盖规则)。但是,交换子系统需要交换文件和块之间的简单、易懂的映射,以及对底层磁盘扇区的直接访问,而这两者都不是日志结构文件系统的特征。Btrfs 是另一个 LFS,它支持交换文件诸多限制,只是为了做到这一点可用的,而 ZFS 甚至不支持O_DIRECT
。 swap 的原因在于分区比 swap 性能更好、更可靠文件。
ZFS 进行了大量内部记录以保证事务安全,并且严重依赖充足的内存。如果您将 ZFS 用于交换,其主要目的是作为内存的磁盘支持扩展,则在高负载或高交换压力下,它会在 ZFS 和内存管理子系统之间产生正反馈循环。例如,这可能导致整个系统软锁定。
如果您进一步使用 swap-on-ZFS 进行休眠,ZFS 的内部数据结构迟早会变得疯狂,因为从休眠状态恢复依赖于从磁盘加载的正确且一致的内存,而 ZFS 还依赖于格式良好的内存数据结构来提供完整的磁盘数据。
答案3
增加交换分区的大小并将其用于休眠
创建交换分区
激活交换分区
使新的交换分区适用于休眠(可选)
创建交换分区启动 Ubuntu 安装 CD 并选择立即运行 Ubuntu 进入系统 -> GParted 分区编辑器
删除交换分区,如果其中没有其他内容,则删除包含该分区的扩展分区。(如果您能奇迹般地从这里调整交换分区的大小,我想您的生活将比我轻松得多。)将主分区的大小减少到您想要的新交换分区的大小(为了安全起见,我将其设置为 2x RAM + 500MB)。最简单的方法是在“以下可用空间”字段中填写您想要交换的空间量。在现在创建的可用空间中,选择新建,键入 linux-swap,如果您愿意,可以将分区命名为“swap”。点击申请按钮(应该是一个复选标记)将更改写入磁盘完成后,重新启动回到 Ubuntu 激活交换分区(如果您的交换位于主硬盘上,则无需在此处执行任何操作。)现在您需要找到您的交换所在的分区以及它的 UUID 是什么。你说的是 UUID?!好吧,这是分区的通用唯一标识符,因此即使由于添加磁盘等原因,它在启动时位于不同的挂载点,您也可以引用它。
打开终端并运行 gksu gparted & 并输入您的 root 密码。& 可让此进程运行,同时仍允许您访问命令行。
右键单击交换分区并选择信息. 您应该看到小路和唯一唯一标识符列出。请保留此内容以供进一步参考。运行 gksu gedit /etc/fstab & 并查找包含以下内容的行交换在其中。它应该是第三列,以空格或制表符分隔。您可以使用路径或 UUID 来告诉 Linux 在哪里找到您的交换分区。我推荐使用 UUID,因为即使您移动分区或磁盘以某种方式变成 sdb 而不是 sda 或类似名称,它也会保持不变。进行适当的编辑并保存文件。如果您使用 UUID(当然,用您的 UUID 代替),您的行应该看起来像这样:
UUID=41e86209-3802-424b-9a9d-d7683142dab7 无交换 sw 0 0
或者如果你使用路径:/dev/sda2 none swap sw 0 0
保存文件。使用此命令启用新的交换分区。
sudo swapon --all
或者
$ sudo swapon --all --verbose
swapon on /dev/sda2
swapon: /dev/sda2: found swap signature: version 1, page-size 4, same byte order
swapon: /dev/sda2: pagesize=4096, swapsize=2147483648, devsize=2147483648
Confirm that the swap partition exists.
$ cat /proc/swaps
Filename Type Size Used Priority
/dev/sda2 partition 2097148 0 -1
重新启动以确保新的交换在启动时正确激活使交换分区适用于休眠状态(可选)'INFO:这不适用于 12.04,在 12.04 中从休眠状态恢复的工作方式不同。'
再次打开终端并运行 cat /proc/swaps,希望您能看到列出的交换分区路径。如果没有,则可能是上述步骤出了问题。这是我的输出:
文件名 类型 大小 已用 优先级 /dev/sda2 分区 2676732 73380 -1 gksu gedit /etc/default/grub & 调出引导加载程序配置
查找行 GRUB_CMDLINE_LINUX="" 并确保它看起来像这样(当然使用你的 UUID)GRUB_CMDLINE_LINUX="resume=UUID=41e86209-3802-424b-9a9d-d7683142dab7" 并保存文件
sudo update-grub
并等待它完成
gksu gedit /etc/initramfs-tools/conf.d/resume & 并确保其内容为 resume=UUID=41e86209-3802-424b-9a9d-d7683142dab7(当然,用您的 UUID 代替我的)。保存文件!
sudo update-initramfs -u
重启!现在您应该可以休眠并恢复了!