GNU bug report logs - #8374
cp -a [-l] sometimes does not preserve timestamps of symlinks

Previous Next

Package: coreutils;

Reported by: Ruediger Meier <ruediger.meier <at> ga-group.nl>

Date: Tue, 29 Mar 2011 16:31:01 UTC

Severity: normal

Done: Pádraig Brady <P <at> draigBrady.com>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 8374 in the body.
You can then email your comments to 8374 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#8374; Package coreutils. (Tue, 29 Mar 2011 16:31:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Ruediger Meier <ruediger.meier <at> ga-group.nl>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Tue, 29 Mar 2011 16:31:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ruediger Meier <ruediger.meier <at> ga-group.nl>
To: bug-coreutils <at> gnu.org
Subject: cp -a [-l] sometimes does not preserve timestamps of symlinks
Date: Tue, 29 Mar 2011 15:46:07 +0200
Hi,


I see you fixed that already for for cp -a
http://marc.info/?t=124897089600001&r=1&w=2

But it does not together with option -link:

cd /tmp/
ln -s somewhere symlink
touch -h -t "197001010000"  symlink
cp -a symlink symlink-a
cp -al symlink symlink-al
ls -l symlink*
lrwxrwxrwx 1 rudi users 9 1970-01-01 00:00 symlink -> somewhere
lrwxrwxrwx 1 rudi users 9 1970-01-01 00:00 symlink-a -> somewhere
lrwxrwxrwx 1 rudi users 9 2011-03-29 13:44 symlink-al -> somewhere


I'm using core utils coreutils 8.9 (opensuse 11.4).

BTW with coreutils 7.1 and 6.9 it behaves the other way, -al is correct 
but -a not.

So probably -al is broken since you fixed -a in 7.5.



cu,
Rudi  




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#8374; Package coreutils. (Thu, 31 Mar 2011 14:13:02 GMT) Full text and rfc822 format available.

Message #8 received at 8374 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Ruediger Meier <ruediger.meier <at> ga-group.nl>
Cc: 8374 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com>
Subject: Re: bug#8374: cp -a [-l] sometimes does not preserve timestamps of
	symlinks
Date: Thu, 31 Mar 2011 15:11:42 +0100
On 29/03/11 14:46, Ruediger Meier wrote:
> Hi,
> 
> 
> I see you fixed that already for for cp -a
> http://marc.info/?t=124897089600001&r=1&w=2
> 
> But it does not together with option -link:
> 
> cd /tmp/
> ln -s somewhere symlink
> touch -h -t "197001010000"  symlink
> cp -a symlink symlink-a
> cp -al symlink symlink-al
> ls -l symlink*
> lrwxrwxrwx 1 rudi users 9 1970-01-01 00:00 symlink -> somewhere
> lrwxrwxrwx 1 rudi users 9 1970-01-01 00:00 symlink-a -> somewhere
> lrwxrwxrwx 1 rudi users 9 2011-03-29 13:44 symlink-al -> somewhere
> 
> 
> I'm using core utils coreutils 8.9 (opensuse 11.4).
> 
> BTW with coreutils 7.1 and 6.9 it behaves the other way, -al is correct 
> but -a not.
> 
> So probably -al is broken since you fixed -a in 7.5.

Hmm it looks now like we're creating symlinks (with wrong timestamps),
but in fact we should be creating hardlinks to symlinks.

This seems to have been changed with:
http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commit;h=3346c0af

Eric do you have any suggestions?
The following seems to make things work as expected

diff --git a/src/copy.c b/src/copy.c
index a672fd3..4f07d2c 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -2226,8 +2226,7 @@ copy_internal (char const *src_name, char const *dst_name,
      where link(2) follows the link, gnulib creates a symlink with
      identical contents, which is good enough for our purposes).  */
   else if (x->hard_link
-           && (!S_ISLNK (src_mode)
-               || x->dereference != DEREF_NEVER))
+           && !(S_ISLNK (src_mode) && x->dereference != DEREF_NEVER))
     {
        if (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0))
         {

Hmm, maybe it's better to skip linkat() for symlinks altogether
since the gnulib fallback on systems that implicitly dereference,
will create symlinks, but without the right timestamps.
Or, perhaps the gnulib fallback should try to update timestamps too?

cheers,
Pádraig.




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#8374; Package coreutils. (Thu, 31 Mar 2011 14:21:01 GMT) Full text and rfc822 format available.

Message #11 received at 8374 <at> debbugs.gnu.org (full text, mbox):

From: Eric Blake <eblake <at> redhat.com>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: 8374 <at> debbugs.gnu.org, bug-gnulib <bug-gnulib <at> gnu.org>,
	Ruediger Meier <ruediger.meier <at> ga-group.nl>
Subject: Re: bug#8374: cp -a [-l] sometimes does not preserve timestamps of
	symlinks
Date: Thu, 31 Mar 2011 08:20:16 -0600
[Message part 1 (text/plain, inline)]
[adding bug-gnulib]

On 03/31/2011 08:11 AM, Pádraig Brady wrote:
>> So probably -al is broken since you fixed -a in 7.5.
> 
> Hmm it looks now like we're creating symlinks (with wrong timestamps),
> but in fact we should be creating hardlinks to symlinks.
> 
> This seems to have been changed with:
> http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commit;h=3346c0af
> 
> Eric do you have any suggestions?
> The following seems to make things work as expected
> 
> diff --git a/src/copy.c b/src/copy.c
> index a672fd3..4f07d2c 100644
> --- a/src/copy.c
> +++ b/src/copy.c
> @@ -2226,8 +2226,7 @@ copy_internal (char const *src_name, char const *dst_name,
>       where link(2) follows the link, gnulib creates a symlink with
>       identical contents, which is good enough for our purposes).  */
>    else if (x->hard_link
> -           && (!S_ISLNK (src_mode)
> -               || x->dereference != DEREF_NEVER))
> +           && !(S_ISLNK (src_mode) && x->dereference != DEREF_NEVER))
>      {
>         if (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0))
>          {
> 
> Hmm, maybe it's better to skip linkat() for symlinks altogether
> since the gnulib fallback on systems that implicitly dereference,
> will create symlinks, but without the right timestamps.
> Or, perhaps the gnulib fallback should try to update timestamps too?

Sounds to me like the gnulib fallback should be made smarter.  Which
systems lack linkat() but have the capability to set timestamps?  BSD?
But the original report was about opensuse, which is Linux based, and my
recollection is that Linux handles hardlinks to symlinks much longer
than it could set symlink timestamps.

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

[signature.asc (application/pgp-signature, attachment)]

Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#8374; Package coreutils. (Thu, 31 Mar 2011 15:00:03 GMT) Full text and rfc822 format available.

Message #14 received at 8374 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Eric Blake <eblake <at> redhat.com>
Cc: 8374 <at> debbugs.gnu.org, bug-gnulib <bug-gnulib <at> gnu.org>,
	Ruediger Meier <ruediger.meier <at> ga-group.nl>
Subject: Re: bug#8374: cp -a [-l] sometimes does not preserve timestamps of
	symlinks
Date: Thu, 31 Mar 2011 15:58:50 +0100
On 31/03/11 15:20, Eric Blake wrote:
> Sounds to me like the gnulib fallback should be made smarter.  Which
> systems lack linkat() but have the capability to set timestamps?  BSD?
> But the original report was about opensuse, which is Linux based, and my
> recollection is that Linux handles hardlinks to symlinks much longer
> than it could set symlink timestamps.

When you put it like that, then it's probably not worth
worrying about updating timestamps in gnulib, when it's probably
not even possible.

cheers,
Pádraig.




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#8374; Package coreutils. (Fri, 01 Apr 2011 11:10:02 GMT) Full text and rfc822 format available.

Message #17 received at 8374 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Ruediger Meier <ruediger.meier <at> ga-group.nl>
Cc: 8374 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com>
Subject: Re: bug#8374: cp -a [-l] sometimes does not preserve timestamps of
	symlinks
Date: Fri, 01 Apr 2011 12:08:55 +0100
[Message part 1 (text/plain, inline)]
On 31/03/11 15:11, Pádraig Brady wrote:
> On 29/03/11 14:46, Ruediger Meier wrote:
>> Hi,
>>
>>
>> I see you fixed that already for for cp -a
>> http://marc.info/?t=124897089600001&r=1&w=2
>>
>> But it does not together with option -link:
>>
>> cd /tmp/
>> ln -s somewhere symlink
>> touch -h -t "197001010000"  symlink
>> cp -a symlink symlink-a
>> cp -al symlink symlink-al
>> ls -l symlink*
>> lrwxrwxrwx 1 rudi users 9 1970-01-01 00:00 symlink -> somewhere
>> lrwxrwxrwx 1 rudi users 9 1970-01-01 00:00 symlink-a -> somewhere
>> lrwxrwxrwx 1 rudi users 9 2011-03-29 13:44 symlink-al -> somewhere
>>
>>
>> I'm using core utils coreutils 8.9 (opensuse 11.4).
>>
>> BTW with coreutils 7.1 and 6.9 it behaves the other way, -al is correct 
>> but -a not.
>>
>> So probably -al is broken since you fixed -a in 7.5.
> 
> Hmm it looks now like we're creating symlinks (with wrong timestamps),
> but in fact we should be creating hardlinks to symlinks.
> 
> This seems to have been changed with:
> http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commit;h=3346c0af

That commit didn't actually change the logic as far as I can see.
It was actually ca9e212c that introduced the logic bug I think.

So I'm going to apply the attached.

cheers,
Pádraig.
[cp-al-timestamps.diff (text/x-patch, attachment)]

Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#8374; Package coreutils. (Fri, 01 Apr 2011 12:22:02 GMT) Full text and rfc822 format available.

Message #20 received at 8374 <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: 8374 <at> debbugs.gnu.org, Eric Blake <eblake <at> redhat.com>,
	Ruediger Meier <ruediger.meier <at> ga-group.nl>
Subject: Re: bug#8374: cp -a [-l] sometimes does not preserve timestamps of
	symlinks
Date: Fri, 01 Apr 2011 14:21:29 +0200
Pádraig Brady wrote:
...
>> Hmm it looks now like we're creating symlinks (with wrong timestamps),
>> but in fact we should be creating hardlinks to symlinks.
>>
>> This seems to have been changed with:
>> http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=commit;h=3346c0af
>
> That commit didn't actually change the logic as far as I can see.
> It was actually ca9e212c that introduced the logic bug I think.
>
> So I'm going to apply the attached.
...
> Subject: [PATCH] copy: link rather than copy symlinks, when --link used
>
> This bug was introduced in commit ca9e212c, 2009-09-24,
> "cp, mv: use linkat to guarantee semantics", which
> inadvertently disabled the creation of hardlinks to symlinks.
> However rather than implementing the intention of that commit
> and relying on gnulib linkat emulation, we'll revert to the
> previous emulation as that maintains ownership and timestamps.
>
> * src/copy.c (copy_internal): Use our existing hardlink to
> symlink emulation when we're not sure that link() will
> not dereference the symlink.  Also ensure that we copy the

How about "...when link() might dereference..."

> timestamps of the original symlink when we use the emulation.
> * tests/cp/link-symlink: Add a test to ensure timestamps copied.
> * tests/Makefile.am: Reference the new test.
> * NEWS: Mention the fix.
> Reported by Ruediger Meier
> ---
>  NEWS                  |    4 ++++
>  src/copy.c            |   27 ++++++++++++++++++++-------
>  tests/Makefile.am     |    1 +
>  tests/cp/link-symlink |   41 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 66 insertions(+), 7 deletions(-)
>  create mode 100755 tests/cp/link-symlink
>
> diff --git a/NEWS b/NEWS
> index 6d66355..f25a696 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -20,6 +20,10 @@ GNU coreutils NEWS                                    -*- outline -*-
>    wc would dereference a NULL pointer upon an early out-of-memory error
>    [bug introduced in coreutils-7.1]
>
> +  cp -a --link would not create a hardlink to a symlink, instead
> +  copying the symlink and then not preserving its timestamp.
> +  [bug introduced in coreutils-8.0]

Please move that "up" so they're alphabetized.

>    dd now accepts the 'nocache' flag to the iflag and oflag options,
> diff --git a/src/copy.c b/src/copy.c

Thanks for fixing that!




Reply sent to Pádraig Brady <P <at> draigBrady.com>:
You have taken responsibility. (Fri, 01 Apr 2011 13:57:02 GMT) Full text and rfc822 format available.

Notification sent to Ruediger Meier <ruediger.meier <at> ga-group.nl>:
bug acknowledged by developer. (Fri, 01 Apr 2011 13:57:02 GMT) Full text and rfc822 format available.

Message #25 received at 8374-done <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
Cc: 8374-done <at> debbugs.gnu.org
Subject: Re: bug#8374: cp -a [-l] sometimes does not preserve timestamps of
	symlinks
Date: Fri, 01 Apr 2011 14:55:22 +0100
On 01/04/11 13:21, Jim Meyering wrote:
>> * src/copy.c (copy_internal): Use our existing hardlink to
>> symlink emulation when we're not sure that link() will
>> not dereference the symlink.  Also ensure that we copy the
> 
> How about "...when link() might dereference..."

Much clearer thanks.

I've pushed that.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 30 Apr 2011 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 14 years and 54 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.