This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: tar --atime-preserve with an empty file triggers a warning


[adding bug-tar]

On 03/07/2011 07:43 AM, Corinna Vinschen wrote:
>>> Of course the empty.tar is created as expected (ie identical as without
>>> `--atime-preserve). The warning is not produced on Solaris, Darwin or
>>> Linux,
>>> therefore i contacted this list. Do you think, with your expertise, that i
>>> should contact bug-tar also?
>>
>> No, this list is correct.  utime should not fail on an empty file, so
>> you've probably exposed a bug in cygwin1.dll.
> 
> THis looks like a tar bug, per the strace.  For some reason, if the
> file is empty, tar calls futimens on file descriptor 0 (which is
> connected to /dev/tty1 in my case), while it call futimens on
> file descriptor 4 (connected to the file empty) if the file empty
> is... well, not empty.

This is indeed multiple bug reports for the price of 1 :)

When I strace the same thing on Linux with tar 1.23 (actually,
tar-1.23-7.fc14 of Fedora), I see:

lstat("a", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
utimensat(AT_FDCWD, "a", {{1299509299, 962839134}, {1299509299,
962839134}}, 0) = 0

Empty file optimization - tar skipped opening and reading from "a", and
called utimensat to adjust "a" itself.

lstat("b", {st_mode=S_IFREG|0664, st_size=2, ...}) = 0
open("b", O_RDONLY)                     = 4
read(4, "b\n", 2)                       = 2
fstat(4, {st_mode=S_IFREG|0664, st_size=2, ...}) = 0
utimensat(4, NULL, {{1299509302, 688833576}, {1299509302, 688833576}},
0) = 0
close(4)                                = 0

Non-empty file; tar opened "b", read it, then called futimens on the
open fd.

Tar should NOT be calling utimensat() on an empty file, since this is
inherently racy (the file could have been made non-empty between when
tar stat'ed it as empty and when tar issues the utimensat).  Besides, if
we _know_ the file is empty at the time we did the stat, and didn't open
it, then we didn't modify the atime in the first place, so we can avoid
the race entirely by avoiding the attempt to restore the atime.

Then, when I upgrade to the latest tar.git, post-1.25, still on Linux, I
see:

newfstatat(AT_FDCWD, "a", {st_mode=S_IFREG|0664, st_size=0, ...},
AT_SYMLINK_NOFOLLOW) = 0
dup2(0, 0)                              = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
utimensat(0, NULL, {{1299510124, 243649745}, {1299510141, 910632470}},
0) = 0
newfstatat(AT_FDCWD, "b", {st_mode=S_IFREG|0664, st_size=2, ...},
AT_SYMLINK_NOFOLLOW) = 0
...
openat(AT_FDCWD, "b", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC) = 4
fstat(4, {st_mode=S_IFREG|0664, st_size=2, ...}) = 0
read(4, "b\n", 2)                       = 2
fstat(4, {st_mode=S_IFREG|0664, st_size=2, ...}) = 0
dup2(4, 4)                              = 4
fstat(4, {st_mode=S_IFREG|0664, st_size=2, ...}) = 0
utimensat(4, NULL, {{1299510125, 985648045}, {1299510125, 985648045}},
0) = 0
close(4)                                = 0

So indeed, something in the latest tar is trying to call futimens on fd
0 when encountering an empty file, which is the wrong file to be
changing timestamps for.

Finally, cygwin is failing with EINVAL for futimens on a pty fd.
However, I don't know if that's something that we can change, since
cygwin doesn't really maintain a notion of changeable times on ptys at
the moment.

-- 
Eric Blake   eblake@redhat.com    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]