summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2019-02-26 08:40:10 +0100
committerJürg Billeter <j@bitron.ch>2019-02-26 09:49:47 +0100
commitb660a8c619dfa51c1797db0e22b16071fa54883b (patch)
treeebb3e4e11c7468d583fa8aa3305d3b9568254eb0
parentd6ec082a3017882e69b070f1f5435b5a5eead29f (diff)
downloadbuildstream-juerg/unlink.tar.gz
utils.py: safe_link(): Unlink only if target already existsjuerg/unlink
Unlike shutil.copyfile(), os.link() will not modify the target file if it exists already. This improves staging performance by about 10% in a simple test.
-rw-r--r--buildstream/utils.py22
1 files changed, 13 insertions, 9 deletions
diff --git a/buildstream/utils.py b/buildstream/utils.py
index a4e84097b..204afca0c 100644
--- a/buildstream/utils.py
+++ b/buildstream/utils.py
@@ -280,7 +280,7 @@ def safe_copy(src, dest, *, result=None):
.format(src, dest, e)) from e
-def safe_link(src, dest, *, result=None):
+def safe_link(src, dest, *, result=None, _unlink=False):
"""Try to create a hardlink, but resort to copying in the case of cross device links.
Args:
@@ -292,19 +292,23 @@ def safe_link(src, dest, *, result=None):
UtilError: In the case of unexpected system call failures
"""
- # First unlink the target if it exists
- try:
- os.unlink(dest)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise UtilError("Failed to remove destination file '{}': {}"
- .format(dest, e)) from e
+ if _unlink:
+ # First unlink the target if it exists
+ try:
+ os.unlink(dest)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise UtilError("Failed to remove destination file '{}': {}"
+ .format(dest, e)) from e
# If we can't link it due to cross-device hardlink, copy
try:
os.link(src, dest)
except OSError as e:
- if e.errno == errno.EXDEV:
+ if e.errno == errno.EEXIST and not _unlink:
+ # Target exists already, unlink and try again
+ safe_link(src, dest, result=result, _unlink=True)
+ elif e.errno == errno.EXDEV:
safe_copy(src, dest)
else:
raise UtilError("Failed to link '{} -> {}': {}"