Fix os.mkdir race condition.

This code checks whether a dir exists before creating it. In between the
check and the mkdir call, it is possible that another process will have
created the directory. We have seen this bug occur many times in
practice during our 'repo init' tests.

Change-Id: Ia47d39955739aa38fd303f4e90be7b4c50d9d4ba
This commit is contained in:
David James 2013-12-26 14:20:13 -08:00
parent f045d49a71
commit bf79c6618e

25
repo
View File

@ -110,6 +110,7 @@ REPO_MAIN = S_repo + '/main.py' # main script
MIN_PYTHON_VERSION = (2, 6) # minimum supported python version MIN_PYTHON_VERSION = (2, 6) # minimum supported python version
import errno
import optparse import optparse
import os import os
import re import re
@ -243,10 +244,10 @@ def _Init(args):
_print("fatal: invalid branch name '%s'" % branch, file=sys.stderr) _print("fatal: invalid branch name '%s'" % branch, file=sys.stderr)
raise CloneFailure() raise CloneFailure()
if not os.path.isdir(repodir): try:
try: os.mkdir(repodir)
os.mkdir(repodir) except OSError as e:
except OSError as e: if e.errno != errno.EEXIST:
_print('fatal: cannot make %s directory: %s' _print('fatal: cannot make %s directory: %s'
% (repodir, e.strerror), file=sys.stderr) % (repodir, e.strerror), file=sys.stderr)
# Don't raise CloneFailure; that would delete the # Don't raise CloneFailure; that would delete the
@ -325,18 +326,18 @@ def NeedSetupGnuPG():
def SetupGnuPG(quiet): def SetupGnuPG(quiet):
if not os.path.isdir(home_dot_repo): try:
try: os.mkdir(home_dot_repo)
os.mkdir(home_dot_repo) except OSError as e:
except OSError as e: if e.errno != errno.EEXIST:
_print('fatal: cannot make %s directory: %s' _print('fatal: cannot make %s directory: %s'
% (home_dot_repo, e.strerror), file=sys.stderr) % (home_dot_repo, e.strerror), file=sys.stderr)
sys.exit(1) sys.exit(1)
if not os.path.isdir(gpg_dir): try:
try: os.mkdir(gpg_dir, stat.S_IRWXU)
os.mkdir(gpg_dir, stat.S_IRWXU) except OSError as e:
except OSError as e: if e.errno != errno.EEXIST:
_print('fatal: cannot make %s directory: %s' % (gpg_dir, e.strerror), _print('fatal: cannot make %s directory: %s' % (gpg_dir, e.strerror),
file=sys.stderr) file=sys.stderr)
sys.exit(1) sys.exit(1)