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

login
register
mail settings
Submitter Mathias De Maré
Date Nov. 6, 2015, 4:55 p.m.
Message ID <f8ff6c7234fec490e5ab.1446828946@waste.org>
Download mbox | patch
Permalink /patch/11303/
State Rejected
Headers show

Comments

Mathias De Maré - Nov. 6, 2015, 4:55 p.m.
# HG changeset patch
# User Mathias De Maré <mathias.demare@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.

Patch

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: