ZFS:有没有办法找出文件的块存储在哪里?

ZFS:有没有办法找出文件的块存储在哪里?

在 zfs 中是否有办法找出特定文件的块存储在哪里?我希望能够询问文件的所有块的位置,包括 ditto 块。

(是的,我明白这是通常不会向用户公开的低级内容。)

(v0.6.0.56-rc8,ZFS 池版本 28,ZFS 文件系统版本 5,Ubuntu 11.10)

答案1

这不是一件小事,可能超出了 SF 问答的范围,因为所需的工具似乎没有很好的记录。你也许可以使用1分贝结合磁盘格式doc 来查找所需信息。有一个博客介绍如何执行此操作这里

本质上

用于ls -i获取初始 inode。

用于zdb -ddddd <inodenum>获取块信息并使用 ODF 对其进行解码

答案2

ZFS 使用 DVA(设备虚拟地址)偏移量 + 长度来物理存储数据。您可以使用以下方式获取相关数据zdb -bbb -vvv <dataset> -O <filename>。您应该记住:

  • ZFS 将 DVA 偏移存储在磁盘上的 512 字节扇区中,因此zdb将其转换为字节
  • zdb以十六进制格式输出此类数字
  • 偏移量 0 从每个磁盘上的 4 MB 标头之后开始。

例如,在刚刚创建的(其他为空的)测试池中:

root@localhost:~# zpool status
  pool: tank
 state: ONLINE
config:

        NAME                     STATE     READ WRITE CKSUM
        tank                     ONLINE       0     0     0
          /root/disks/disk1.img  ONLINE       0     0     0

root@localhost:~# cp /etc/services /tank/
root@localhost:~# zdb -bbb -vvv tank -O services
...
Indirect blocks:
               0 L0 DVA[0]=<0:10007000:4000> [L0 ZFS plain file]

# some math:
# 0x10007000 == 268464128 == 65543 4K blocks
# 65543 + 1024 4K blocks (header) == 66567 4K blocks
# our file starts at 4k offset 66567

# check with dd over the raw device (a backing file, in this test)
root@localhost:~# dd if=/root/disks/disk1.img bs=4k count=1 skip=66567 | head -3
1+0 records in
1+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 2.3434e-05 s, 175 MB/s
# Network services, Internet style
#
# Updated from https://www.iana.org/assignments/service-names-port-numbers...

一些参考资料:

https://utcc.utoronto.ca/~cks/space/blog/solaris/ZFSDVAOffsetVdevDetails https://utcc.utoronto.ca/~cks/space/blog/solaris/ZFSDVAOffsetsInBytesII

答案3

您可以使用ls -i它来查看初始 inode,之后我建议您阅读已发布的源代码以了解磁盘上的数据结构。完成此操作后,我建议您编写自己的工具来读取原始设备并收集您感兴趣的所有块布局信息。有一个小型的 ZFS API(libzfs)项目,仅提供基本的 ZFS 配置,如列出、创建等。zpools。

答案4

在 FreeBSD 上,你可以使用以下命令获取文件的对象 ID统计(1)

stat -f %i /your/file

当然,ls -i也可以这样,但必须使用 grep 之类的命令从 ls 的输出中解析数字。

相关内容