From ff3617cc2cd5618f48a25aa4e3b2014430fcbe23 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Aug 2017 23:30:39 +0100 Subject: staging: Avoid sysroot removal races Currently a task could remove a dependency needed by another task leading to build failures, often due to missing dependencies (e.g. dynamic libraries not being found). This was often seen for all-arch recipes in package_write_rpm. When removing a dependency, first check that no other task active for the recipe has that same dependency. Signed-off-by: Richard Purdie --- meta/classes/staging.bbclass | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/meta/classes/staging.bbclass b/meta/classes/staging.bbclass index 9d3d2ad9dd..8b833d313c 100644 --- a/meta/classes/staging.bbclass +++ b/meta/classes/staging.bbclass @@ -247,6 +247,7 @@ python extend_recipe_sysroot() { import subprocess import errno import collections + import glob taskdepdata = d.getVar("BB_TASKDEPDATA", False) mytaskname = d.getVar("BB_RUNTASK") @@ -531,6 +532,7 @@ python extend_recipe_sysroot() { # to be insignificant taskindex = depdir + "/" + "index." + mytaskname if os.path.exists(taskindex): + potential = [] with open(taskindex, "r") as f: for l in f: l = l.strip() @@ -539,11 +541,24 @@ python extend_recipe_sysroot() { if not os.path.exists(l): # Was likely already uninstalled continue - bb.note("Task %s no longer depends on %s, removing from sysroot" % (mytaskname, l)) - lnk = os.readlink(l) - sstate_clean_manifest(depdir + "/" + lnk, d, workdir) - os.unlink(l) - os.unlink(l + ".complete") + potential.append(l) + # We need to ensure not other task needs this dependency. We hold the sysroot + # lock so we ca search the indexes to check + if potential: + for i in glob.glob(depdir + "/index.*"): + if i.endswith("." + mytaskname): + continue + with open(i, "r") as f: + for l in f: + l = l.strip() + if l in potential: + potential.remove(l) + for l in potential: + bb.note("Task %s no longer depends on %s, removing from sysroot" % (mytaskname, l)) + lnk = os.readlink(l) + sstate_clean_manifest(depdir + "/" + lnk, d, workdir) + os.unlink(l) + os.unlink(l + ".complete") with open(taskindex, "w") as f: for l in sorted(installed): f.write(l + "\n") -- cgit 1.2.3-korg