如何在ZFS中设置文件创建时间?

Sil*_*evy 9 filesystems inode timestamp freebsd zfs

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

是否有类似于ZFS的debugfs的工具?

PS.为了更好地解释:

  • 我有一个USB驱动器连接到Ubuntu 14.04笔记本电脑.它拥有一个文件系统,我关心各个文件的创建日期(出生日期).我经常使用基于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文件系统,但他们无法提供等效的功能.所以,经过大量的谷歌搜索和尝试的事情后,我终于决定今天在这里发一个问题,希望有人可能有答案.

我很惊讶这是多么艰难的结果.从档案的角度来看,如何复制数据集使所有时间戳都相同的问题似乎很自然.

G. *_*ito 5

实际上,既不适合fsdb也不debugfs适合与ZFS一起使用.您可能需要做的是找到一个存档格式,该格式将保留crtime字段,该字段可能已经为文件服务器上的文件设置.如果有一个版本的pax为你的系统或其他归档工具可能是能够做到这一点(参见-pe的"保留一切"的标志pax,它似乎在目前的版本中并没有保留"一切" - .即它不保留crtime/ birth_time).crtime通过使用可能是基本工具的基于ZFS的FreeBSD系统进行攻击,您可能会更有成功地找到" 意识到" 的归档应用程序,而不是尝试设置创建时间.

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

这个核心工具错误报告可能会对Linux上用户和操作系统级工具的状态有所了解.可以说,crtimeinode 的文件系统级别字段应该很难改变.虽然ZFS FreeBSD的 "支持" 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 post,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
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

(注意: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
Run Code Online (Sandbox Code Playgroud)

它总是更真实实际上为你看看:-)年轻

时间和Unix - 一个既实用又富有诗意的主题:毕竟,什么是"改变"; "修改"或"创造"某些东西意味着什么?感谢您的精彩帖子Silvio - 我希望它继续存在并收集有用的答案.


如果您可以更加具体地了解保存,设置和归档文件时间戳字段的要求,则可以改进和概括您的问题.不要误会我的意思:这是一个非常好的问题,它将继续长期赢得选票.

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


[1]有一个传说在开始时声称,从很久以来的秒数(SSL)之前从未date -u -j -f "%Y-%m-%d:%T" "1970-01-01:00:00:01" "+%s"因为闰秒而减少......

  • Cito - 您可以修改答案的第一段,因为 pax -pe 不会保留出生时间或更改时间。(man pax 说:“保留所有内容”,即用户 ID、组 ID、文件模式位、文件访问时间和文件修改时间。)不过,谢谢您向我介绍 pax。(我还可能指出一个小错字:它是 cf. 而不是 cf ——它来自一个单词,拉丁语“confer”,意思是“比较”。) (2认同)