btrfs、LUKS、交换文件:如何在交换文件上休眠?

Jan*_*oon 5 linux fedora hibernate luks btrfs

我在 fedora 32 silverblue、内核版本 5.7.7 和 anaconda 安装程序默认设置上使用由 LUKS 加密的 btrfs。

因为 Fedora 安装程序自动分区不会添加交换分区或文件(或者我做错了),所以我自己添加了交换文件以进行休眠,如下所示:

$ # swapfile under /var directory because the location is the only part user can modify on fedora silverblue
$ touch /var/swapfile
$ chattr +C /var/swapfile 
$ fallocate --length 10GiB /var/swapfile
$ sudo chown root /var/swapfile 
$ sudo chmod 600 /var/swapfile 
$ sudo mkswap /var/swapfile 
$ sudo swapon /var/swapfile
Run Code Online (Sandbox Code Playgroud)

swapfile_t为 selinux 添加了 attr:

$ ls -Z /var/swapfile
unconfined_u:object_r:swapfile_t:s0 /var/swapfile
Run Code Online (Sandbox Code Playgroud)

然后我按照arch wiki指令(https://wiki.archlinux.org/index.php/Power_management/Sus ​​pend_and_hibernate#Hibernation_into_swap_file_on_Btrfs)。

/var/swapfile的物理偏移量是19793240064,页面大小是4096,所以我用grub添加了内核参数。现在这是我的/etc/default/grub内核参数的一部分:

GRUB_CMDLINE_LINUX="rd.luks.uuid=luks-572bfd87-6fa7-4be1-8c73-4759ac9af3cd rhgb quiet resume=UUID=572bfd87-6fa7-4be1-8c73-4759ac9af3cd resume_offset=4832334"
Run Code Online (Sandbox Code Playgroud)

这是我的块:

$ sudo blkid
/dev/nvme0n1p1: UUID="5490-E733" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="46ecd0d1-6722-4b92-af73-9574a58eb332"
/dev/nvme0n1p2: UUID="c9294f4d-9c92-4c08-a037-715223443f2b" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="731852d5-26cd-43bb-8904-c4256247f97d"
/dev/nvme0n1p3: UUID="572bfd87-6fa7-4be1-8c73-4759ac9af3cd" TYPE="crypto_LUKS" PARTUUID="e74de89a-fe5f-402f-a3bf-e398ad069b5b"
/dev/sda: BLOCK_SIZE="512" UUID="C602B4D602B4CD25" TYPE="ntfs"
/dev/mapper/luks-572bfd87-6fa7-4be1-8c73-4759ac9af3cd: LABEL="fedora_fedora" UUID="337b2fcb-a61b-4976-89ac-2b3feee02963" UUID_SUB="932cfe1c-9713-4063-bda0-a8a792654c39" BLOCK_SIZE="4096" TYPE="btrfs"
Run Code Online (Sandbox Code Playgroud)

并且休眠失败。看来简历参数有问题。我尝试过UUID=572bfd87-6fa7-4be1-8c73-4759ac9af3cdUUID=337b2fcb-a61b-4976-89ac-2b3feee02963但都失败了。出了什么问题?如何正确设置交换文件休眠?

我已经检查journalctl -u systemd-logind并找到了该消息,但这没有帮助:

$ ls -Z /var/swapfile
unconfined_u:object_r:swapfile_t:s0 /var/swapfile
Run Code Online (Sandbox Code Playgroud)

nja*_*jam 5

以下步骤使 hibernate 能够在 Fedora Silverblue 33 上使用 btrfs 文件系统交换文件,可能使用 LUKS 加密。不幸的是,它不是很直接,但它确实有效。

\n

注意安全启动才能使休眠功能正常工作。检查 BIOS 设置是否已禁用。

\n

有关更多背景信息以及为什么休眠功能不能开箱即用的信息,请参阅这个旧的 Fedora Workstation wiki 页面

\n
    \n
  1. 创建并配置与系统内存大小相同的交换文件
  2. \n
\n
sudo touch /var/swapfile\nsudo chattr +C /var/swapfile\nsudo fallocate --length "$(grep MemTotal /proc/meminfo | awk \'{print $2 * 1024}\')" /var/swapfile\nsudo chmod 600 /var/swapfile\nsudo mkswap /var/swapfile\nsudo swapon /var/swapfile\necho \'/var/swapfile none swap sw 0 0\' | sudo tee -a /etc/fstab\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 设置resume内核参数。
    \n首先我们需要计算交换文件的偏移量btrfs_map_physical.c。\n以下命令使用Arch Linux wiki 页面中有关电源管理的描述的程序描述的程序。
  2. \n
\n
sudo podman run --rm -it --privileged -v /var/swapfile:/var/swapfile -v /tmp:/tmp debian:stable sh -c \'\n  apt-get update &&\n  apt-get install -qy gcc wget &&\n  wget "https://raw.githubusercontent.com/osandov/osandov-linux/61679ecd914d653bab14d0e752595e86b9f50513/scripts/btrfs_map_physical.c" &&\n  gcc -O2 -o btrfs_map_physical btrfs_map_physical.c &&\n  ./btrfs_map_physical /var/swapfile | sed -n "2p" | awk "{print \\$NF}" >/tmp/swap_physical_offset\n  \'\nSWAP_PHYSICAL_OFFSET=$(cat /tmp/swap_physical_offset)\nSWAP_OFFSET=$(echo "${SWAP_PHYSICAL_OFFSET} / $(getconf PAGESIZE)" | bc)\n
Run Code Online (Sandbox Code Playgroud)\n

然后我们构建实际的内核参数并将它们打印到屏幕上。

\n
SWAP_UUID=$(findmnt -no UUID -T /var/swapfile)\nRESUME_ARGS="resume=UUID=${SWAP_UUID} resume_offset=${SWAP_OFFSET}"\necho "${RESUME_ARGS}"\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x9a\xa0 确保输出看起来与此类似,只是具有不同的 UUID 和偏移量:

\n
\n

简历=UUID=3d2b6777-0114-4a9d-8b98-e279e7e09cdaresume_offset=7753110

\n
\n

如果输出看起来正确,请使用grubby设置内核参数设置内核参数:

\n
sudo grubby --update-kernel=ALL --args="${RESUME_ARGS}"\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 禁用 systemd 交换空间检查。
    \n为了避免有关交换大小的误报 systemd 错误,如果已经存在交换目标(例如默认的 zram 设备)。
  2. \n
\n
sudo mkdir -p /etc/systemd/system/systemd-logind.service.d/\ncat <<-EOF | sudo tee /etc/systemd/system/systemd-logind.service.d/override.conf\n[Service]\nEnvironment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1\nEOF\nsudo mkdir -p /etc/systemd/system/systemd-hibernate.service.d/\ncat <<-EOF | sudo tee /etc/systemd/system/systemd-hibernate.service.d/override.conf\n[Service]\nEnvironment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1\nEOF\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. SELinux:允许 systemd 访问交换文件。
    \n这是 Fedora 的“selinux-policy”中缺少规则的解决方法(请参阅12)),应该在未来的版本 3.14.7 中修复。
  2. \n
\n
cd "$(mktemp -dt)"\ncat <<-EOF | tee systemd_swapfile.te\nmodule systemd_swapfile 1.0;\n\nrequire {\n    type init_t;\n    type swapfile_t;\n    class file { open getattr read ioctl lock };\n}\n\nallow init_t swapfile_t:file { open getattr read ioctl lock };\nEOF\ncheckmodule -M -m -o systemd_swapfile.mod systemd_swapfile.te\nsemodule_package -o systemd_swapfile.pp -m systemd_swapfile.mod\nsudo semodule -i systemd_swapfile.pp\ncd -\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 重新启动并测试休眠。
    \n首先重新启动以应用所有设置:
  2. \n
\n
systemctl reboot\n
Run Code Online (Sandbox Code Playgroud)\n

然后尝试休眠:

\n
systemctl hibernate\n
Run Code Online (Sandbox Code Playgroud)\n


har*_*ymc 2

发帖人缺少的步骤是在需要选择交换文件所在的分区时查找包含交换文件的分区的 UUID。可以使用以下findmnt命令检索:

sudo findmnt -no SOURCE,UUID -T /path/to/swapfile
Run Code Online (Sandbox Code Playgroud)

已发布多种用于在交换文件上休眠的方法,每种方法都在其预期环境中有效。以下是一些参考资料,但您可以在帖子上面的评论中找到更多信息: