summaryrefslogtreecommitdiffstats
path: root/meta/classes/sstate.bbclass
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2021-06-30 13:02:25 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-07-02 07:24:21 +0100
commit2b3ced714a2388f1dac43915e67fdd6c62892238 (patch)
tree57b0b0f8e8afcd25cdcc488def7e6c0f209efc8d /meta/classes/sstate.bbclass
parent68a4cbb7b2dba70fdf931fbd4a316e1dacd2dacc (diff)
downloadpoky-2b3ced714a2388f1dac43915e67fdd6c62892238.tar.gz
sstate/staging: Handle directory creation race issue
The sstate code tries to be careful about racing around directory creation. In particular, the copyhardlinktree code creates the directory tree first allowing for "already exists" errors and ignoring them, then hardlinks the files in. Unfortunately the sstate removal code can race against this since it will try and remove empty directories. If there is some bad timing, a newly created directory can be removed before it was populated, leading to build failures. We could try and add locking but this would damage performance, we've been there before. It is also unclear where to actually place locks just based on the contents of a manifest file which may cover multiple sstate install locations for a given task. Instead, lets disable directory removal in the problematic "shared" core path. This could result in a few more empty directories being left on disk but those should be harmless and better than locking hurting performance or rare build races. [YOCTO #13999] [YOCTO #14379] (From OE-Core rev: 4f94d9296394bc7ce241439f00df86eb5912875f) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes/sstate.bbclass')
-rw-r--r--meta/classes/sstate.bbclass8
1 files changed, 5 insertions, 3 deletions
diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index 72eebd70c9..6c8e64ed00 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -483,7 +483,7 @@ def sstate_clean_cachefiles(d):
483 ss = sstate_state_fromvars(ld, task) 483 ss = sstate_state_fromvars(ld, task)
484 sstate_clean_cachefile(ss, ld) 484 sstate_clean_cachefile(ss, ld)
485 485
486def sstate_clean_manifest(manifest, d, prefix=None): 486def sstate_clean_manifest(manifest, d, canrace=False, prefix=None):
487 import oe.path 487 import oe.path
488 488
489 mfile = open(manifest) 489 mfile = open(manifest)
@@ -501,7 +501,9 @@ def sstate_clean_manifest(manifest, d, prefix=None):
501 if entry.endswith("/"): 501 if entry.endswith("/"):
502 if os.path.islink(entry[:-1]): 502 if os.path.islink(entry[:-1]):
503 os.remove(entry[:-1]) 503 os.remove(entry[:-1])
504 elif os.path.exists(entry) and len(os.listdir(entry)) == 0: 504 elif os.path.exists(entry) and len(os.listdir(entry)) == 0 and not canrace:
505 # Removing directories whilst builds are in progress exposes a race. Only
506 # do it in contexts where it is safe to do so.
505 os.rmdir(entry[:-1]) 507 os.rmdir(entry[:-1])
506 else: 508 else:
507 os.remove(entry) 509 os.remove(entry)
@@ -539,7 +541,7 @@ def sstate_clean(ss, d):
539 for lock in ss['lockfiles']: 541 for lock in ss['lockfiles']:
540 locks.append(bb.utils.lockfile(lock)) 542 locks.append(bb.utils.lockfile(lock))
541 543
542 sstate_clean_manifest(manifest, d) 544 sstate_clean_manifest(manifest, d, canrace=True)
543 545
544 for lock in locks: 546 for lock in locks:
545 bb.utils.unlockfile(lock) 547 bb.utils.unlockfile(lock)