How does one atomically transform a symlink to a directory in busybox?

I am attempting to (as close as perhaps) atomically transform a symlink. I've attempted:

ln -sf other_dir existing_symlink

That simply placed the new symlink in the directory that existing_symlink sharp to.

ln -sf other_dir new_symlink
mv -f new_symlink existing_symlink

That did the very same point : it relocated the symlink right into the directory.

cp -s other_dir existing_symlink

It rejects due to the fact that it is a directory.

I've read that mv -T is was created this, yet busybox does not have the -T flag.

2019-05-13 05:44:01
Source Share
Answers: 2

This can without a doubt be done atomically with rename(2), by first developing the new symlink under a short-lived name and afterwards easily overwriting the old symlink in one go. As the man page states:

If newpath describes a symbolic link the link will certainly be overwritten.

In the covering, you would certainly do this with mv -T as adheres to:

$ mkdir a b
$ ln -s a z
$ ln -s b
$ mv -T z

You can strace that last command to see to it it is without a doubt making use of rename(2) under the hood:

$ strace mv -T z
lstat64("", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("z", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
rename("", "z")                    = 0

Note that in the above, both mv -T and also strace are Linux - details.

On FreeBSD, usage mv -h at the same time.

2019-05-21 12:48:41

I do not see just how you can get atomic procedure. The male web page for symlink(2) claims it offers EEXIST if the target currently exists. If the bit does not sustain atomic procedure, your userland constraints are unnecessary.

I additionally do not see just how mv -T aids, also if you have it. Attempt it on a normal Linux box, one with GNU mv:

$ mkdir a b
$ ln -s a z
$ mv -T b z
mv: cannot overwrite non-directory `z' with directory `b'

I assume you are mosting likely to need to do this in 2 actions : remove the old symlink and also recreate it.

2019-05-17 19:33:39