I have a symlink that points to a directory mounted via network file system like so:
2023 -> /mnt/bulk013/obs_data_archive/metwatch/2023/
now I want to replace the symlink with the folder that it points to in a fashion that doesn't disturb a productive application that frequently reads from this directory (atomically). This meant in my case first copying all the data to my local harddrive (where the folder 2023 lives). I did so and used a temporary directory to store the files:
2023.tmp/
So now the question is, how can I atomically switch the symlink with the actual folder, so that the folder then has the name 2023?
2023 -> /mnt/bulk013/obs_data_archive/metwatch/2023/ # remove this
2023.tmp/ # and replaced with this (renamed to 2023)
In brief notation, if we have:
and want to swizzle this to become:
It would seem that what we want is to execute the system call
rename("dir", "link/").Unfortunately, that refuses to work on Linux with an
errnoof 20 (ENOTDIR). This is documented forrenameby POSIX: one of the reasonsrenamecan returnENOTDIRis:Looks like there may not be a way to do this; it has to be done in two operations, requiring the accessing application to be suspended.
If the application consists of a small number of processes, you may be able to
kill -STOPthem all, do the swizzle, and thenkill -CONT. To a stopped process, the operation will appear atomic.