9

我刚刚有一个运行 ZFS 的 NAS,我想在将文件传输到其中时保留创建时间。linux/ext4(数据现在所在的位置)和 zfs 都存储创建时间或出生时间。在 zfs 的情况下,它甚至由 stat 命令报告。但我无法弄清楚如何设置文件的创建时间,以便它反映原始文件系统中的创建时间。与 ext4->ext4 传输不同,我可以为 debugfs 提供一个脚本来设置文件创建时间。

有没有类似于 ZFS 的 debugfs 的工具?

PS。为了更好地解释:

  • 我有一个连接到 Ubuntu 14.04 笔记本电脑的 USB 驱动器。它拥有一个文件系统,我关心各个文件的创建日期(出生日期)。我经常使用基于 debugfs 的脚本来查阅这些创建时间戳,该脚本将其报告为 crtime。

  • 我想将数据移动到运行 ZFS 的 NAS 盒中,但我知道的方法(scp -p -r、rsync -a 和 tar 以及我尝试过的其他方法)保留了修改时间,但没有保留创建时间。

  • 如果我要迁移到另一个 ext4 文件系统,我会使用神奇的工具来解决问题debugfs。具体来说,我可以在源 fs(文件系统)上列出 (filename, crtime) 对,然后debugfs -w在目标 fs 上使用以下形式读取脚本

    set_inode_field filename crtime <value>

我已经对此进行了测试,并且效果很好。

  • 但我的目标 fs 不是 ext4 而是 ZFS,虽然debugfs在目标机器上运行,但在那里完全没用。它甚至不识别fs。另一个可以让您通过直接编辑 inode 来更改时间戳的调试工具是 fsdb;它也在目标机器上运行,但我似乎无法让它识别 ZFS 文件系统。

  • 卖给我 NAS 盒子的人告诉我,debugfs 和 fsdb 不适用于 ZFS 文件系统,但他们还没有找到等效的东西。所以,经过大量的谷歌搜索和尝试,我终于决定今天在这里发布一个问题,希望有人能给出答案。

我很惊讶这变得多么困难。从档案的角度来看,如何复制数据集以使所有时间戳都相同的问题似乎很自然。

4

1 回答 1

5

实际上,两者fsdb都不debugfs适合与 ZFS 一起使用。您可能需要做的是找到一种存档格式,该格式将保留crtime可能已经为文件服务器上的文件设置的保留字段。如果pax您的系统有一个版本或另一个存档工具,它可能能够做到这一点(参见-pe保留一切”标志pax,它在当前版本中似乎保留“一切” -它不保留crtime/出生时间)。您可能会更成功地找到“crtime意识到”而不是尝试通过使用可能是基本工具的基于 ZFS 的 FreeBSD 系统来设置创建时间。

您可能能够在基于OpenSolaris的系统上找到更高级的工具,例如IllumosSmartOS例如 mdb)。是否有可能将您的数据传输到其中一个平台上的 ZFS 数据集,然后将他们拥有的工具与例如dtrace重写crtime字段相结合,这更像是一个理论问题。如果它有效,那么您可以将池及其数据集导出到 FreeBSD - 导出池似乎确实保留了crtime时间戳。如果您在将 ext4 文件系统转储到同一主机上的ZFSonLinux数据集能够保留(nbcrtime:我没有测试过这个)然后你可以zfs send用来将整个文件系统传输到你的 NAS。

这个核心 utils 错误报告可能会揭示 Linux 上用户和操作系统级工具的状态。crtime可以说,inode的文件系统级别字段应该很难更改。虽然FreeBSD 上的ZFS “支持” crtime,但 FreeBSD 上低级文件系统调试工具的状态可能跟不上早期版本的步伐(参见zdb手册页)。您确定要“设置”(或重置)inode 创建时间吗?或者您想在它们被设置在已经支持它们的系统上之后保留它们?

在 FreeBSD 系统上,如果您stat将文件存储在 ZFS 数据集上,您通常会注意到crtime文件的字段设置为与ctime字段相同的时间。crtime这可能是因为编写文件的应用程序无法访问在文件“诞生”和创建其 inode 条目时需要设置的库和内核函数。有一些应用程序/库的示例尝试crtime在应用程序级别保留,例如libarchive(3)(另请参阅archive_entry_atime(3):),如果存档在不支持该crtime字段的文件系统上恢复,则可以优雅地处理 inode 创建。但这可能与您的情况无关。

正如您可能想象的那样,有很多应用程序将文件写入文件系统……尤其是对于“一切都是文件”的 Unix/POSIX 系统。我不确定是否需要修改或重新编译旧应用程序以支持这些字段,或者它们是否会从主机系统的 C 库中透明地获取它们。例如,在较旧的 FreeBSD 版本或没有 ext4 的 Linux 系统上使用的应用程序可以在最新的操作系统上以兼容模式运行,但是它们是否能正确处理时间字段是一个很好的问题。

对我来说,运行这个小脚本可以sh birthtime_test确认我的 FreeBSD 系统上的文件创建时间已“打开”(所有这些系统都使用 ZFS 帖子,v28 带有功能标志):

#!/bin/sh
#birthtime_test
uname -r 
if [ -f new_born ] ; then rm -f new_born ; fi

touch new_born 
sleep 3 
touch -a new_born
sleep 3 
echo "Hello from new_born at:" >> new_born 
echo `date` >> new_born
sleep 3 
chmod o+w new_born

stat -f "Name:%t%N
Born:%t%SB
Access:%t%Sa
Modify:%t%Sm 
Change:%t%Sc" new_born

cat new_born

输出:

9.2-RELEASE-p10
Name:   new_born
Born:   May  7 12:38:35 2015
Access: May  7 12:38:38 2015
Modify: May  7 12:38:41 2015 
Change: May  7 12:38:44 2015
Hello from new_born at:
Thu May 7 12:38:41 EDT 2015

(注意:chmod操作“更改”但不“修改”文件内容 - 这是echo命令通过向文件添加内容来执行的操作。有关和 标志touch的说明,请参见手册页)。-m-a

这是我现在可以访问的最古老的 FreeBSD 版本。我很想知道 FreeBSD 在发布周期中能处理多长时间(在 ZFS 或 UFS2 文件系统上)。我很确定这已经是很长一段时间的功能了。还有一些 OSX 和 Linux 版本的 ZFS,了解有关此功能的信息会很有用。

还有一件事 ...

对于简单的“取证”,这是一个特别好的功能。假设我们想将我们的new_born文件发送回时间开始的时间,回到从未发生过的闰秒以及 - 在一个永恒的时刻 - Unix 诞生的时刻...... :-) 1。我们可以更改使用日期touch -d,每个人都会认为new_born老而明智,对吧?

没有:

~/ % touch -d "1970-01-01T00:00:01" new_born                
~/ % stat -f "Name:%t%N   
Born:%t%SB
Access:%t%Sa
Modify:%t%Sm
Change:%t%Sc" new_born
Name:   new_born
Born:   May  7 12:38:35 2015
Access: Jan  1 00:00:01 1970
Modify: Jan  1 00:00:01 1970 
Change: May  7 13:29:37 2015

实际上像你看起来一样年轻总是更真实:-)

时间和Unix——一个既实用又富有诗意的主题:毕竟,什么是“变化”;“修改”或“创造”某物是什么意思?感谢您的精彩帖子 Silvio - 我希望它能够继续存在并收集有用的答案。


如果您可以更具体地了解您对保存、设置、归档文件时间戳字段的要求,您可以改进和概括您的问题。不要误会我的意思:这是一个非常好的问题,并且会在很长一段时间内继续获得投票。

您可以查看 Dylan Leigh 的演示文稿Forensic Timestamp Analysis of ZFS,甚至可以联系 Dylan 以获取有关如何访问crftime信息的线索。


[1] 一开始就有一个传说,自古以来的秒数(SSL)从不小于date -u -j -f "%Y-%m-%d:%T" "1970-01-01:00:00:01" "+%s"因为闰秒......

于 2015-05-05T21:32:14.693 回答