Atomically swap contents of two files on Linux

ε祈祈猫儿з 提交于 2020-01-01 11:34:29

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/27862057/atomically-swap-contents-of-two-files-on-linux

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!