不能在 ZFS 上使用交换文件:有漏洞的文件

sla*_*bin 3 xubuntu swap zfs 19.10

我正在尝试swapfile按照本教程添加一个新的来增加交换空间。

swapfile创建成功,但是,该swapon命令将不接受它:说“跳绳-它似乎有洞。” .

我在 root 上使用 ZFS 运行 Xubuntu 19.10。

这是我迄今为止尝试过的:

创建交换文件

使用fallocate- 失败

sudo fallocate -l 8G /swapfile
fallocate: fallocate failed: Operation not supported
Run Code Online (Sandbox Code Playgroud)

似乎 fallocate 目前不支持 ZFS

替代方式 - 使用dd- 成功

sudo dd if=/dev/zero of=/swapfile bs=1MiB count=$((8*1024))
8192+0 records in
8192+0 records out
8589934592 bytes (8.6 GB, 8.0 GiB) copied, 2.68284 s, 3.2 GB/s
Run Code Online (Sandbox Code Playgroud)

准备交换文件 - 成功

sudo chmod 600 /swapfile
ls -lah /swapfile 
-rw------- 1 root root 8.0G Dec 27 14:15 /swapfile

sudo mkswap /swapfile
Setting up swapspace version 1, size = 8 GiB (8589930496 bytes)
no label, UUID=db8aa64c-734c-4eba-a803-72db681ec1a1
Run Code Online (Sandbox Code Playgroud)

启用交换文件 - 失败

sudo swapon /swapfile
swapon: /swapfile: skipping - it appears to have holes.
Run Code Online (Sandbox Code Playgroud)

swapon 手册

带孔的文件

内核中的交换文件实现期望能够直接写入文件,而无需文件系统的帮助。这是有漏洞的文件或 Btrfs 等文件系统上的写时复制文件的问题。

cp(1) 或 truncate(1) 之类的命令会创建带有漏洞的文件。这些文件将被 swapon 拒绝。

fallocate(1) 创建的预分配文件也可能被解释为有漏洞的文件,具体取决于文件系统。从 Linux 4.18 开始,XFS 支持预分配的交换文件。

创建交换文件的最便携的解决方案是使用 dd(1) 和 /dev/zero。

如何在swapon命令接受的ZFS 上创建交换文件?

系统信息:

sudo parted -l

Model: WDC PC SN520 SDAPNUW-512G-1002 (nvme)
Disk /dev/nvme0n1: 512GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system     Name                  Flags
 1      1049kB  538MB   537MB   fat32           EFI System Partition  boot, esp
 2      538MB   590MB   52.4MB  ext4
 3      590MB   2738MB  2147MB  linux-swap(v1)
 4      2738MB  4885MB  2147MB  zfs
 5      4885MB  512GB   507GB   zfs
Run Code Online (Sandbox Code Playgroud)
sudo zpool list -v

NAME          SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
bpool        1.88G   131M  1.75G        -         -     0%     6%  1.00x    ONLINE  -
  nvme0n1p4  1.88G   131M  1.75G        -         -     0%  6.82%      -  ONLINE  
rpool         472G   112G   360G        -         -     9%    23%  1.00x    ONLINE  -
  nvme0n1p5   472G   112G   360G        -         -     9%  23.8%      -  ONLINE
Run Code Online (Sandbox Code Playgroud)
sudo zfs list

# https://pastebin.ubuntu.com/p/6jDVwbhfCT/
Run Code Online (Sandbox Code Playgroud)
sudo lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 19.10
Release:    19.10
Codename:   eoan
Run Code Online (Sandbox Code Playgroud)
sudo uname -a

Linux iCyberRoze 5.3.0-24-generic #26-Ubuntu SMP Thu Nov 14 01:33:18 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

str*_*tus 8

我认为您想要的实际上在ZFSOnlinux页面上有详细记录

TLDR;

# To set swap on a zfs drive:
zfs create -V 8G -b $(getconf PAGESIZE) -o logbias=throughput -o sync=always -o primarycache=metadata -o com.sun:auto-snapshot=false VMs/swap

mkswap -f /dev/zvol/VMs/swap
swapon /dev/zvol/VMs/swap

# IN FSTAB
/dev/zvol/VMs/swap none swap discard 0 0
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回复,但这不是问题的重点。此解决方案用于创建 zvol 并将其用作交换,但问题是关于在 zfs 分区上创建交换文件。 (4认同)
  • 但是,我理解这个问题,当 Linux 项目上的 ZFS 有记录的方式使用 ZFS 交换时,这就是您应该走的路。在 ZFS 卷上创建文件与 ZFS 的预期使用方式背道而驰。因此,这样做可能会遇到奇怪的问题。最终,我不确定您为什么不遵循记录的方法。我没有看到在 ZVOL 上有一个文件具有其他不需要的属性或可能冲突或使交换无用的好处。(单独写交换的副本会很糟糕) (4认同)
  • 感谢您的担忧,但是,我想您应该评论说,在您看来,这样做并不是一个好的解决方案,而不是强制采用一个不能解决此问题的解决方案。 (2认同)

小智 4

您链接的教程并不假设您的根文件系统是 ZFS。ZFS联机帮助页指出:

ZFS 卷作为交换

ZFS 卷可以用作交换设备。使用命令创建卷后,zfs create -V使用 mkswap(8) 和 swapon(8) 命令设置并启用交换区域。不要交换到 ZFS 文件系统上的文件。不支持 ZFS 交换文件配置。

您可以按照 stratus 的另一个答案中的说明从 zvol 获取交换空间,该交换空间可用作 ZFS 池一部分的交换空间。

但是,如果您确实想继续使用存储在 ZFS 文件系统中的交换文件的建议:

fallocate不适用于 ZFS 文件系统,正如您从已发布的 zfsonlinux github bug 中了解到的那样。dd您可能希望快速创建一个可以在 ZFS 文件系统上创建的大型稀疏文件,而不是使用速度较慢的命令,因为它必须写入输出文件的每一部分,请尝试执行相同truncate操作但适用于 ZFS 的命令。

sudo truncate -s 8G /swapfile
sudo chmod 600 /swapfile
sudo swapon /swapfile
Run Code Online (Sandbox Code Playgroud)

它仍然显示:swapon: /swapfile: skipping - it appears to have holes.

ls -lsh /swapfile
Run Code Online (Sandbox Code Playgroud)

报告512 -rw------- 1 root root 8.0G Jan 17 18:27 /swapfile显示,创建的文件仅占用 512 字节,而不是 8 GB。

您对包含此文件的 ZFS 文件系统的压缩设置很可能会导致输出dd稀疏(占用的磁盘空间比报告的文件大小少得多)。

sudo dd if=/dev/zero of=/swapfile bs=1M count=8k status=progress
ls -lsh /swapfile
Run Code Online (Sandbox Code Playgroud)

报告512 -rw-rw-r-- 1 root root 8.0G Jan 17 18:39 /swapfile显示,ZFS 文件系统压缩设置使完整的 8 GB 文件适合 512 字节。

您可以使用不可压缩的输入,而不是使用高度dd可压缩的输入,这样它实际上会占用 8 GB 的硬盘空间。然而根据我的测试,swapon 仍然拒绝它:/dev/zero/dev/urandom

sudo dd if=/dev/urandom of=/swapfile bs=1M count=8k status=progress
sudo chmod 600 /swapfile
sudo swapon /swapfile
Run Code Online (Sandbox Code Playgroud)

它仍然显示:swapon: /swapfile: skipping - it appears to have holes.

另一项实验可能是在关闭压缩的 ZFS 文件系统中进行尝试。

sudo zfs create rpool/swap -o compression=off -o mountpoint=/swap/
sudo dd if=/dev/zero of=/swap/swapfile bs=1M count=8k status=progress
Run Code Online (Sandbox Code Playgroud)

这次它确实将全 0 写入磁盘。

ls -lsh /swap/swapfile
Run Code Online (Sandbox Code Playgroud)

此报告返回8.0G -rw-r--r-- 1 root root 8.0G Jan 17 18:52 /swap/swapfile

sudo chmod 600 /swap/swapfile
sudo swapon /swap/swapfile
Run Code Online (Sandbox Code Playgroud)

它仍然显示:swapon: /swapfile: skipping - it appears to have holes.

我的结论是,我无法判断是否有一种方法可以规避其拒绝使用位于 ZFS 文件系统中的文件作为交换文件的情况。

超出这个问题的范围,在此系统上使用交换空间的替代方案是交换分区(我看到您已经有一个590MB交换分区,或者将交换文件放在非 ZFS 文件系统上,例如 ext4 分区上) ,或者如果磁盘空间不可用,请使用Zswap(用作交换空间的 RAM 压缩块)或vramfs(位于显卡 RAM 上的交换空间)。