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

标签 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(文件系统)上列出(文件名,crtime)对,然后在目标fs上使用debugfs -w来读取具有以下形式的行的脚本

set_inode_field filename crtime <value>


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


但是我的目标文件系统不是ext4,而是ZFS,尽管debugfs在目标计算机上运行,​​但在那里完全没有用。它甚至不识别fs。另一个调试工具fsdb是使您可以通过直接编辑inode来更改时间戳的工具。它也可以在目标计算机上运行,​​但是我似乎还是无法识别ZFS文件系统。
卖给我NAS盒的人告诉我,debugfs和fsdb不适用于ZFS文件系统,但是它们还不能提供等效的文件系统。因此,经过大量的搜索和尝试后,我终于决定今天在这里发布一个问题,希望有人能得到答案。


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

最佳答案

实际上,fsdbdebugfs都不适合与ZFS一起使用。您可能需要做的是找到一种存档格式,该格式将保留crtime字段,该字段可能已经为文件服务器上的文件设置了。如果您的系统有pax版本或其他归档工具,则可以执行此操作(请参见-pepax“保留所有内容”标志,在当前版本中似乎不能保留“所有内容” ”-即,它不保留crtime / birth_time)。与试图通过使用可能是基本工具的基于ZFS的FreeBSD系统进行黑客攻击来尝试设置创建时间相比,找到“ crtime感知”的归档应用程序可能会获得更大的成功。

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

core utils bug report可能会阐明Linux上用户和操作系统级别工具的状态。可以说,索引节点的文件系统级别crtime字段应该很难更改。尽管FreeBSD上的ZFS“支持” crtime,但FreeBSD上的低级文件系统调试工具的状态在较早的发行版中可能没有跟上(参见zdb手册页)。您确定要“设置”(或重置)inode创建时间吗?还是要在已经支持它们的系统上设置它们后保留它们?

在FreeBSD系统上,如果您stat存储在ZFS数据集上的文件,您通常会注意到该文件的crtime字段设置为与ctime字段相同的时间。这可能是因为编写文件的应用程序无权访问文件“出生”及其创建的inode条目时设置crtime所需的库和内核功能。有一些应用程序/库的示例,它们尝试在应用程序级别上保留crtime,例如libarchive(3)(另请参见:archive_entry_atime(3)),如果归档文件在不支持< cc>字段。但这可能与您的情况无关。

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

对我来说,在crtime下运行此小脚本可确认在我的FreeBSD系统上“打开”了文件创建时间(所有系统都使用ZFS发布sh birthtime_test,即带有功能标志):

#!/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


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

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

还有一件事 ...

对于简单的“取证”而言,这是一个特别好的功能。假设我们想将我们的-m文件发送回时间开始,回到从未发生过的the秒,以及在-永恒的时刻-Unix诞生... :-) 1.我们可以更改使用-a约会,每个人都会认为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联系以获取有关如何访问touch -d信息的线索。



[1]最初有一段传说声称,由于long秒,很久以前(SSL)以来的秒数始终不小于new_born

关于filesystems - 如何在ZFS中设置文件创建时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29906359/

相关文章:

swift - iOS SWIFT 和 Parse 获取日期和时间

Vim 的 cscope 连接在每次 GNU screen 重新连接时中断

clang - 在 Freebsd 上启用黄金链接器

windows - 来自另一个线程的套接字关闭调用是否总是使阻塞的 recv() 线程唤醒?

php - 试图用php删除linux中的一个目录和他的隐藏文件

asp.net - 如何组织和操作文件系统中的图片?

Python os.walk 和日本文件名崩溃

python - 从 python 脚本运行 C# 应用程序

php - 使用 PHP 将 MySQL 条目的年龄截断为最接近的时间单位

mysql - 联合mariadb中的n个表并根据时间戳找到不同的值