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:
link -> dir/
and want to swizzle this to become:
link/
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 errno of 20 (ENOTDIR). This is documented for rename by POSIX: one of the reasons rename can return ENOTDIR is:
the old argument names a directory and the new argument names a non-directory file
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 -STOP them all, do the swizzle, and then kill -CONT. To a stopped process, the operation will appear atomic.
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