bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Eric Blake
Subject: [Bug-tar] Re: tar --atime-preserve with an empty file triggers a warning
Date: Mon, 07 Mar 2011 08:07:20 -0700
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Lightning/1.0b3pre Mnenhy/0.8.3 Thunderbird/3.1.7

[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   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]