無縫更換 symbolic link 所指的目錄或檔案

這邊如果把 atomatically 翻成原子性好像怪怪的,就照意思來翻好了。

這是一篇 2005 年的文章,講如何更換 symbolic link 內容,而且確保 symbolic link 不會短時間不見:「How to change symlinks atomically」。

作者拿了 strace 解釋 ln -snf 的例子,來說明這個方法沒辦法做到無縫:

$ strace ln -snf new current 2>&1 | grep link
unlink("current")         = 0
symlink("new", "current") = 0

unlink()symlink() 中間的 race condition 如果有人存取這個 symbolic link 就會失敗。作者提了這樣的方法來解決:

$ ln -s new current_tmp && mv -Tf current_tmp current

在「How does one atomically change a symlink to a directory in busybox?」這邊雖然提問的是 BusyBox,但道理相同,提到了怎麼做以及為什麼 (不要看綠色勾勾那個,看分數比較高的那個):

This can indeed be done atomically with rename(2), by first creating the new symlink under a temporary name and then cleanly overwriting the old symlink in one go.

DocumentRoot 是 symbolic link 時,這點變得很重要。這個方法才能避免切換目錄的過程中間不會有空檔,導致使用者收到 404...

另外通常會配合 mod_realdoc 一起用,避免程式用到 DocumentRoot 的路徑而導致前面指到的東西跟後面指到的東西不同。