diff options
author | Jason M. Bills <jason.m.bills@linux.intel.com> | 2021-05-24 22:35:24 +0300 |
---|---|---|
committer | Jason M. Bills <jason.m.bills@linux.intel.com> | 2021-05-24 22:35:24 +0300 |
commit | 0e0df451ae365f09d5c0c766b253f23de26901f2 (patch) | |
tree | db4d7d3ce85e02ee01ad58a86ede02ac876aae77 /poky/bitbake/lib/bb/runqueue.py | |
parent | e370fd750e2821620ec427f26f8efab0069824ff (diff) | |
parent | 7e10dee74964afa47859704886128dd256acf854 (diff) | |
download | openbmc-0e0df451ae365f09d5c0c766b253f23de26901f2.tar.xz |
Merge tag '0.52' of ssh://git-amr-1.devtools.intel.com:29418/openbmc-openbmc into update
Diffstat (limited to 'poky/bitbake/lib/bb/runqueue.py')
-rw-r--r-- | poky/bitbake/lib/bb/runqueue.py | 106 |
1 files changed, 84 insertions, 22 deletions
diff --git a/poky/bitbake/lib/bb/runqueue.py b/poky/bitbake/lib/bb/runqueue.py index 54ef245a6..cd56a5547 100644 --- a/poky/bitbake/lib/bb/runqueue.py +++ b/poky/bitbake/lib/bb/runqueue.py @@ -1242,6 +1242,7 @@ class RunQueue: magic = "decafbad" if self.cooker.configuration.profile: magic = "decafbadbad" + fakerootlogs = None if fakeroot: magic = magic + "beef" mcdata = self.cooker.databuilder.mcdata[mc] @@ -1251,10 +1252,11 @@ class RunQueue: for key, value in (var.split('=') for var in fakerootenv): env[key] = value worker = subprocess.Popen(fakerootcmd + ["bitbake-worker", magic], stdout=subprocess.PIPE, stdin=subprocess.PIPE, env=env) + fakerootlogs = self.rqdata.dataCaches[mc].fakerootlogs else: worker = subprocess.Popen(["bitbake-worker", magic], stdout=subprocess.PIPE, stdin=subprocess.PIPE) bb.utils.nonblockingfd(worker.stdout) - workerpipe = runQueuePipe(worker.stdout, None, self.cfgData, self, rqexec) + workerpipe = runQueuePipe(worker.stdout, None, self.cfgData, self, rqexec, fakerootlogs=fakerootlogs) workerdata = { "taskdeps" : self.rqdata.dataCaches[mc].task_deps, @@ -1772,7 +1774,7 @@ class RunQueueExecute: self.sqdata = SQData() build_scenequeue_data(self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self) - def runqueue_process_waitpid(self, task, status): + def runqueue_process_waitpid(self, task, status, fakerootlog=None): # self.build_stamps[pid] may not exist when use shared work directory. if task in self.build_stamps: @@ -1787,7 +1789,7 @@ class RunQueueExecute: self.sq_live.remove(task) else: if status != 0: - self.task_fail(task, status) + self.task_fail(task, status, fakerootlog=fakerootlog) else: self.task_complete(task) return True @@ -1908,14 +1910,31 @@ class RunQueueExecute: self.task_completeoutright(task) self.runq_tasksrun.add(task) - def task_fail(self, task, exitcode): + def task_fail(self, task, exitcode, fakerootlog=None): """ Called when a task has failed Updates the state engine with the failure """ self.stats.taskFailed() self.failed_tids.append(task) - bb.event.fire(runQueueTaskFailed(task, self.stats, exitcode, self.rq), self.cfgData) + + fakeroot_log = "" + if fakerootlog and os.path.exists(fakerootlog): + with open(fakerootlog) as fakeroot_log_file: + fakeroot_failed = False + for line in reversed(fakeroot_log_file.readlines()): + for fakeroot_error in ['mismatch', 'error', 'fatal']: + if fakeroot_error in line.lower(): + fakeroot_failed = True + if 'doing new pid setup and server start' in line: + break + fakeroot_log = line + fakeroot_log + + if not fakeroot_failed: + fakeroot_log = None + + bb.event.fire(runQueueTaskFailed(task, self.stats, exitcode, self.rq, fakeroot_log=fakeroot_log), self.cfgData) + if self.rqdata.taskData[''].abort: self.rq.state = runQueueCleanUp @@ -1943,6 +1962,10 @@ class RunQueueExecute: logger.error("Scenequeue had holdoff tasks: %s" % pprint.pformat(self.holdoff_tasks)) err = True + for tid in self.scenequeue_covered.intersection(self.scenequeue_notcovered): + # No task should end up in both covered and uncovered, that is a bug. + logger.error("Setscene task %s in both covered and notcovered." % tid) + for tid in self.rqdata.runq_setscene_tids: if tid not in self.scenequeue_covered and tid not in self.scenequeue_notcovered: err = True @@ -2431,6 +2454,12 @@ class RunQueueExecute: for dep in sorted(self.sqdata.sq_deps[task]): if fail and task in self.sqdata.sq_harddeps and dep in self.sqdata.sq_harddeps[task]: + if dep in self.scenequeue_covered or dep in self.scenequeue_notcovered: + # dependency could be already processed, e.g. noexec setscene task + continue + noexec, stamppresent = check_setscene_stamps(dep, self.rqdata, self.rq, self.stampcache) + if noexec or stamppresent: + continue logger.debug2("%s was unavailable and is a hard dependency of %s so skipping" % (task, dep)) self.sq_task_failoutright(dep) continue @@ -2755,6 +2784,40 @@ def build_scenequeue_data(sqdata, rqdata, rq, cooker, stampcache, sqrq): update_scenequeue_data(sqdata.sq_revdeps, sqdata, rqdata, rq, cooker, stampcache, sqrq, summary=True) + # Compute a list of 'stale' sstate tasks where the current hash does not match the one + # in any stamp files. Pass the list out to metadata as an event. + found = {} + for tid in rqdata.runq_setscene_tids: + (mc, fn, taskname, taskfn) = split_tid_mcfn(tid) + stamps = bb.build.find_stale_stamps(taskname, rqdata.dataCaches[mc], taskfn) + if stamps: + if mc not in found: + found[mc] = {} + found[mc][tid] = stamps + for mc in found: + event = bb.event.StaleSetSceneTasks(found[mc]) + bb.event.fire(event, cooker.databuilder.mcdata[mc]) + +def check_setscene_stamps(tid, rqdata, rq, stampcache, noexecstamp=False): + + (mc, fn, taskname, taskfn) = split_tid_mcfn(tid) + + taskdep = rqdata.dataCaches[mc].task_deps[taskfn] + + if 'noexec' in taskdep and taskname in taskdep['noexec']: + bb.build.make_stamp(taskname + "_setscene", rqdata.dataCaches[mc], taskfn) + return True, False + + if rq.check_stamp_task(tid, taskname + "_setscene", cache=stampcache): + logger.debug2('Setscene stamp current for task %s', tid) + return False, True + + if rq.check_stamp_task(tid, taskname, recurse = True, cache=stampcache): + logger.debug2('Normal stamp current for task %s', tid) + return False, True + + return False, False + def update_scenequeue_data(tids, sqdata, rqdata, rq, cooker, stampcache, sqrq, summary=True): tocheck = set() @@ -2765,24 +2828,14 @@ def update_scenequeue_data(tids, sqdata, rqdata, rq, cooker, stampcache, sqrq, s if tid in sqdata.valid: sqdata.valid.remove(tid) - (mc, fn, taskname, taskfn) = split_tid_mcfn(tid) - - taskdep = rqdata.dataCaches[mc].task_deps[taskfn] + noexec, stamppresent = check_setscene_stamps(tid, rqdata, rq, stampcache, noexecstamp=True) - if 'noexec' in taskdep and taskname in taskdep['noexec']: + if noexec: sqdata.noexec.add(tid) sqrq.sq_task_skip(tid) - bb.build.make_stamp(taskname + "_setscene", rqdata.dataCaches[mc], taskfn) continue - if rq.check_stamp_task(tid, taskname + "_setscene", cache=stampcache): - logger.debug2('Setscene stamp current for task %s', tid) - sqdata.stamppresent.add(tid) - sqrq.sq_task_skip(tid) - continue - - if rq.check_stamp_task(tid, taskname, recurse = True, cache=stampcache): - logger.debug2('Normal stamp current for task %s', tid) + if stamppresent: sqdata.stamppresent.add(tid) sqrq.sq_task_skip(tid) continue @@ -2876,12 +2929,16 @@ class runQueueTaskFailed(runQueueEvent): """ Event notifying a task failed """ - def __init__(self, task, stats, exitcode, rq): + def __init__(self, task, stats, exitcode, rq, fakeroot_log=None): runQueueEvent.__init__(self, task, stats, rq) self.exitcode = exitcode + self.fakeroot_log = fakeroot_log def __str__(self): - return "Task (%s) failed with exit code '%s'" % (self.taskstring, self.exitcode) + if self.fakeroot_log: + return "Task (%s) failed with exit code '%s' \nPseudo log:\n%s" % (self.taskstring, self.exitcode, self.fakeroot_log) + else: + return "Task (%s) failed with exit code '%s'" % (self.taskstring, self.exitcode) class sceneQueueTaskFailed(sceneQueueEvent): """ @@ -2933,7 +2990,7 @@ class runQueuePipe(): """ Abstraction for a pipe between a worker thread and the server """ - def __init__(self, pipein, pipeout, d, rq, rqexec): + def __init__(self, pipein, pipeout, d, rq, rqexec, fakerootlogs=None): self.input = pipein if pipeout: pipeout.close() @@ -2942,6 +2999,7 @@ class runQueuePipe(): self.d = d self.rq = rq self.rqexec = rqexec + self.fakerootlogs = fakerootlogs def setrunqueueexec(self, rqexec): self.rqexec = rqexec @@ -2987,7 +3045,11 @@ class runQueuePipe(): task, status = pickle.loads(self.queue[10:index]) except (ValueError, pickle.UnpicklingError, AttributeError, IndexError) as e: bb.msg.fatal("RunQueue", "failed load pickle '%s': '%s'" % (e, self.queue[10:index])) - self.rqexec.runqueue_process_waitpid(task, status) + (_, _, _, taskfn) = split_tid_mcfn(task) + fakerootlog = None + if self.fakerootlogs and taskfn and taskfn in self.fakerootlogs: + fakerootlog = self.fakerootlogs[taskfn] + self.rqexec.runqueue_process_waitpid(task, status, fakerootlog=fakerootlog) found = True self.queue = self.queue[index+11:] index = self.queue.find(b"</exitcode>") |