path.py: Deal with race issue

The change to use copyhardlinktree in some of the sstate code instead of
copytree exposed a race condition. This is due to cp failing if it finds
a directory doesn't exist yet some other process creates it while cp was
trying to create it itself. tar doesn't error in this case.

To fix this we need to create the directory structure with tar, then
use cp to hardlink the files. Messy but probably worth doing.

I also took the opportunity to remove src_bak since the code is neater
without it.

(From OE-Core rev: 2f954a9a6932f1e6c564e7e7aacaac628a75eed7)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie 2013-05-03 15:11:33 +01:00
parent c09866b4cf
commit 61823f6194
1 changed files with 11 additions and 7 deletions

View File

@ -87,16 +87,20 @@ def copytree(src, dst):
def copyhardlinktree(src, dst):
""" Make the hard link when possible, otherwise copy. """
bb.utils.mkdirhier(dst)
src_bak = src
if os.path.isdir(src):
if not len(os.listdir(src)):
return
src = src + "/*"
if (os.stat(src_bak).st_dev == os.stat(dst).st_dev):
if os.path.isdir(src) and not len(os.listdir(src)):
return
if (os.stat(src).st_dev == os.stat(dst).st_dev):
# Need to copy directories only with tar first since cp will error if two
# writers try and create a directory at the same time
cmd = 'cd %s; find . -type d -print | tar -cf - -C %s -ps --files-from - | tar -xf - -C %s' % (src, src, dst)
check_output(cmd, shell=True, stderr=subprocess.STDOUT)
if os.path.isdir(src):
src = src + "/*"
cmd = 'cp -afl %s %s' % (src, dst)
check_output(cmd, shell=True, stderr=subprocess.STDOUT)
else:
copytree(src_bak, dst)
copytree(src, dst)
def remove(path, recurse=True):
"""Equivalent to rm -f or rm -rf"""