I wonder if there are ways to copy or restore crtime (creation time) for inodes/files/directories in Linux in 2020. I’ve accidentally deleted a folder while I still have a full disk backup, but neither cp -a, nor rsync can restore/copy files/directories crtimes.
I have found a way to achieve it using debugfs but it’s super complicated and I need to automate it (I have hundreds of deleted files/directories).
For the source disk you do this:
# 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
Remember the crtime, these are two fields, crtime_lo (yes, the first) and crtime_hi (the second)
Then for the destination disk you do this:
# 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}
Maybe there’s something else I’m missing in the debugfs manual which could help me do that, so I’d be glad if people could help.
-f cmd_file surely seems like a nice way to start but still a little bit too difficult for me.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I’ve actually solved it on my own. You never know what you can do till you try 🙂
It must be safe to run even when all the filesystems are mounted read-write.
#! /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
If people are interested I can adjust the script to allow to use it within one partition as well, e.g. after running cp -a. It’s quite easy actually.
Method 2
If you have a modern tar archive that includes all time stamps, you can do this with star -xp -ctime ... in case you call star as root.
Note that this leẗ́s star cause time storms and should not be done in a serious multi user mode.
See http://schilytools.sourceforge.net/man/man1/star.1.html for moreinformation.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0