Discussion:
I am confused about the configure rename managing hardlinks test.
(too old to reply)
John E. Malmberg
2017-09-29 23:13:50 UTC
Permalink
Raw Message
Hello,

I am confused about the rename managing hardlinks test.

It starts out with conftest.f as an empty file and conftest.fl as a hard
link to conftest.f.

Step 1:
rename ("conftest.f", "conftest.f1")

I would expect after a success, conftest.f would no longer exist, only
conftest.f1.

Step 2:
unlink ("conftest.f1")

Now I would expect confest.f1 to not exist after this.

Step 3 is what confuses me.

rename("conftest.f", "conftest.f") which is expected to work.

How can this succeed if "conftest.f" was removed in step 1?

Regards,
-John
Eric Blake
2017-09-29 23:43:03 UTC
Permalink
Raw Message
Post by John E. Malmberg
Hello,
I am confused about the rename managing hardlinks test.
It starts out with conftest.f as an empty file and conftest.fl as a hard
link to conftest.f.
    rename ("conftest.f", "conftest.f1")
I would expect after a success, conftest.f would no longer exist, only
conftest.f1.
Sadly, your expectations are contrary to the POSIX requirements, that if
two (possibly different hard-links) names point to the same inode, then
rename() is a no-op rather than removing one of the two names. This
behavior is historical, even though it violates the principle of least
surprise, so the kernel can't really change it, and GNU coreutils 'mv'
has to go to great lengths to work around this shortcoming in the
syscall specification.

The new Linux renameat2() syscall would have to add a new RENAME_ flag
if we wanted any saner behavior (although there has also been a recent
report that one of the BSD's wrote a broken rename() syscall that
behaves sanely by default). But until someone implements that, and we
can rely on it, then you must assume that "conftest.f" still exists
after this no-op call.
Post by John E. Malmberg
    unlink ("conftest.f1")
Now I would expect confest.f1 to not exist after this.
Correct.
Post by John E. Malmberg
Step 3 is what confuses me.
   rename("conftest.f", "conftest.f") which is expected to work.
How can this succeed if "conftest.f" was removed in step 1?
Because it wasn't removed in step 1.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
John E. Malmberg
2017-09-30 00:25:50 UTC
Permalink
Raw Message
Post by Eric Blake
Post by John E. Malmberg
Hello,
I am confused about the rename managing hardlinks test.
It starts out with conftest.f as an empty file and conftest.fl as a hard
link to conftest.f.
    rename ("conftest.f", "conftest.f1")
I would expect after a success, conftest.f would no longer exist, only
conftest.f1.
Sadly, your expectations are contrary to the POSIX requirements, that if
two (possibly different hard-links) names point to the same inode, then
rename() is a no-op rather than removing one of the two names. This
behavior is historical, even though it violates the principle of least
surprise, so the kernel can't really change it, and GNU coreutils 'mv'
has to go to great lengths to work around this shortcoming in the
syscall specification.
I suspected something like that.

I have read and re-read:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html

And I do not see anything in that text that states the behavior would be
a noop when the source and destination links to the same file.
Post by Eric Blake
The new Linux renameat2() syscall would have to add a new RENAME_ flag
if we wanted any saner behavior (although there has also been a recent
report that one of the BSD's wrote a broken rename() syscall that
behaves sanely by default). But until someone implements that, and we
can rely on it, then you must assume that "conftest.f" still exists
after this no-op call.
The OpenVMS rename() removes the "conftest.f" and creates a "conftest.f1;2"
Post by Eric Blake
Post by John E. Malmberg
    unlink ("conftest.f1")
Now I would expect confest.f1 to not exist after this.
Correct.
Except on OpenVMS of course, it removes "conftest.f1;" leaving the
original "conftest.f1".
Post by Eric Blake
Post by John E. Malmberg
Step 3 is what confuses me.
   rename("conftest.f", "conftest.f") which is expected to work.
How can this succeed if "conftest.f" was removed in step 1?
Because it wasn't removed in step 1.
Ok, now I need to do with the OpenVMS specific code.

Thanks,
-John
Bruno Haible
2017-09-30 01:10:35 UTC
Permalink
Raw Message
Post by John E. Malmberg
http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html
And I do not see anything in that text that states the behavior would be
a noop when the source and destination links to the same file.
It's in the third paragraph, the sentence about
"different directory entries for the same existing file".

Bruno

Loading...