Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Atomically replace symlink with the folder it points to

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)
like image 435
glades Avatar asked Dec 23 '25 02:12

glades


1 Answers

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.

like image 140
Kaz Avatar answered Dec 24 '25 22:12

Kaz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!