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

时间:2015-04-27 21:34:15

标签: filesystems timestamp freebsd inode zfs

我刚刚运行了一个运行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)对列表,然后在目标fs上使用debugfs -w来读取带有

    形式行的脚本

    set_inode_field filename crtime <value>

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

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

  • 我告诉那些向我销售NAS框的人们,debugfs和fsdb并不适用于ZFS文件系统,但是他们还没有能够提供相应的功能。所以,经过大量的谷歌搜索和尝试的事情后,我终于决定今天在这里发一个问题,希望有人可能有答案。

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

1 个答案:

答案 0 :(得分:5)

实际上,fsdbdebugfs都不适合与ZFS一起使用。您可能需要做的是找到一个存档格式,该格式将保留crtime字段,该字段可能已经为文件服务器上的文件设置。如果您的系统有版本pax或其他归档工具,则可以执行此操作( cf。 -pe&#34;保留所有内容&#34; pax的标记在当前版本中似乎 保留&#34;一切&#34; - 即。它确实不保留crtime / birth_time)。您可能会更成功地找到一个&#34; crtime知道的归档应用程序&#34;通过使用可能是基本工具的基于ZFS的FreeBSD系统进行攻击来尝试设置创建时间。

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

这个core utils bug report可能会对Linux上用户和操作系统级工具的状态有所了解。可以说,inode 的文件系统级crtime字段应该很难改变。虽然ZFS 在FreeBSD上&#34;支持&#34; crtime,FreeBSD上的低级文件系统调试工具的状态可能没有跟上早期版本( c.f。 zdb手册页)的步伐。你确定要&#34;设置&#34; (或重置)inode创建时间?或者,您是否希望在已经支持它们的系统上设置它们后保留它们?

在FreeBSD系统上,如果stat存储在ZFS数据集中的文件,您会经常注意到文件的crtime字段设置为ctime字段的同一时间。这可能是因为编写该文件的应用程序无法访问文件出生时设置crtime所需的库和内核函数&#34;并创建了它的inode条目。有些应用程序/库试图在应用程序级别保留crtime,例如libarchive(3)(另请参阅:archive_entry_atime(3)),并且如果在文件系统上还原存档,则可以正常处理inode创建这不支持crtime字段。但这可能与您的情况无关。

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

对于我来说,运行这个小脚本sh birthtime_test确认文件创建时间是&#34;打开&#34;在我的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操作&#34;更改&#34;但不修改&#34;文件内容 - 这是echo命令添加内容的功能有关touch-m标志的说明,请参阅-a手册页。

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

还有一件事......

这是一个特别好的功能,简单的&#34;取证&#34;。假设我们希望在时间开始时将我们的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--一个既实用又富有诗意的主题:毕竟,什么是&#34;改变&#34 ;;什么是&#34;修改&#34;或&#34;创建&#34;什么?感谢您的精彩帖子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" ...