bitbake: fetch2: Do not fail to create symbolic links if they already exist

When the fetcher retrieves file:// URLs, there is no lock file being
used. This means that in case two separate tasks (typically from two
concurrent invocations of bitbake) want to download the same file://
URL at the same time, there is a very small chance that they also end
up wanting to create a symbolic link to the file at the same time.
This would previously lead to one of the tasks failing as the other
task would have created the link.

(Bitbake rev: 5f5e13bacde95a93633f621ec6b94a022c476a58)

Signed-off-by: Peter Kjellerstedt <pkj@axis.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Peter Kjellerstedt 2017-03-31 16:59:56 +02:00 committed by Richard Purdie
parent 84fd0eb005
commit e3ff03599e

View File

@ -967,7 +967,14 @@ def try_mirror_url(fetch, origud, ud, ld, check = False):
open(ud.donestamp, 'w').close()
dest = os.path.join(dldir, os.path.basename(ud.localpath))
if not os.path.exists(dest):
os.symlink(ud.localpath, dest)
# In case this is executing without any file locks held (as is
# the case for file:// URLs), two tasks may end up here at the
# same time, in which case we do not want the second task to
# fail when the link has already been created by the first task.
try:
os.symlink(ud.localpath, dest)
except FileExistsError:
pass
if not verify_donestamp(origud, ld) or origud.method.need_update(origud, ld):
origud.method.download(origud, ld)
if hasattr(origud.method,"build_mirror_data"):
@ -979,7 +986,11 @@ def try_mirror_url(fetch, origud, ud, ld, check = False):
# Broken symbolic link
os.unlink(origud.localpath)
os.symlink(ud.localpath, origud.localpath)
# As per above, in case two tasks end up here simultaneously.
try:
os.symlink(ud.localpath, origud.localpath)
except FileExistsError:
pass
update_stamp(origud, ld)
return ud.localpath