Date: Mon, 3 Feb 2020 18:48:58
From: Carl Edquist <address@hidden>
To: address@hidden
Subject: cpio -m does not preserve timestamps for symlinks
It seems that for a cpio archive that contains symlinks, the timestamps for
those symlinks are not getting preserved, even with the '-m' option.
A quick strace shows that in '-m' mode, utimensat(2) gets called for all the
regular files and directories, to restore their timestamps, but no attempt is
made to restore it for symlinks (even though utimensat(2) does allow that
with AT_SYMLINK_NOFOLLOW).
At first I was not sure if this was going to be a bug report or a feature
request, so I took a look at the latest cpio-2.13 sources.
There is an inline wrapper function called 'lutimensat' around utimensat with
AT_SYMLINK_NOFOLLOW, but it is never referenced anywhere else in the sources.
And there is a more complicated 'lutimens' function which contains some
#ifdefs to try to do the right thing as best it can to set symlink timestamps
if possible.
'lutimens' is defined in utimens.c and referenced in utimensat.c, which
includes at-func.c, which is a maze of macros that's a bit hard to follow.
So it seems that the intention in cpio is to handle setting timestamps for
symlinks. But in any case that code path does not seem to get reached for
me, even with the latest cpio-2.13. (I'm using Linux kernel 4.15.0, gcc
7.4.0, and gnu libc 2.27.)
Easy reproducer:
$ ln -s . selfie
$ touch -hd '2000-01-01 12:34:56' selfie
$ echo selfie | cpio -o > selfie.cpio
$ cpio -tv < selfie.cpio
lrwxrwxrwx 1 root root 1 Jan 1 2000 selfie -> .
$ rm selfie
$ cpio -im < selfie.cpio
$ ls -l selfie
lrwxrwxrwx 1 root root 1 Feb 3 18:10 selfie -> .
Note the timestamp of the 'selfie' symlink was not preserved.
Can the current maintainers confirm whether this might be broken?
Thanks,
Carl