diff options
author | Tomasz Dziendzielski <tomasz.dziendzielski@gmail.com> | 2021-03-05 12:44:24 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-03-11 14:04:45 +0000 |
commit | 5386b3db50d99965f15013c8831999f63dce8fbe (patch) | |
tree | 14161469e96307bdfa72fbbf77c0949624745f28 /bitbake/lib | |
parent | d3a0f074bcfcc5d158709906c37af76110418f0d (diff) | |
download | poky-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.py | 3 | ||||
-rw-r--r-- | bitbake/lib/bb/runqueue.py | 46 |
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 | ||
236 | def virtualfn2realfn(virtualfn): | 239 | def 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 | ||
2893 | class sceneQueueTaskFailed(sceneQueueEvent): | 2916 | class 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>") |