我在 fedora 32 silverblue 上使用由 LUKS 加密的 btrfs,内核版本 5.7.7,使用 anaconda 安装程序默认设置。
因为 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
并且我swapfile_t
为 selinux 添加了 attr:
$ ls -Z /var/swapfile
unconfined_u:object_r:swapfile_t:s0 /var/swapfile
然后我按照 arch wiki 说明进行操作(https://wiki.archlinux.org/index.php/Power_management/Suspend_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"
这是我的 blkid:
$ 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"
并且休眠失败。似乎是恢复参数问题。我尝试了UUID=572bfd87-6fa7-4be1-8c73-4759ac9af3cd
,但UUID=337b2fcb-a61b-4976-89ac-2b3feee02963
都失败了。哪里出了问题?如何正确设置交换文件休眠?
我已检查journalctl -u systemd-logind
并找到了该消息,但这没有帮助:
...
localhost.localdomain systemd-logind[936]: Failed to open swap file /var/swapfile to determine on-disk offset: Permission denied
...
答案1
以下步骤使 Hibernate 能够在 Fedora Silverblue 33 上使用 btrfs 文件系统(可能使用 LUKS 加密)交换文件。不幸的是,这不是很简单,但它确实有效。
注意安全启动必须禁用休眠功能才能工作。检查 BIOS 设置是否已禁用。
有关更多背景信息以及为什么休眠功能无法立即使用,请参阅旧 Fedora Workstation 维基页面。
- 创建并配置与系统内存大小相同的交换文件。
sudo touch /var/swapfile
sudo chattr +C /var/swapfile
sudo fallocate --length "$(grep MemTotal /proc/meminfo | awk '{print $2 * 1024}')" /var/swapfile
sudo chmod 600 /var/swapfile
sudo mkswap /var/swapfile
sudo swapon /var/swapfile
echo '/var/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
- 设置
resume
内核参数。
首先我们需要计算抵消交换文件。以下命令使用btrfs_map_physical.c
Arch Linux 中描述的程序有关电源管理的 wiki 页面。
sudo podman run --rm -it --privileged -v /var/swapfile:/var/swapfile -v /tmp:/tmp debian:stable sh -c '
apt-get update &&
apt-get install -qy gcc wget &&
wget "https://raw.githubusercontent.com/osandov/osandov-linux/61679ecd914d653bab14d0e752595e86b9f50513/scripts/btrfs_map_physical.c" &&
gcc -O2 -o btrfs_map_physical btrfs_map_physical.c &&
./btrfs_map_physical /var/swapfile | sed -n "2p" | awk "{print \$NF}" >/tmp/swap_physical_offset
'
SWAP_PHYSICAL_OFFSET=$(cat /tmp/swap_physical_offset)
SWAP_OFFSET=$(echo "${SWAP_PHYSICAL_OFFSET} / $(getconf PAGESIZE)" | bc)
然后我们构建实际的内核参数并将其打印到屏幕上。
SWAP_UUID=$(findmnt -no UUID -T /var/swapfile)
RESUME_ARGS="resume=UUID=${SWAP_UUID} resume_offset=${SWAP_OFFSET}"
echo "${RESUME_ARGS}"
⚠ 确保输出与此类似,只是 UUID 和偏移量不同:
简历=UUID=3d2b6777-0114-4a9d-8b98-e279e7e09cda 简历偏移量=7753110
如果输出正确,请使用以下命令设置内核参数邋遢的:
sudo grubby --update-kernel=ALL --args="${RESUME_ARGS}"
- 禁用 systemd 交换空间检查。
如果已经存在交换目标(例如默认的 zram 设备),则为了避免有关交换大小的误报 systemd 错误。
sudo mkdir -p /etc/systemd/system/systemd-logind.service.d/
cat <<-EOF | sudo tee /etc/systemd/system/systemd-logind.service.d/override.conf
[Service]
Environment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1
EOF
sudo mkdir -p /etc/systemd/system/systemd-hibernate.service.d/
cat <<-EOF | sudo tee /etc/systemd/system/systemd-hibernate.service.d/override.conf
[Service]
Environment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1
EOF
cd "$(mktemp -dt)"
cat <<-EOF | tee systemd_swapfile.te
module systemd_swapfile 1.0;
require {
type init_t;
type swapfile_t;
class file { open getattr read ioctl lock };
}
allow init_t swapfile_t:file { open getattr read ioctl lock };
EOF
checkmodule -M -m -o systemd_swapfile.mod systemd_swapfile.te
semodule_package -o systemd_swapfile.pp -m systemd_swapfile.mod
sudo semodule -i systemd_swapfile.pp
cd -
- 重新启动并测试休眠。
首次重启以应用所有设置:
systemctl reboot
然后尝试休眠:
systemctl hibernate
答案2
发帖者缺少的步骤是找到包含交换文件的分区的 UUID,以便选择交换文件所在的分区。可以使用以下命令检索findmnt
:
sudo findmnt -no SOURCE,UUID -T /path/to/swapfile
已发布了多种在交换文件上休眠的方法,每种方法在其目标环境中均有效。以下是一些参考资料,但您可以在帖子上方的评论中找到更多信息:
- 休眠并从交换文件恢复(发布者针对 Arch Linux 使用的方法)
- 电源管理/挂起和休眠 - 休眠至 Btrfs 上的交换文件