On 06/03/16 19:46, Marc Lehmann wrote:
On Sun, Mar 06, 2016 at 02:06:47PM -0700, Bob Proulx <b...@proulx.com> wrote:
The kernel system call rename(2) returns 0 for SUCCESS.  And yet the
operation definitely did not succeed.

It did - this is how rename must behave according to POSIX.

I find the above result surprising!

Right, which isn't asurprising :)

So why did this appear to work previously with previous versions of
coreutils mv command?  Because 'mv' didn't previously rename(2) the
files at all.

It worked because I reported this as a bug long ago, and it was changed.

POSIX allows three behaviours for mv in this case:

    1. silently succeed
    2. issue a disgnostic
    3. unlink the source

So very old coreutils used 1, then switched to 3, and now switched to 2,
essentially to please apple users (the race condition could be fixed by a
rename/unlink combination).

place.  The utilities should not hide race condition behavior.

It could be done without races by first renaming the source to a third
name for example, one that doesn't conflict with a concurrent mv (bceause
it can't know that name).

Nevertheless, mv needs to do more than one system call to detect this issue,
so the change doesn't save on system calls.

The only way to save systems calls would be to silently ignore3 this case
(which is allowed by posix).

the script author still wants the racy behavior then the script author
can perform the same actions explicitly and get identical behavior.)

(which script author?)

If you refer to me, this has nothing to do with scripts, it#s simply me
dpoing mv commands sometimes, and expecting mv to do be useful on my
Debian GNU/Linux box, without thinbking too much about apple users and
their problems because their filesystem isn't posix-compliant.

Which means it was historical behavior on multiple kernels originally
and standardized specifically for the reason that changing it would
make portable programs impossible.

Nothing a rename3 or renameat2 (which already exists) couldn't improve with a
flag. In fact, renameat2 with RENAME_EXCHANGE can already be useful. and
renameat2 with RENAME_NOREPLACE can be useful to save on syscalls to detect
this case.

I hope this additional information helps understand what is happening.

I'm not sure anybody was unclear about it. The bug was about keeping
the existing behaviour as a useful extension to POSIX. Unsurprising
mv behaviour would certainly be a useful extension, but upstream
apparently decided to sacrifice quality for better non-posixs (apple)
compatibility. Tough game, but so be it. I'll just keep a copy of mv for
personal use, problem solved.

I do disagree with your mail's implicationh that this is a technical issue,
though - it isn't. It's a policy issue - what weighs more, surprising
behaviour on non-posix filesystems vs. rational behaviour on posix
filesystems, and the decision went to support non-posix filesystems.


It's not to appease case retentive file systems.
There is a race between multiple mv calls issuing unlink();
The race must be fixed in the kernel.
I proposed a new flag to renameat() on the kernel mailing list,
to get the kernel to handle it. When/If that becomes available,
mv can safely restore this behaviour.

Pádraig

Reply via email to