[PATCH STABLE] posix: avoid race condition while checking for symlinking capability

Mathias De Maré mathias.demare at gmail.com
Fri Nov 6 16:55:46 UTC 2015


# HG changeset patch
# User Mathias De Maré <mathias.demare at gmail.com>
# Date 1446828659 -3600
#      Fri Nov 06 17:50:59 2015 +0100
# Branch stable
# Node ID f8ff6c7234fec490e5ab98633bdcabbb403d48a1
# Parent  e7c618cee8df35aefedad15b991d628bae1c60c8
posix: avoid race condition while checking for symlinking capability

We start several workers (one per core), so it's possible
two workers get the same result for 'mktemp'.
This can result in one of the workers failing to create a symlink,
causing a percentage of the symlinks to be created as regular files.

This happens very rarely, but I've seen it occur on a repository
with ~6000 symbolic links and with a machine with 32 cores.

diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -168,9 +168,8 @@
 
 def checklink(path):
     """check whether the given path is on a symlink-capable filesystem"""
-    # mktemp is not racy because symlink creation will fail if the
-    # file already exists
-    name = tempfile.mktemp(dir=path, prefix='hg-checklink-')
+    tmpdir = tempfile.mkdtemp(dir=path, prefix='hg-checklink-')
+    name = os.path.join(tmpdir, 'link')
     try:
         fd = tempfile.NamedTemporaryFile(dir=path, prefix='hg-checklink-')
         try:
@@ -179,6 +178,7 @@
             return True
         finally:
             fd.close()
+            os.rmdir(tmpdir)
     except AttributeError:
         return False
     except OSError as inst:


More information about the Mercurial-devel mailing list