GNU bug report logs - #36818
mv fails to clobber target if it's a hardlink of a source

Previous Next

Package: coreutils;

Reported by: Sergei Trofimovich <slyfox <at> gentoo.org>

Date: Fri, 26 Jul 2019 17:45:02 UTC

Severity: normal

Done: Sergei Trofimovich <slyfox <at> gentoo.org>

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 36818 in the body.
You can then email your comments to 36818 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 bug-coreutils <at> gnu.org:
bug#36818; Package coreutils. (Fri, 26 Jul 2019 17:45:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Sergei Trofimovich <slyfox <at> gentoo.org>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Fri, 26 Jul 2019 17:45:02 GMT) Full text and rfc822 format available.

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

From: Sergei Trofimovich <slyfox <at> gentoo.org>
To: bug-coreutils <at> gnu.org
Subject: mv fails to clobber target if it's a hardlink of a source
Date: Fri, 26 Jul 2019 18:43:51 +0100
The below is a bug initially reported by Xuefer at https://bugs.gentoo.org/646412.

Reproducer:

  $ mv --version
  mv (GNU coreutils) 8.31
  Packaged by Gentoo (8.31 (p0))

  $ touch a.aa
  $ ln a.aa b.bb
  $ mv a.aa b.bb
  mv: 'a.aa' and 'b.bb' are the same file

For comparison if fines are unrelated 'mv' just works:

  $ touch a.aa
  $ touch b.bb
  $ mv a.aa b.bb
  $ echo $?
  0

Fun fact: busybox does not complain about hardlinked files:

  $ touch a.aa
  $ ln a.aa b.bb
  $ busybox mv a.aa b.bb
  $ echo $?
  $ echo $?
  0

Some context on where these accidentally hardlinked files come from:

gdb build system simplistically does the following:
    $ gcc a.c -o a.tmp.o && mv a.tmp.o a.o

ccache has a mode to create a resulting file by hardlinking
if possible instead of copying data round.

If the above command is ran without ccache wrapper 'a.tmp.o'
is always a new file. Otherwise if it's ran via ccache with
CCACHE_HARDLINK=1 then 'a.tmp.o' and 'a.o' and both
hardlinks of a file stored in cache originally.

Is it an 'mv's bug or a feature to prevent hardlinked file clobbering?
If feels like an unnecessary restriction.

Thank you!

-- 

  Sergei




Information forwarded to bug-coreutils <at> gnu.org:
bug#36818; Package coreutils. (Fri, 26 Jul 2019 18:02:02 GMT) Full text and rfc822 format available.

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

From: Eric Blake <eblake <at> redhat.com>
To: Sergei Trofimovich <slyfox <at> gentoo.org>, 36818 <at> debbugs.gnu.org
Subject: Re: bug#36818: mv fails to clobber target if it's a hardlink of a
 source
Date: Fri, 26 Jul 2019 13:01:44 -0500
[Message part 1 (text/plain, inline)]
On 7/26/19 12:43 PM, Sergei Trofimovich wrote:

> Is it an 'mv's bug or a feature to prevent hardlinked file clobbering?
> If feels like an unnecessary restriction.

It's a POSIX (mis-)feature that for hard links, rename("file1", "file2")
is a mandatory no-op (no error, but also no change to the existence or
contents of either file1 or file2).  Back under POSIX 2001, mv was
required to behave identically to the rename() syscall.  But this was
confusing enough that POSIX 2008 relaxed the wording as follows,
inspired in part by complaint from GNU coreutils:

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/mv.html

"If the source_file operand and destination path resolve to either the
same existing directory entry or different directory entries for the
same existing file, then the destination path shall not be removed, and
one of the following shall occur:

    No change is made to source_file, no error occurs, and no diagnostic
is issued.

    No change is made to source_file, a diagnostic is issued to standard
error identifying the two names, and the exit status is affected.

    If the source_file operand and destination path name distinct
directory entries, then the source_file operand is removed, no error
occurs, and no diagnostic is issued."

The difference between GNU coreutils and busybox both appear to be
compliant behaviors (you didn't actually show after the 'mv' command
whether a.aa still exists, so I can't tell whether busybox implemented
option 1 or option 3; but it appears GNU implemented option 2).  Option
1 is probably the least intuitive but is the historical behavior when
you use rename() without any checking.  Option 2 at least points out the
issue that your usage is not going to be universally portable.  Option 3
is closest to what happens when there are no hard links.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

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

Information forwarded to bug-coreutils <at> gnu.org:
bug#36818; Package coreutils. (Fri, 26 Jul 2019 18:24:02 GMT) Full text and rfc822 format available.

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

From: Sergei Trofimovich <slyfox <at> gentoo.org>
To: Eric Blake <eblake <at> redhat.com>, 36818-done <at> debbugs.gnu.org
Cc: 36818 <at> debbugs.gnu.org
Subject: Re: bug#36818: mv fails to clobber target if it's a hardlink of a
 source
Date: Fri, 26 Jul 2019 19:23:22 +0100
[Message part 1 (text/plain, inline)]
On Fri, 26 Jul 2019 13:01:44 -0500
Eric Blake <eblake <at> redhat.com> wrote:

> On 7/26/19 12:43 PM, Sergei Trofimovich wrote:
> 
> > Is it an 'mv's bug or a feature to prevent hardlinked file clobbering?
> > If feels like an unnecessary restriction.  
> 
> It's a POSIX (mis-)feature that for hard links, rename("file1", "file2")
> is a mandatory no-op (no error, but also no change to the existence or
> contents of either file1 or file2).  Back under POSIX 2001, mv was
> required to behave identically to the rename() syscall.  But this was
> confusing enough that POSIX 2008 relaxed the wording as follows,
> inspired in part by complaint from GNU coreutils:
> 
> https://pubs.opengroup.org/onlinepubs/9699919799/utilities/mv.html
> 
> "If the source_file operand and destination path resolve to either the
> same existing directory entry or different directory entries for the
> same existing file, then the destination path shall not be removed, and
> one of the following shall occur:
> 
>     No change is made to source_file, no error occurs, and no diagnostic
> is issued.
> 
>     No change is made to source_file, a diagnostic is issued to standard
> error identifying the two names, and the exit status is affected.
> 
>     If the source_file operand and destination path name distinct
> directory entries, then the source_file operand is removed, no error
> occurs, and no diagnostic is issued."
> 
> The difference between GNU coreutils and busybox both appear to be
> compliant behaviors (you didn't actually show after the 'mv' command
> whether a.aa still exists, so I can't tell whether busybox implemented
> option 1 or option 3;

Oh, I did not realize source file did not disappear.

Looks like busybox's behaviour is an 'option 1':

  $ ls -i a.aa b.bb
  208636260 a.aa  208636260 b.bb

  $ strace -f busybox mv a.aa b.bb
  ...
  stat("b.bb", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
  access("b.bb", W_OK)                    = 0
  rename("a.aa", "b.bb")                  = 0
  exit_group(0)                           = ?
  +++ exited with 0 +++

  $ ls -i a.aa b.bb
  208636260 a.aa  208636260 b.bb

> but it appears GNU implemented option 2).  Option
> 1 is probably the least intuitive but is the historical behavior when
> you use rename() without any checking.  Option 2 at least points out the
> issue that your usage is not going to be universally portable.  Option 3
> is closest to what happens when there are no hard links.

Thank you for the quick response. The bug can be closed as WAI then.

-- 

  Sergei
[Message part 2 (application/pgp-signature, inline)]

Reply sent to Sergei Trofimovich <slyfox <at> gentoo.org>:
You have taken responsibility. (Fri, 26 Jul 2019 18:24:02 GMT) Full text and rfc822 format available.

Notification sent to Sergei Trofimovich <slyfox <at> gentoo.org>:
bug acknowledged by developer. (Fri, 26 Jul 2019 18:24:03 GMT) Full text and rfc822 format available.

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

This bug report was last modified 4 years and 245 days ago.

Previous Next


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