问题
I am not being able to check this via experiments and could not gather it from the man pages as well.
Say I have two processes, one moving(rename) file1 from directory1 to directory2. Say the other process running concurrently copies the contents of directory1 and directory2 to another location. Is it possible that the copy happens in such a way that both directory1 and directory2 will show file1 - i.e directory1 is copied before the move and directory2 after the move by the first process.
Basically is rename() is an atomic system call?
Thanks
回答1:
Yes and no.
rename() is atomic assuming the OS does not crash. It cannot be split by any other filesystem op.
If the system crashes you might see a ln() operation instead.
Also note, when operating on a network filesystem, you might get ENOENT when the operation succeeded successfully. Local filesystem can't do that to you.
回答2:
This is a very late answer, but... yes rename()
is atomic but not in the sense of your question. Under Linux, rename(2)
says:
However, when overwriting there will probably be a window in which both oldpath and newpath refer to the file being renamed.
But rename()
is still atomic in a very important sense: if you use it to overwrite a file, then you will end up with either the old or the new version and nothing else.
[update: but as @jonas-wielicki points out in the comments, you need to make sure the file you are renaming actually has up-to-date contents, using fsync()
and friends.]
If newpath already exists it will be atomically replaced (subject to a few conditions; see ERRORS below), so that there is no point at which another process attempting to access newpath will find it missing.
If you see ERRORS, you will find that the rename might fail, but it will never break the atomicity.
This is all from the Linux man page. What I don't know is if you do a rename()
on a network file-system where the server runs a different OS. Does the client have a hope in hell of guaranteeing atomicity then? I doubt it.
回答3:
I'm not sure the "basically" part of your question is valid. Unless you have some kind of synchronization between the two, it doesn't matter how atomic rename is. If the directory copy gets there before the rename, you are going to have file1 in both places.
I'm not sure if you meant thread or processes, but if there are locking mechanisms for both, threading locks are by far the simplest because they don't have to cross process boundaries.
回答4:
the gnu libc manual says
One useful feature of rename is that the meaning of newname changes “atomically” from any previously existing file by that name to its new meaning (i.e., the file that was called oldname). There is no instant at which newname is non-existent “in between” the old meaning and the new meaning. If there is a system crash during the operation, it is possible for both names to still exist; but newname will always be intact if it exists at all.
来源:https://stackoverflow.com/questions/7054844/is-rename-atomic