[libvirt PATCH] scripts: Fix meson-install-symlink.py overwriting existing links

Martin Kletzander mkletzan at redhat.com
Tue Aug 4 17:48:15 UTC 2020


On Tue, Aug 04, 2020 at 06:27:08PM +0200, Erik Skultety wrote:
>By default, symlink re-creation fails if the link already exists, more
>specifically in case of meson-install-symlink.py:
>
>Traceback (most recent call last):
>  File "/<path_to_libvirt_repo>/scripts/meson-install-symlink.py",
>    line 15, in <module>
>        os.symlink(target, link)
>FileExistsError: File exists: '../default.xml' -> 'default.xml'
>
>Unfortunately, Python can't mimic "ln -sf", so we have to fix this
>differently - create a temporary name which is then going to be used
>for the temporary link followed by a rename with the original link's
>name.
>Note that this solution is racy as mktemp() doesn't guarantee
>atomicity in link creation, so theoretically another process could come
>and create a file with the same name as the temporary link name, but
>a proper solution would be longer and not as elegant.
>

Well, you could do subprocess.check_output(['ln', '-sf', ...]) (yuck), but it
does essentially the same thing anyway.

I don't think a race here would cause anything.  I would probably remove the
file and then create the symlink and if there is something/someone else
installing the same file than it is good that we error our because there are
bigger issues than that.  The whole installation process should not be
interfered with and you cannot make it atomic anyway.

Thoughts?

>Signed-off-by: Erik Skultety <eskultet at redhat.com>
>---
> scripts/meson-install-symlink.py | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
>diff --git a/scripts/meson-install-symlink.py b/scripts/meson-install-symlink.py
>index e38507072d..630dfc079f 100644
>--- a/scripts/meson-install-symlink.py
>+++ b/scripts/meson-install-symlink.py
>@@ -2,6 +2,7 @@
>
> import os
> import sys
>+import tempfile
>
> destdir = os.environ.get('DESTDIR', os.sep)
> dirname = sys.argv[1]
>@@ -12,4 +13,7 @@ workdir = os.path.join(destdir, dirname.strip(os.sep))
>
> os.makedirs(workdir, exist_ok=True)
> os.chdir(workdir)
>-os.symlink(target, link)
>+
>+templink = tempfile.mktemp(dir=workdir)
>+os.symlink(target, templink)
>+os.replace(templink, link)
>-- 
>2.26.2
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20200804/d53a15d6/attachment-0001.sig>


More information about the libvir-list mailing list