poky/bitbake
Richard Purdie 83fda1bb2e bitbake: event/utils: Avoid deadlock from lock_timeout() and recursive events
We've been seeing intermittent failures on Ubuntu 22.04 in oe-selftest which
were problematic to debug. The failure was inside lock_timeout and once that was
identified and the backtrace obtained, the problem becomes clearer:

  File "X/bitbake/lib/bb/server/process.py", line 466, in idle_thread_internal
    retval = function(self, data, False)
  File "X/bitbake/lib/bb/command.py", line 123, in runAsyncCommand
    self.cooker.updateCache()
  File "X/bitbake/lib/bb/cooker.py", line 1629, in updateCache
    self.parser = CookerParser(self, mcfilelist, total_masked)
  File "X/bitbake/lib/bb/cooker.py", line 2141, in __init__
    self.bb_caches = bb.cache.MulticonfigCache(self.cfgbuilder, self.cfghash, cooker.caches_array)
  File "X/bitbake/lib/bb/cache.py", line 772, in __init__
    loaded += c.prepare_cache(progress)
  File "X/bitbake/lib/bb/cache.py", line 435, in prepare_cache
    loaded = self.load_cachefile(progress)
  File "X/bitbake/lib/bb/cache.py", line 516, in load_cachefile
    progress(cachefile.tell() + previous_progress)
  File "X/bitbake/lib/bb/cache.py", line 751, in progress
    bb.event.fire(bb.event.CacheLoadProgress(current_progress, cachesize),
  File "X/bitbake/lib/bb/event.py", line 234, in fire
    fire_ui_handlers(event, d)
  File "X/bitbake/lib/bb/event.py", line 210, in fire_ui_handlers
    _ui_handlers[h].event.send(event)
  File "X/bitbake/lib/bb/cooker.py", line 117, in send
    str_event = codecs.encode(pickle.dumps(event), \'base64\').decode(\'utf-8\')
  File "/usr/lib/python3.10/asyncio/sslproto.py", line 320, in __del__
    _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
  File "/usr/lib/python3.10/warnings.py", line 109, in _showwarnmsg
    sw(msg.message, msg.category, msg.filename, msg.lineno,
  File "X/bitbake/lib/bb/main.py", line 113, in _showwarning
    warnlog.warning(s)
  File "/usr/lib/python3.10/logging/__init__.py", line 1489, in warning
    self._log(WARNING, msg, args, **kwargs)
  File "/usr/lib/python3.10/logging/__init__.py", line 1624, in _log
    self.handle(record)
  File "/usr/lib/python3.10/logging/__init__.py", line 1634, in handle
    self.callHandlers(record)
  File "/usr/lib/python3.10/logging/__init__.py", line 1696, in callHandlers
    hdlr.handle(record)
  File "/usr/lib/python3.10/logging/__init__.py", line 968, in handle
    self.emit(record)
  File "X/bitbake/lib/bb/event.py", line 778, in emit
    fire(record, None)
  File "X/bitbake/lib/bb/event.py", line 234, in fire
    fire_ui_handlers(event, d)
  File "X/bitbake/lib/bb/event.py", line 197, in fire_ui_handlers
    with bb.utils.lock_timeout(_thread_lock):
  File "/usr/lib/python3.10/contextlib.py", line 135, in __enter__
    return next(self.gen)
  File "X/bitbake/lib/bb/utils.py", line 1888, in lock_timeout
    bb.server.process.serverlog("Couldn\'t get the lock for 5 mins, timed out, exiting. %s" % traceback.format_stack())

or put in simpler terms, whilst sending an event(), an unrelated warning
message happens to be triggered from asyncio:

/usr/lib/python3.10/asyncio/sslproto.py:320: ResourceWarning: unclosed transport <asyncio.sslproto._SSLProtocolTransport object at 0x7f0e797d3100>

which triggers a second event() which can't be sent as we're already
in the critcal section and already hold the lock.

That warning is due to the version of asyncio used on Ubuntu 22.04 with
python 3.10 and that comined with timing issues explains why we don't
see it on other python versions or distros.

We can't handle the second event as the lock is there to serialise the
events. Instead, we queue the event and then process the queue later.

Add a new version of lock_timeout which allows us to handle the situation
more gracefully.

(Bitbake rev: 696c2c1ef095f8b11c7d2eff36fae50f58c62e5e)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit 2c590ff1aff89d23b25ce808650f200013a1e6af)
Signed-off-by: Steve Sakoman <steve@sakoman.com>
2025-03-15 06:40:07 -07:00
..
bin bitbake: bitbake-diffsigs: fix handling when finding only a single sigfile 2025-03-08 06:22:56 -08:00
contrib bitbake: contrib/vim: Syntax improvements 2023-12-23 16:20:25 +00:00
doc bitbake: bitbake: doc/user-manual: Update the BB_HASHSERVE_UPSTREAM 2024-11-02 06:12:00 -07:00
lib bitbake: event/utils: Avoid deadlock from lock_timeout() and recursive events 2025-03-15 06:40:07 -07:00
.gitattributes bitbake: .gitattributes: Add to improve git diff for minified css/js files 2019-03-07 12:18:48 +00:00
AUTHORS
ChangeLog
LICENSE bitbake: bitbake: Add initial pass of SPDX license headers to source code 2019-05-04 10:44:04 +01:00
LICENSE.GPL-2.0-only bitbake: bitbake: Add initial pass of SPDX license headers to source code 2019-05-04 10:44:04 +01:00
LICENSE.MIT bitbake: bitbake: Add initial pass of SPDX license headers to source code 2019-05-04 10:44:04 +01:00
README bitbake: doc: README: simpler link to contributor guide 2024-02-10 14:13:51 +00:00
SECURITY.md bitbake: SECURITY.md: add file 2023-10-24 12:49:56 +01:00
toaster-requirements.txt bitbake: Update toaster-requirements to add django-log-viewer==1.1.7 2023-10-15 09:12:05 +01:00

Bitbake

BitBake is a generic task execution engine that allows shell and Python tasks to be run efficiently and in parallel while working within complex inter-task dependency constraints. One of BitBake's main users, OpenEmbedded, takes this core and builds embedded Linux software stacks using a task-oriented approach.

For information about Bitbake, see the OpenEmbedded website: https://www.openembedded.org/

Bitbake plain documentation can be found under the doc directory or its integrated html version at the Yocto Project website: https://docs.yoctoproject.org

Bitbake requires Python version 3.8 or newer.

Contributing

Please refer to our contributor guide here: https://docs.yoctoproject.org/contributor-guide/ for full details on how to submit changes.

As a quick guide, patches should be sent to bitbake-devel@lists.openembedded.org The git command to do that would be:

git send-email -M -1 --to bitbake-devel@lists.openembedded.org

If you're sending a patch related to the BitBake manual, make sure you copy the Yocto Project documentation mailing list:

git send-email -M -1 --to bitbake-devel@lists.openembedded.org --cc docs@lists.yoctoproject.org

Mailing list:

https://lists.openembedded.org/g/bitbake-devel

Source code:

https://git.openembedded.org/bitbake/

Testing

Bitbake has a testsuite located in lib/bb/tests/ whichs aim to try and prevent regressions. You can run this with "bitbake-selftest". In particular the fetcher is well covered since it has so many corner cases. The datastore has many tests too. Testing with the testsuite is recommended before submitting patches, particularly to the fetcher and datastore. We also appreciate new test cases and may require them for more obscure issues.

To run the tests "zstd" and "git" must be installed.

The assumption is made that this testsuite is run from an initialized OpenEmbedded build environment (i.e. source oe-init-build-env is used). If this is not the case, run the testsuite as follows:

export PATH=$(pwd)/bin:$PATH
bin/bitbake-selftest

The testsuite can alternatively be executed using pytest, e.g. obtained from PyPI (in this case, the PATH is configured automatically):

pytest