Subject: bug#36818: mv fails to clobber target if it's a hardlink of a source

From: Eric Blake <[email-masked]>
Date: Fri, 26 Jul 2019 13:01:44 -0500

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