Atomical swap contents of two files in Linux

I have two files: A

and B

, each with its own content.

I would like to swap these two files, so A

will become B

, and B

will become A

. But I would like to make sure that no other process finds these two files in an inconsistent state, and neither of the processes finds any of these files, even for a short time. So, as a side operation, I would also like to be sure that if something goes wrong during the operation, nothing will change (like a transaction, I guess).

OS X has a feature exchangedata()

, so I'm guessing I'm looking for a Linux equivalent, or at least an equivalent method for sharing kernel files.

+3


source to share


2 answers


You can use the (fairly recent) linux syscallrenameat2

Here's the definition:

int renameat2(int olddir, const char *oldname, 
      int newdir, const char *newname, unsigned int flags);

      



You can find its source code in the core Git repo if needed.

This is basically the same as, renameat

but if you pass the RENAME_EXCHANGE flag, it will replace the two files instead of renaming them to another.

The operation is atomic.

+7


source


Depending on what you mean by "inconsistent state". If it is acceptable that there is a period of time during which the two files are identical, 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 a file open. Remember that paths are not files, they are just file references, so if process 1 opens a file on path "A" and then you change the names A and B, process 1 will still have the file passed by named A.

+1


source







All Articles