2

We need to backup the a/c/mtime-stamps of files and directories, and have the ability to restore them if necessary.

An example command to back up could be:

$ timestamp backup --all-stamps --incl-dir-stamps --recursive out.stampbak file.bin /dir/with/files/

And to restore could be:

$ timestamp restore --all-stamps out.stampbak

Does such a command exist to achieve the results I'm looking for? Nanosecond accuracy would be preferred, or anything else more granular, although I believe most filesystems stop at nanoseconds. POSIX compliance is also important as we need timestamps on both BSD and GNU/Linux systems to be backed/restored.


Edit: To clarify a few things, the filesystems I listed are, for the most part, holding on to files for now until I can ultimately move them to a master ZFS server. This is what made us consider the possibility of preserving time stamps before migrating data to ZFS. Just in case stamps were to change during the transfer process (we use several methods like HTTP, FTP, SMB), we want to ensure they can be restored to what they should be. Even post transfer, it would be beneficial to retain the timestamps as a small backup, so regardless of the fact the files will end up on ZFS, the question is still about backing/restoring timestamps only. Permissions and group information can be omitted from the backup.

The operating systems used for backing up timestamps include macOS Mojave 10.14.6, Ubuntu Server 18.04.5 LTS, Debian 10.2/7.8, FreeBSD 12.2 and CentOS 8. Restoring will mainly be done on the FreeBSD (ZFS server host), I don't think it will be necessary anywhere else. If it helps to mention, I have a few drives with files on NTFS partitions. Is it necessary to run a small Windows instance to back these stamps up properly?

Furthermore I was under the impression most filesystems used atime, ctime and mtime, and no others (I assume this ultimately differs between filesystems). My goal is to save and restore all of them, if possible.

I mentioned POSIX compliance in that, the tool can be used on either platform--I apologize if my description earlier was incorrect or inadequate. I also thought ctime = creation/birth time, I now see it's change time.

The timestamps of most importance to be retained are creation/birth time and modification time. Access time would be nice as well, change time is of least importance but would still help to have. Again, I apologize for the error, I'm still learning.


Edit 2: From this article I learned this:

  • there’s no file creation timestamp kept in most filesystems – meaning you can’t run a command like “show me all files created on certain date”. This said, it’s usually possible to deduce the same from ctime and mtime (if they match – this probably means that’s when the file was created).

  • When a new file or directory is created, usually all three times – atime, ctime and mtime – are configured to capture the current time.

Since the destination filesystem will be ZFS where timestamps of files/directories will be restored, it is probably best to at least save atime, ctime, mtime in case the filesystem the timestamps were saved from does not store a birthtime.

2
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Jeff Schaller
    Sep 16, 2021 at 11:06
  • Note that the article you found is 13 years old — things have changed since then. Sep 16, 2021 at 20:39

3 Answers 3

3

If you have GNU find and Perl available, you could rig something up with them. The -printf action to find can print the timestamps, and Perl has the utime function to modify them. Or two, the builtin one, and one in the Time::HiRes module, the latter supports subsecond precision.

Some files for testing:

$ find . -printf '%A@ %T@ %p\n'
1631866504.4180281370 1631866763.5380257720 .
1631866763.5380257720 1631866768.2101700800 ./dir
1631866768.2101700800 1631866768.2101700800 ./dir/bar.txt
1631866760.2619245850 1631866760.2619245850 ./foo.txt

Save the timestamps to a file:

$ find . -printf '%A@ %T@ %p\0' > ../times

Let's trash the timestamps:

$ touch -d 1999-01-01 **/*
$ find . -printf '%A@ %T@ %p\n'
1631866771.6022748540 1631866763.5380257720 .
915141600.0000000000 915141600.0000000000 ./dir
915141600.0000000000 915141600.0000000000 ./dir/bar.txt
915141600.0000000000 915141600.0000000000 ./foo.txt

and reload them from the file:

$ perl -MTime::HiRes=utime -0 -ne 'chomp; my ($atime, $mtime, $file) = split(/ /, $_, 3); utime $atime, $mtime, $file;'    < ../times
1631866771.6022748950 1631866763.5380258560 .
1631866771.6022748950 1631866768.2101700310 ./dir
1631866768.2101700310 1631866768.2101700310 ./dir/bar.txt
1631866760.2619245050 1631866760.2619245050 ./foo.txt

The file simply contains NUL-terminated fields with the atime, mtime and the filename, and the Perl snippet calls utime for each set of values.

With NUL as terminator, it should be able to deal with arbitrary filenames, but note that I used \n instead of \0 for the printouts here, which won't work with that Perl snippet, since it expects NUL, and not newline.

Also, I completely ignored ctime, since as far as I know, it can't be set with utime()/utimensat() anyway. Same for any birth timestamps.

1

As discussed before already, the only way to set ctime and similar is from inside the kernel and the userland interfaces for good reason do not allow to set timestamps beyond atime and mtime. If you like to retain ctime and crtime, this could be done with ZFS/send and ZFS/receive, but this requires to have ZFS on both sides already.

So let me repeat what I believe what you like to do:

  • Copy an existing filesystem to another location

  • Retain atime and mtime while doing this copy or restore timestamps by a different program later on.

You could do this either by running any backup/restore method followed by another program that restores timestamps or by runnung a backup/restore method that is able to correctly restore timestamps.

star is a mature backup tool, that could help you with both methods.

If you like to use star to backup and restore the filesystems including the time stamps, please have a look at the man page at: http://schilytools.sourceforge.net/man/man1/star.1.html

If you like to save and restore the time stamps separately, you need to save the timestamps before you run the backup, because the backup will most likely affect the atime values of all files.

  • To save all timetamps of all files from a directory tree, simply run:

    star -c -dump -meta f=timestamparchive.tar .
    
  • To restore all timestamps to the new location, run:

    star -xU -meta f=timestamparchive.tar
    

The archive file created by the first command uses approx. 1.5 kBytes per file. The second command will restore all timestampt from all files in the archive, that exist already, but will not touch the file content.

BTW: I am the author of star since 39 years.

1
-1

The "ls --full-time" command gives a full timestamp for files which can be formatted with "awk" and saved to a file named with the current time using "date":

ls --full-time | awk '{print $6"\t"$7"\t"$9}' > timestamps.output.`date +%Y-%m-%d_%k:%M:%S.%N`

This yields something like:

timestamps.output.2021-09-16_16:33:05.363928457:

2021-09-16  16:13:40.988062443  file1
2021-09-16  16:13:45.408053173  file2
2021-09-16  16:13:49.496044596  file3
2021-09-16  16:13:52.628038023  file4

This would allow you to keep track of changes in the timestamps of files over time. Of course you can format the timestamps however you like.

You could also use a "git" repository to keep track of timestamp.output file changes over time.

2
  • 3
    Welcome to the site, and thank you for your contribution. Please note however that your post doesn't address a key point of the question - how to apply the backed-up timestamps to the files again after they have been copied to a new filesystem.
    – AdminBee
    Sep 17, 2021 at 11:56
  • This will fail for file names with whitespace (spaces, tabs, newlines etc.) since $9 will only be the first word of the file. You're also skipping the time zone field and you're using the full-iso time format so that can be different for different files. I have some +0300 and some +0200 in my home dir.
    – terdon
    Sep 23, 2021 at 8:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.