I have two files, A
and B
, each with its own content.
I would like to swap these two files, so A
would become B
, and B
would become A
. But I would like to do with a guaranty that no other process will find these two files in an inconsistent state, nor any process will find any of those files missing, even for a short while. So, as a side operation, I would also like to have a guaranty that if anything would go wrong during the operation, nothing will be changed (kind of like a transaction I guess).
On OS X there is a exchangedata()
function, so I guess I'm looking for a Linux equivalent of it, or at least an equivalent method for doing atomic file swap.
You can use the (fairly recent) linux syscall renameat2
Here is the definition :
int renameat2(int olddir, const char *oldname,
int newdir, const char *newname, unsigned int flags);
You can find its source code on the kernel's Git repo if needed.
It's basically the same as renameat
, but if you pass the flag RENAME_EXCHANGE it will swap the two files instead of renaming one into the other.
The operation is atomic.
I depends on what you mean by "inconsistent state". If it is acceptable for there to be a period of time during which the two files are identical, then you can simply do:
ln A C
ln B D
ln -f D A
# now, A and B have the same content
ln -f C B
It also depends on the behavior you want for processes that already have the file opened. Remember that paths are not files, but merely links to a file, so if process 1 opens a file via the path 'A', and then you swap the names A and B, process 1 will still have the file opened that was referred to by the name A.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With