summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorDevendra Tewari <devendra.tewari@gmail.com>2021-04-19 11:23:58 -0300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-05-06 11:04:59 +0100
commit581233a798434f178898f12fa35bbcccb92e7768 (patch)
tree85b7608515935ce107304532ea64cda8a0e80dd9 /bitbake
parent7fbd7744ea68c17f396e87e15f9c7c9f6a371f23 (diff)
downloadpoky-581233a798434f178898f12fa35bbcccb92e7768.tar.gz
bitbake: lib/bb: Add bb.utils.rename() helper function and use for renaming
os.rename can fail for example an incremental build in Docker fails with: OSError: [Errno 18] Invalid cross-device link when source and destination are on different overlay filesystems. Rather than trying to fix every call site, add a wrapper in bb.utils for renames. We can then handle cross device failures and fall back to shutil.move. The reason os.rename is still used is because shutil.move is too slow for speed sensitive sections of code. [YOCTO #14301] (Bitbake rev: c5c4e49574ab2a65e06298a0a77bb98b041cf56b) Signed-off-by: Devendra Tewari <devendra.tewari@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/siggen.py2
-rw-r--r--bitbake/lib/bb/tests/fetch.py4
-rw-r--r--bitbake/lib/bb/utils.py18
3 files changed, 18 insertions, 6 deletions
diff --git a/bitbake/lib/bb/siggen.py b/bitbake/lib/bb/siggen.py
index f3fa3000fa..07692e673c 100644
--- a/bitbake/lib/bb/siggen.py
+++ b/bitbake/lib/bb/siggen.py
@@ -402,7 +402,7 @@ class SignatureGeneratorBasic(SignatureGenerator):
402 p = pickle.dump(data, stream, -1) 402 p = pickle.dump(data, stream, -1)
403 stream.flush() 403 stream.flush()
404 os.chmod(tmpfile, 0o664) 404 os.chmod(tmpfile, 0o664)
405 os.rename(tmpfile, sigfile) 405 bb.utils.rename(tmpfile, sigfile)
406 except (OSError, IOError) as err: 406 except (OSError, IOError) as err:
407 try: 407 try:
408 os.unlink(tmpfile) 408 os.unlink(tmpfile)
diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py
index 0f7585e119..9291ce4a06 100644
--- a/bitbake/lib/bb/tests/fetch.py
+++ b/bitbake/lib/bb/tests/fetch.py
@@ -1798,7 +1798,7 @@ class GitShallowTest(FetcherTest):
1798 1798
1799 # Set up the mirror 1799 # Set up the mirror
1800 mirrordir = os.path.join(self.tempdir, 'mirror') 1800 mirrordir = os.path.join(self.tempdir, 'mirror')
1801 os.rename(self.dldir, mirrordir) 1801 bb.utils.rename(self.dldir, mirrordir)
1802 self.d.setVar('PREMIRRORS', 'gitsm://.*/.* file://%s/\n' % mirrordir) 1802 self.d.setVar('PREMIRRORS', 'gitsm://.*/.* file://%s/\n' % mirrordir)
1803 1803
1804 # Fetch from the mirror 1804 # Fetch from the mirror
@@ -1916,7 +1916,7 @@ class GitShallowTest(FetcherTest):
1916 bb.utils.mkdirhier(mirrordir) 1916 bb.utils.mkdirhier(mirrordir)
1917 self.d.setVar('PREMIRRORS', 'git://.*/.* file://%s/\n' % mirrordir) 1917 self.d.setVar('PREMIRRORS', 'git://.*/.* file://%s/\n' % mirrordir)
1918 1918
1919 os.rename(os.path.join(self.dldir, mirrortarball), 1919 bb.utils.rename(os.path.join(self.dldir, mirrortarball),
1920 os.path.join(mirrordir, mirrortarball)) 1920 os.path.join(mirrordir, mirrortarball))
1921 1921
1922 # Fetch from the mirror 1922 # Fetch from the mirror
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py
index b282d09abf..6ba1d2a376 100644
--- a/bitbake/lib/bb/utils.py
+++ b/bitbake/lib/bb/utils.py
@@ -782,7 +782,7 @@ def movefile(src, dest, newmtime = None, sstat = None):
782 782
783 if sstat[stat.ST_DEV] == dstat[stat.ST_DEV]: 783 if sstat[stat.ST_DEV] == dstat[stat.ST_DEV]:
784 try: 784 try:
785 os.rename(src, destpath) 785 bb.utils.rename(src, destpath)
786 renamefailed = 0 786 renamefailed = 0
787 except Exception as e: 787 except Exception as e:
788 if e.errno != errno.EXDEV: 788 if e.errno != errno.EXDEV:
@@ -796,7 +796,7 @@ def movefile(src, dest, newmtime = None, sstat = None):
796 if stat.S_ISREG(sstat[stat.ST_MODE]): 796 if stat.S_ISREG(sstat[stat.ST_MODE]):
797 try: # For safety copy then move it over. 797 try: # For safety copy then move it over.
798 shutil.copyfile(src, destpath + "#new") 798 shutil.copyfile(src, destpath + "#new")
799 os.rename(destpath + "#new", destpath) 799 bb.utils.rename(destpath + "#new", destpath)
800 didcopy = 1 800 didcopy = 1
801 except Exception as e: 801 except Exception as e:
802 print('movefile: copy', src, '->', dest, 'failed.', e) 802 print('movefile: copy', src, '->', dest, 'failed.', e)
@@ -874,7 +874,7 @@ def copyfile(src, dest, newmtime = None, sstat = None):
874 874
875 # For safety copy then move it over. 875 # For safety copy then move it over.
876 shutil.copyfile(src, dest + "#new") 876 shutil.copyfile(src, dest + "#new")
877 os.rename(dest + "#new", dest) 877 bb.utils.rename(dest + "#new", dest)
878 except Exception as e: 878 except Exception as e:
879 logger.warning("copyfile: copy %s to %s failed (%s)" % (src, dest, e)) 879 logger.warning("copyfile: copy %s to %s failed (%s)" % (src, dest, e))
880 return False 880 return False
@@ -1669,3 +1669,15 @@ def is_semver(version):
1669 return False 1669 return False
1670 1670
1671 return True 1671 return True
1672
1673# Wrapper around os.rename which can handle cross device problems
1674# e.g. from container filesystems
1675def rename(src, dst):
1676 try:
1677 os.rename(src, dst)
1678 except OSError as err:
1679 if err.errno == 18:
1680 # Invalid cross-device link error
1681 shutil.move(src, dst)
1682 else:
1683 raise err