复制或恢复 ext4fs 文件系统上文件/目录的 crtime

Art*_*nov 2 backup ext4 restore debugfs

我想知道 2020 年是否有方法复制或恢复 Linux 中 inode/文件/目录的 crtime(创建时间)。我不小心删除了一个文件夹,而我仍然有完整的磁盘备份,但 cp -a 和 rsync 都没有可以恢复/复制文件/目录crtimes。

我找到了一种使用 debugfs 来实现它的方法,但它非常复杂,我需要自动化它(我有数百个已删除的文件/目录)。

对于源磁盘,您可以执行以下操作:

# debugfs /dev/sdXX
# stat /path
Inode: 432772   Type: directory    Mode:  0700   Flags: 0x80000
Generation: 3810862225    Version: 0x00000000:00000006
User:  1000   Group:  1000   Project:     0   Size: 4096
File ACL: 0
Links: 5   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5db96479:184bb16c -- Wed Oct 30 15:22:49 2019
 atime: 0x5b687c70:ee4dff18 -- Mon Aug  6 21:50:56 2018
 mtime: 0x5db96479:184bb16c -- Wed Oct 30 15:22:49 2019
crtime: 0x5b687c70:d35d1348 -- Mon Aug  6 21:50:56 2018
Size of extra inode fields: 32
Extended attributes:
  security.selinux (40)
EXTENTS:
(0):1737229
Run Code Online (Sandbox Code Playgroud)

记住 crtime,这是两个字段,crtime_lo(是的,第一个)和crtime_hi(第二个)

然后对于目标磁盘,您可以执行以下操作:

# debugfs -w /dev/sdYY
# set_inode_field /path crtime_lo 0x${1st_value_from_earlier}
# set_inode_field /path crtime_hi 0x${2nd_value_from_earlier}
Run Code Online (Sandbox Code Playgroud)

也许 debugfs 手册中还缺少一些可以帮助我做到这一点的东西,所以如果人们可以提供帮助,我会很高兴。

-f cmd_file确实似乎是一个不错的开始方式,但对我来说仍然有点太难了。

Art*_*nov 6

其实我已经自己解决了。在尝试之前你永远不知道自己能做什么:-)

即使所有文件系统都以读写方式安装,它也必须安全运行。

#! /bin/bash

dsk_src=/dev/sdc4 # source disk with original timestamps
mnt_src=/mnt/sdc4 # source disk mounted at this path
dsk_dst=/dev/sda4 # destination disk
directory=user/.thunderbird # the leading slash _must_ be omitted

cd $mnt_src || exit 1

find $directory -depth | while read name; do
    read crtime_lo crtime_hi < <(debugfs -R "stat \"/$name\"" $dsk_src 2>/dev/null | awk '/crtime:/{print $2}' | sed 's/0x//;s/:/ /')

    echo "File: $name"
    echo "crtime_lo: $crtime_lo"
    echo "crtime_hi: $crtime_hi"

    debugfs -w $dsk_dst -R "set_inode_field \"/$name\" crtime_lo 0x$crtime_lo"
    debugfs -w $dsk_dst -R "set_inode_field \"/$name\" crtime_hi 0x$crtime_hi"
done
Run Code Online (Sandbox Code Playgroud)

如果人们感兴趣,我可以调整脚本以允许在一个分区内使用它,例如运行后cp -a。实际上这很容易。