sstate: Remove stale objects before the main build

The split of util-linux-uuid out from util-linux caused some interesting
sstate file overlap errors on existing build directories. This is a
challenge to handle since util-linux depends on util-linux-uuid and has
overlapping files in package data and deploy/packages directories.
The util-linux build happens later and is what would clean up those files
but it happens too late for uuid.

Fixing this is hard as we don't know the taskhashes until the task
graph is calculated. Once that is ready, we can compare the hashes
with the existing hashes and know which sstate tasks are "stale".

This patch adds a handler which iterates the sstate manifests looking
for matching stamp paths and then removes the manifests along with the
associated stamp files.

(From OE-Core rev: 60e77b1777c6c304aa1d629c4cfdabe0daa22eb1)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie
2021-03-18 17:57:45 +00:00
parent 5372c7b54e
commit 75c2c03416

View File

@@ -1223,3 +1223,48 @@ python sstate_eventhandler2() {
if preservestamps:
os.remove(preservestampfile)
}
addhandler sstate_eventhandler_stalesstate
sstate_eventhandler_stalesstate[eventmask] = "bb.event.StaleSetSceneTasks"
python sstate_eventhandler_stalesstate() {
d = e.data
tasks = e.tasks
bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
for a in list(set(d.getVar("SSTATE_ARCHS").split())):
toremove = []
i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
if not os.path.exists(i):
continue
with open(i, "r") as f:
lines = f.readlines()
for l in lines:
try:
(stamp, manifest, workdir) = l.split()
for tid in tasks:
for s in tasks[tid]:
if s.startswith(stamp):
taskname = bb.runqueue.taskname_from_tid(tid)[3:]
manname = manifest + "." + taskname
if os.path.exists(manname):
bb.debug(2, "Sstate for %s is stale, removing related manifest %s" % (tid, manname))
toremove.append((manname, tid, tasks[tid]))
break
except ValueError:
bb.fatal("Invalid line '%s' in sstate manifest '%s'" % (l, i))
if toremove:
msg = "Removing %d stale sstate objects for arch %s" % (len(toremove), a)
bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
removed = 0
for (manname, tid, stamps) in toremove:
sstate_clean_manifest(manname, d)
for stamp in stamps:
bb.utils.remove(stamp)
removed = removed + 1
bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
bb.event.fire(bb.event.ProcessFinished(msg), d)
}