[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#6960: mv refuses to move a symlink over a hard link to the same file
From: |
Eric Blake |
Subject: |
bug#6960: mv refuses to move a symlink over a hard link to the same file |
Date: |
Tue, 31 Aug 2010 17:30:19 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100806 Fedora/3.1.2-1.fc13 Mnenhy/0.8.3 Thunderbird/3.1.2 |
On 08/31/2010 04:48 PM, Davide Brini wrote:
A simpler example is something like
$ touch New_York
$ ln -s New_York New_York.sym
$ mv New_York.sym New_York
mv: `New_York.sym' and `New_York' are the same file
I think the reason is that when the source is a symbolic link, mv operates
on the symlink itself, not the file it points to. So, it can't rename the
symlink, because if successful that would imply having two entries named
"New_York" in the same directory.
Not quite. POSIX specifies that:
http://www.opengroup.org/onlinepubs/9699919799/utilities/mv.html
If the source_file operand and destination path name the same existing
file, then the destination path shall not be removed, and one of the
following shall occur:
1. No change is made to source_file, no error occurs, and no
diagnostic is issued.
2. No change is made to source_file, a diagnostic is issued to
standard error identifying the two names, and the exit status is affected.
3. 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 question boils down to whether "New_York" and "New_York.sym" name
the same file (stat semantics), or whether, since mv generally operates
on symlinks rather than dereferencing them, they are distinct files
(lstat semantics).
Solaris /usr/xpg4/bin/mv (which is supposedly POSIX-compliant, although
we could debate that) goes ahead with the move:
$ touch a
$ ln -s a b
$ /usr/xpg4/bin/mv b a
$ echo $? ?
0 a
$ readlink a
a
Certainly, the underlying rename() call is allowed to replace a file
with a symlink, even if the symlink was to the file that it was
replacing (and thus will create an ELOOP situation on the symlink while
losing the contents that were pointed to). So, in that regards, you
could argue that Solaris' behavior is dangerous (it lost data) while
coreutils is playing it safe, when the destination has a link count of 1
in this simplified example. But when the destination has a link count
of 2, there is no data loss, so the original example seems like it is
pointing out a case where coreutils is over-strict.
And I would argue that the strict POSIX wording says that we should only
be refusing to move if the two files have the same inode; in both the
original and simplified examples, the symlink has a different inode than
the file it would be overwriting, so I think POSIX mandates that the
data destruction happen rather than the coreutils behavior.
Maybe this would argue for a POSIXLY_CORRECT behavior choice? :(
Maybe we need to raise this as a question to the Austin Group to argue
that coreutils behavior should be permitted?
If this is really the reason for the
error, the error message could probably be improved.
This part is true - the error message could definitely be more precise,
if we decide that POSIX even lets us issue an error in the first place.
--
Eric Blake address@hidden +1-801-349-2682
Libvirt virtualization library http://libvirt.org