Windows 未报告使用 ZFS 的 Samba 服务器上正确的已用磁盘空间和可用磁盘空间

Windows 未报告使用 ZFS 的 Samba 服务器上正确的已用磁盘空间和可用磁盘空间

我有一个在 Linux 中运行 ZFS 的 Samba 服务器。

  • 这是标准的按书安装,没有特殊配置。
  • 每个共享都映射到自己的 ZFS 数据集,但并非所有数据集都有自己的共享。

Oracle Linux 9.2 ZFS 2.1.12 Samba 4.17.5

我用了这个 dfree 脚本让 Windows 报告文件资源管理器中正确的已用空间和剩余可用空间:

#!/bin/bash
USED=$((`zfs get -o value -Hp used $1` / 1024)) > /dev/null
AVAIL=$((`zfs get -o value -Hp available $1` / 1024)) > /dev/null
TOTAL=$(($USED+$AVAIL)) > /dev/null
echo -ne $TOTAL $AVAIL

这按预期工作。

然而,这给最终用户带来了困惑:他们看到不同共享的报告容量略有不同,认为这意味着它们必须是不同的服务器,并打电话给我询问原因。

所以我希望 Windows 报告已使用的空间和容量整个 ZFS 池无论份额如何,而不是其份额映射到的单个数据集的报告已用空间和可用空间。

理论上,我应该简单地将 $1 替换为池的名称(在本例中为“tank”),但是报告的磁盘空间在 Windows 中不会改变:

#!/bin/bash
USED=$((`zfs get -o value -Hp used tank` / 1024)) > /dev/null
AVAIL=$((`zfs get -o value -Hp available tank` / 1024)) > /dev/null
TOTAL=$(($USED+$AVAIL)) > /dev/null
echo -ne $TOTAL $AVAIL

在此输入图像描述

各种修补会导致 Windows 报告奇怪的值或根本不报告任何值。

到目前为止,我发现实现这项工作的唯一方法是将 USED 和 AVAIL 硬编码为 zfs get 命令应该返回的内容:

#!/bin/bash
USED=11258621113
AVAIL=28766985099
TOTAL=$(($USED+$AVAIL)) > /dev/null
echo -ne $TOTAL $AVAIL

在此输入图像描述

我错过了一些愚蠢的事情吗?有人让这个工作吗?

谢谢!

答案1

首先,我很遗憾没有为您提供解决方案,因为我无法重现您的问题。我从未在 FreeBSD 机器上的十几个 Samba 实例中使用过dfree command指令,也从未遇到过您所描述的问题。 smb.confSamba 似乎知道如何查询磁盘空间统计信息,并且 Windows 报告合理的磁盘利用率指标。对于具有以下内容的文件系统:

$ zfs list -Hpo used,avail tank/r2d2
2209625051136   1605933772800

Windows 显示:3.32TB 中有 1.45TB 可用

我没有资格肯定地说,但 Samba 无法确定正常数字的根本问题可能在于 ZFS 和 Samba 上游集成的某个缺陷。至少,Samba 应该能够找到 ZFS 文件系统usedavail属性,就像您尝试手动完成的那样。我的所有系统都能自行解决这个问题。

但在更基础的层面上,您的帖子表明您意识到(尽管您的用户可能没有意识到)ZFS 是磁盘存储领域的范式转变。一个明显的提示是您必须计算文件系统的“总”容量。 ZFS 本身没有这个概念(在文件系统级别),而且实际上,没有实用程序size可以访问的属性zfs list

在文件系统级别,used数字available总是很模糊,因为数据本身很模糊。 ZFS 文件系统可以(并且通常)配置为动态压缩数据,而用户不会意识到这一点。因此,用户可能会看到一个有 100G 可用空间的卷,保存了一个可压缩的 10G 文件,然后感到困惑的是,该卷仍然有 95G 可用空间,而不是降至 90G 可用空间。他们会奇怪,服务器的磁盘阵列看似存储了10G的文件,但“可用”空间却只减少了5GB。这是因为压缩对用户来说是透明的

另一种说法是:采用通用 4TB 驱动器。它的“能力”是什么?打电话询问磁盘空间的用户可能会说“4 TB”。但在 ZFS 中,这是物理容量、硬盘空间量、最低限度数字,并且仅在数据不可压缩的情况下为真。如果您的数据是可压缩的,那么总计逻辑的驱动器的容量(这可能是您的用户在询问“我们还有多少存储空间?”时所想到的)可能高于 4 TB。即使使用旧的lz4 压缩算法,我的文件系统的压缩率也超过了 3 倍,其中一个几乎达到了 6 倍。按照该速率,“4 TB”驱动器的容量将在 12 到 24 TB 之间。通过zstd压缩,压缩率可以达到两位数。

困难在于,虽然 ZFS 知道文件的压缩比是多少已存储data 是(usedvs. logicalused),在数据实际写入之前,无法确定“可用”空间的可压缩程度。换句话说,total=used+avail中断是因为虽然used已知,但avail只是最低限度。 total实际上可能超过used+avail,具体取决于您未来的数据存储模式。

在ZFS中文件系统,除了要存储的实际数据的上下文之外,不存在“磁盘容量”这样的东西。当具有已知available值的文件系统存储额外数据时,例如大小为 10G 的文件,它可以以 2:1 压缩,仅消耗 5G 的实际磁盘空间。因此,保存可压缩的 10G 文件可能会导致逻辑容量增加 5GB。存储 10G 数据会导致您的表观“容量”增加 5 GB。这就是您的用户感到困惑的原因。他们不明白标称的驱动器身体的4TB 容量可增加至逻辑的如果用户数据可2:1压缩,则实际用户数据的容量为8TB。跟踪可压缩文件系统中的空间量available始终total是一个不断变化的目标。

IMO 当您说您想要转向在池级别报告磁盘空间指标时,您是在正确的轨道上。这就是我在正常运行时间监控系统中所做的,因为无论压缩级别如何,输出始终反映驱动器上已使用 ( ) 或未使用 ( - )zpool的实际字节数。事实上,在池级别,我们最终找到了“大小”属性,这是 ZFS 文件系统所没有的。已用量和可用量的意义稍小,特别是因为它们反映了 RAID-Z 奇偶校验,但已用量/大小的比率通常是准确的:allocatedsizeallocated

$ zpool list -po cap,alloc,size
  CAP          ALLOC           SIZE
   56  2256319561728  3985729650688
$ bc <<< 'scale=4; 2256319561728/3985729650688'
.5660

大多数人都可以理解为磁盘“已满56%”或“已满92%”。但当他们问:“我们还能存储多少数据?”答案只能是“看情况”。

当您接近您的首选解决方案时,请更新您的帖子。我意识到我在这里发布的所有内容并没有直接解决您的问题,但我想说明这样一个事实:您所面临的困难与技术方法一样根源于用户教育。

答案2

在 Samba 中,共享的磁盘空间报告通常在共享级别完成,而不是在池级别完成。这就是为什么您会看到每个共享的报告容量略有不同,因为它们对应于各个数据集的属性。

如果您希望 Windows 报告整个 ZFS 池的已用空间和容量,您可能需要考虑替代方法,因为修改单个共享的 Samba 磁盘空间报告行为可能很复杂,并且可能不会产生所需的结果。

一种可能的方法是创建一个指向 ZFS 池根的单独共享(例如/tank),然后使用该共享来报告池级磁盘空间。您可以这样做:

  1. 在 Samba 配置文件中创建一个指向 ZFS 池根目录的共享(通常为/etc/samba/smb.conf)。您可以通过添加一个新部分来做到这一点,如下所示:

    [pool-root]
    path = /tank
    read only = yes
    browseable = no
    

    调整路径 ( /tank) 以匹配 ZFS 池的安装点。

  2. 重新启动 Samba 服务以应用配置更改:

    sudo systemctl restart smbd
    
  3. 从 Windows访问pool-root共享,它应该报告整个 ZFS 池的磁盘空间。

请注意,通过创建此特殊共享,用户将能够访问 ZFS 池的根目录,因此请确保设置适当的权限和限制以在必要时限制访问。

请记住,此方法不会修改 Samba 中单个共享级别报告的工作方式。它只是提供一个额外的共享,该共享指向池的根以用于报告目的。

相关内容