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

From: Sergei Trofimovich <[email-masked]>
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