summaryrefslogtreecommitdiffstats
path: root/bitbake/lib
diff options
context:
space:
mode:
authorTomasz Dziendzielski <tomasz.dziendzielski@gmail.com>2021-03-05 12:44:24 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-03-11 14:04:45 +0000
commit5386b3db50d99965f15013c8831999f63dce8fbe (patch)
tree14161469e96307bdfa72fbbf77c0949624745f28 /bitbake/lib
parentd3a0f074bcfcc5d158709906c37af76110418f0d (diff)
downloadpoky-5386b3db50d99965f15013c8831999f63dce8fbe.tar.gz
bitbake: runqueue: Print pseudo.log if fakeroot task failed
Currently if pseudo fails we can only see the path to pseudo.log. If we have no access to server and can only rely on bitbake log then debugging becomes impossible. This printing needs to be added in runqueue level, not inside task execution, because in some cases task fails with pseudo abort really early and we don't even see any log. In this change I'm adding pseudo log printing in every fakeroot task failure that logged `mismatch`, `error` or `fatal` to logfile, because we have no other way to communicate with pseudo if it failed or not. Only lines from last pseudo server execution will be printed. (Bitbake rev: e7c664a947903ed7b868abef62af2ff5f8ef0dc6) Signed-off-by: Tomasz Dziendzielski <tomasz.dziendzielski@gmail.com> Signed-off-by: Jan Brzezanski <jan.brzezanski@gmail.com> Signed-off-by: Adrian Walag Signed-off-by: Paulo Neves <ptsneves@gmail.com> Signed-off-by: Mikolaj Lasota <mikolaj.lasota@protonmail.com> Signed-off-by: Wiktor Baura <wbaura@gmail.com> Signed-off-by: Kamil Kwiek <kamil.kwiek@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/bb/cache.py3
-rw-r--r--bitbake/lib/bb/runqueue.py46
2 files changed, 40 insertions, 9 deletions
diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py
index aea2b8bc11..27eb271798 100644
--- a/bitbake/lib/bb/cache.py
+++ b/bitbake/lib/bb/cache.py
@@ -126,6 +126,7 @@ class CoreRecipeInfo(RecipeInfoCommon):
126 self.inherits = self.getvar('__inherit_cache', metadata, expand=False) 126 self.inherits = self.getvar('__inherit_cache', metadata, expand=False)
127 self.fakerootenv = self.getvar('FAKEROOTENV', metadata) 127 self.fakerootenv = self.getvar('FAKEROOTENV', metadata)
128 self.fakerootdirs = self.getvar('FAKEROOTDIRS', metadata) 128 self.fakerootdirs = self.getvar('FAKEROOTDIRS', metadata)
129 self.fakerootlogs = self.getvar('FAKEROOTLOGS', metadata)
129 self.fakerootnoenv = self.getvar('FAKEROOTNOENV', metadata) 130 self.fakerootnoenv = self.getvar('FAKEROOTNOENV', metadata)
130 self.extradepsfunc = self.getvar('calculate_extra_depends', metadata) 131 self.extradepsfunc = self.getvar('calculate_extra_depends', metadata)
131 132
@@ -163,6 +164,7 @@ class CoreRecipeInfo(RecipeInfoCommon):
163 cachedata.fakerootenv = {} 164 cachedata.fakerootenv = {}
164 cachedata.fakerootnoenv = {} 165 cachedata.fakerootnoenv = {}
165 cachedata.fakerootdirs = {} 166 cachedata.fakerootdirs = {}
167 cachedata.fakerootlogs = {}
166 cachedata.extradepsfunc = {} 168 cachedata.extradepsfunc = {}
167 169
168 def add_cacheData(self, cachedata, fn): 170 def add_cacheData(self, cachedata, fn):
@@ -231,6 +233,7 @@ class CoreRecipeInfo(RecipeInfoCommon):
231 cachedata.fakerootenv[fn] = self.fakerootenv 233 cachedata.fakerootenv[fn] = self.fakerootenv
232 cachedata.fakerootnoenv[fn] = self.fakerootnoenv 234 cachedata.fakerootnoenv[fn] = self.fakerootnoenv
233 cachedata.fakerootdirs[fn] = self.fakerootdirs 235 cachedata.fakerootdirs[fn] = self.fakerootdirs
236 cachedata.fakerootlogs[fn] = self.fakerootlogs
234 cachedata.extradepsfunc[fn] = self.extradepsfunc 237 cachedata.extradepsfunc[fn] = self.extradepsfunc
235 238
236def virtualfn2realfn(virtualfn): 239def virtualfn2realfn(virtualfn):
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index ca71d213d3..3008b7ad4f 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1242,6 +1242,7 @@ class RunQueue:
1242 magic = "decafbad" 1242 magic = "decafbad"
1243 if self.cooker.configuration.profile: 1243 if self.cooker.configuration.profile:
1244 magic = "decafbadbad" 1244 magic = "decafbadbad"
1245 fakerootlogs = None
1245 if fakeroot: 1246 if fakeroot:
1246 magic = magic + "beef" 1247 magic = magic + "beef"
1247 mcdata = self.cooker.databuilder.mcdata[mc] 1248 mcdata = self.cooker.databuilder.mcdata[mc]
@@ -1251,10 +1252,11 @@ class RunQueue:
1251 for key, value in (var.split('=') for var in fakerootenv): 1252 for key, value in (var.split('=') for var in fakerootenv):
1252 env[key] = value 1253 env[key] = value
1253 worker = subprocess.Popen(fakerootcmd + ["bitbake-worker", magic], stdout=subprocess.PIPE, stdin=subprocess.PIPE, env=env) 1254 worker = subprocess.Popen(fakerootcmd + ["bitbake-worker", magic], stdout=subprocess.PIPE, stdin=subprocess.PIPE, env=env)
1255 fakerootlogs = self.rqdata.dataCaches[mc].fakerootlogs
1254 else: 1256 else:
1255 worker = subprocess.Popen(["bitbake-worker", magic], stdout=subprocess.PIPE, stdin=subprocess.PIPE) 1257 worker = subprocess.Popen(["bitbake-worker", magic], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
1256 bb.utils.nonblockingfd(worker.stdout) 1258 bb.utils.nonblockingfd(worker.stdout)
1257 workerpipe = runQueuePipe(worker.stdout, None, self.cfgData, self, rqexec) 1259 workerpipe = runQueuePipe(worker.stdout, None, self.cfgData, self, rqexec, fakerootlogs=fakerootlogs)
1258 1260
1259 workerdata = { 1261 workerdata = {
1260 "taskdeps" : self.rqdata.dataCaches[mc].task_deps, 1262 "taskdeps" : self.rqdata.dataCaches[mc].task_deps,
@@ -1772,7 +1774,7 @@ class RunQueueExecute:
1772 self.sqdata = SQData() 1774 self.sqdata = SQData()
1773 build_scenequeue_data(self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self) 1775 build_scenequeue_data(self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self)
1774 1776
1775 def runqueue_process_waitpid(self, task, status): 1777 def runqueue_process_waitpid(self, task, status, fakerootlog=None):
1776 1778
1777 # self.build_stamps[pid] may not exist when use shared work directory. 1779 # self.build_stamps[pid] may not exist when use shared work directory.
1778 if task in self.build_stamps: 1780 if task in self.build_stamps:
@@ -1787,7 +1789,7 @@ class RunQueueExecute:
1787 self.sq_live.remove(task) 1789 self.sq_live.remove(task)
1788 else: 1790 else:
1789 if status != 0: 1791 if status != 0:
1790 self.task_fail(task, status) 1792 self.task_fail(task, status, fakerootlog=fakerootlog)
1791 else: 1793 else:
1792 self.task_complete(task) 1794 self.task_complete(task)
1793 return True 1795 return True
@@ -1908,14 +1910,31 @@ class RunQueueExecute:
1908 self.task_completeoutright(task) 1910 self.task_completeoutright(task)
1909 self.runq_tasksrun.add(task) 1911 self.runq_tasksrun.add(task)
1910 1912
1911 def task_fail(self, task, exitcode): 1913 def task_fail(self, task, exitcode, fakerootlog=None):
1912 """ 1914 """
1913 Called when a task has failed 1915 Called when a task has failed
1914 Updates the state engine with the failure 1916 Updates the state engine with the failure
1915 """ 1917 """
1916 self.stats.taskFailed() 1918 self.stats.taskFailed()
1917 self.failed_tids.append(task) 1919 self.failed_tids.append(task)
1918 bb.event.fire(runQueueTaskFailed(task, self.stats, exitcode, self.rq), self.cfgData) 1920
1921 fakeroot_log = ""
1922 if fakerootlog and os.path.exists(fakerootlog):
1923 with open(fakerootlog) as fakeroot_log_file:
1924 fakeroot_failed = False
1925 for line in reversed(fakeroot_log_file.readlines()):
1926 for fakeroot_error in ['mismatch', 'error', 'fatal']:
1927 if fakeroot_error in line.lower():
1928 fakeroot_failed = True
1929 if 'doing new pid setup and server start' in line:
1930 break
1931 fakeroot_log = line + fakeroot_log
1932
1933 if not fakeroot_failed:
1934 fakeroot_log = None
1935
1936 bb.event.fire(runQueueTaskFailed(task, self.stats, exitcode, self.rq, fakeroot_log=fakeroot_log), self.cfgData)
1937
1919 if self.rqdata.taskData[''].abort: 1938 if self.rqdata.taskData[''].abort:
1920 self.rq.state = runQueueCleanUp 1939 self.rq.state = runQueueCleanUp
1921 1940
@@ -2883,12 +2902,16 @@ class runQueueTaskFailed(runQueueEvent):
2883 """ 2902 """
2884 Event notifying a task failed 2903 Event notifying a task failed
2885 """ 2904 """
2886 def __init__(self, task, stats, exitcode, rq): 2905 def __init__(self, task, stats, exitcode, rq, fakeroot_log=None):
2887 runQueueEvent.__init__(self, task, stats, rq) 2906 runQueueEvent.__init__(self, task, stats, rq)
2888 self.exitcode = exitcode 2907 self.exitcode = exitcode
2908 self.fakeroot_log = fakeroot_log
2889 2909
2890 def __str__(self): 2910 def __str__(self):
2891 return "Task (%s) failed with exit code '%s'" % (self.taskstring, self.exitcode) 2911 if self.fakeroot_log:
2912 return "Task (%s) failed with exit code '%s' \nPseudo log:\n%s" % (self.taskstring, self.exitcode, self.fakeroot_log)
2913 else:
2914 return "Task (%s) failed with exit code '%s'" % (self.taskstring, self.exitcode)
2892 2915
2893class sceneQueueTaskFailed(sceneQueueEvent): 2916class sceneQueueTaskFailed(sceneQueueEvent):
2894 """ 2917 """
@@ -2940,7 +2963,7 @@ class runQueuePipe():
2940 """ 2963 """
2941 Abstraction for a pipe between a worker thread and the server 2964 Abstraction for a pipe between a worker thread and the server
2942 """ 2965 """
2943 def __init__(self, pipein, pipeout, d, rq, rqexec): 2966 def __init__(self, pipein, pipeout, d, rq, rqexec, fakerootlogs=None):
2944 self.input = pipein 2967 self.input = pipein
2945 if pipeout: 2968 if pipeout:
2946 pipeout.close() 2969 pipeout.close()
@@ -2949,6 +2972,7 @@ class runQueuePipe():
2949 self.d = d 2972 self.d = d
2950 self.rq = rq 2973 self.rq = rq
2951 self.rqexec = rqexec 2974 self.rqexec = rqexec
2975 self.fakerootlogs = fakerootlogs
2952 2976
2953 def setrunqueueexec(self, rqexec): 2977 def setrunqueueexec(self, rqexec):
2954 self.rqexec = rqexec 2978 self.rqexec = rqexec
@@ -2994,7 +3018,11 @@ class runQueuePipe():
2994 task, status = pickle.loads(self.queue[10:index]) 3018 task, status = pickle.loads(self.queue[10:index])
2995 except (ValueError, pickle.UnpicklingError, AttributeError, IndexError) as e: 3019 except (ValueError, pickle.UnpicklingError, AttributeError, IndexError) as e:
2996 bb.msg.fatal("RunQueue", "failed load pickle '%s': '%s'" % (e, self.queue[10:index])) 3020 bb.msg.fatal("RunQueue", "failed load pickle '%s': '%s'" % (e, self.queue[10:index]))
2997 self.rqexec.runqueue_process_waitpid(task, status) 3021 (_, _, _, taskfn) = split_tid_mcfn(task)
3022 fakerootlog = None
3023 if self.fakerootlogs and taskfn and taskfn in self.fakerootlogs:
3024 fakerootlog = self.fakerootlogs[taskfn]
3025 self.rqexec.runqueue_process_waitpid(task, status, fakerootlog=fakerootlog)
2998 found = True 3026 found = True
2999 self.queue = self.queue[index+11:] 3027 self.queue = self.queue[index+11:]
3000 index = self.queue.find(b"</exitcode>") 3028 index = self.queue.find(b"</exitcode>")