subtree updates

meta-openembedded: 7d8115d550..098dc606f9:
  Alex Kiernan (2):
        c-ares: Filter out "Live" tests
        ptest-packagelists-meta-oe.inc Add c-ares to PTESTS_SLOW_META_OE

  Alexander Kanavin (25):
        fontforge: add a readline PACKAGECONFIG
        volume-key: disable python bindings
        audit: disable python bindings as incompatible with python 3.12
        cmpi-bindings: update 1.0.1 -> 1.0.4
        libpwquality: backport a python 3.12 compatibility patch
        mycroft: do not depend on python3-xmlrunner
        python3-xmlrunner: remove the recipe
        system-config-printer: rely on setuptools to obtain distutils copy
        python3-gmpy2: fix python 3.12 issues
        python3-custom-inherit: fix python 3.12 builds
        python3-jsonrpcserver: remove
        python3-oslash: remove
        nmap: disable ndiff
        wireshark: update 4.0.10 -> 4.2.0
        openipmi: update 2.0.32 -> 2.0.34
        libsigrokdecode: add python 3.12 support
        cockpit: add setuptools dependency to bring in distutils copy
        mongodb: skip until python 3.12 fixes are available.
        mercurial: ensure setuptools is present as distutils is no longer (mercurial tries both)
        rwmem: fix python modules packaging
        upm: get disutils copy via setuptools
        python3-kmod: remove the recipe
        hplip: provide setuptools for the distutils copy
        audit: reenable python bindings and bring in distutils via setuptools (needed with python 3.12)
        python3-h5py: backport a cython 3.x compatibility patch

  Christophe Vu-Brugier (1):
        nvme-cli: upgrade 2.6 -> 2.7.1

  Enrico Scholz (1):
        krb5: use PACKAGE_BEFORE_PN

  Fabio Estevam (2):
        i2cdev_git: Remove AUTHOR field
        picocom: Update to 2023-04

  Ilya A. Kriveshko (1):
        srecord: fix install prefix

  Jordan Crouse (2):
        collectd: Remove rrdtool from DEPENDS
        keepalived: Move the sample configuration files to a separate package

  Jose Quaresma (1):
        layer.conf: Add libdevmapper-native PREFERRED_RPROVIDER

  Khem Raj (8):
        mraa: Update to latest tip of trunk
        libcppkafka: Update to tip of trunk
        python3-pydantic-core: Rename the cpython module on musl
        libtinyxml2: Package needed resources to run ptests
        python3-pylint: Ignore failing ptests
        libconfig-general-perl: Enable on musl targets
        tgt: Fix build with musl
        kernel-selftest: remove Wno-alloc-size-larger-than from scripts/Makefile.extrawarn

  Leon Anavi (5):
        ssd1306_git.bb: Add ssd1306_linux
        ssd1306: Update and remove patch
        python3-webargs: Upgrade 8.3.0 -> 8.4.0
        python3-wtforms: Upgrade 3.1.1 -> 3.1.2
        python3-kivy: Upgrade 2.2.1 -> 2.3.0

  Markus Volk (9):
        luajit: upgrade 2.1beta -> 2.1
        gnome-terminal: fix search_provider build
        libplist: make sure rm doesn't fail on nonexistent file
        imagemagick: upgrade 7.1.1-8 -> 7.1.1.26
        mutter: update 45.1 -> 45.3
        gnome-shell: update 45.1 -> 45.3
        gnome-control-center: update 45.1 -> 45.2
        gnome-software: update 45.1 -> 45.3
        gnome-shell-extensions: update 45.1 -> 45.2

  Martin Jansa (1):
        libpwquality: respect PYTHONSITEDIR

  Michael Haener (1):
        mdio-tools: upgrade 1.3.0 -> 1.3.1

  Mingli Yu (2):
        usleep: Make the version consistent
        ipmitool: Make the version consistent

  Peter Marko (1):
        protobuf-c: upgrade 1.4.1 -> 1.5.0

  Richard Leitner (1):
        python3-pytest-cov: add missing python3-coverage dependency

  Robert Yang (1):
        v4l-utils: Add PACKAGECONFIG for v4l2-tracer to fix determinstic build

  Wang Mingyu (52):
        cglm: upgrade 0.9.1 -> 0.9.2
        ctags: upgrade 6.0.20231224.0 -> 6.1.20231231.0
        exiftool: upgrade 12.71 -> 12.72
        feh: upgrade 3.10.1 -> 3.10.2
        libssh: upgrade 0.10.5 -> 0.10.6
        squid: upgrade 6.5 -> 6.6
        imapfilter: upgrade 2.8.1 -> 2.8.2
        redis-plus-plus: upgrade 1.3.10 -> 1.3.11
        python3-netaddr: upgrade 0.9.0 -> 0.10.0
        plocate: upgrade 1.1.19 -> 1.1.20
        python3-cantools: upgrade 39.4.1 -> 39.4.2
        python3-coverage: upgrade 7.3.4 -> 7.4.0
        python3-flask: upgrade 2.3.3 -> 3.0.0
        python3-gspread: upgrade 5.12.3 -> 5.12.4
        python3-pydot: upgrade 1.4.2 -> 2.0.0
        qpdf: upgrade 11.6.4 -> 11.7.0
        thingsboard-gateway: upgrade 3.4.3.1 -> 3.4.4
        python3-pydantic-core: upgrade 2.14.5 -> 2.14.6
        libtinyxml2: upgrade 9.0.0 -> 10.0.0
        adw-gtk3: upgrade 5.1 -> 5.2
        dialog: upgrade 1.3-20231002 -> 1.3-20240101
        ghex: upgrade 45.0 -> 45.1
        jwt-cpp: upgrade 0.6.0 -> 0.7.0
        libcloudproviders: upgrade 0.3.4 -> 0.3.5
        libgedit-gtksourceview: upgrade 299.0.4 -> 299.0.5
        libjcat: upgrade 0.1.14 -> 0.2.0
        libraw: upgrade 0.21.1 -> 0.21.2
        libsass: upgrade 3.6.5 -> 3.6.6
        chrony: upgrade 4.4 -> 4.5
        tgt: upgrade 1.0.83 -> 1.0.90
        lapack: upgrade 3.10.1 -> 3.12.0
        libio-pty-perl: upgrade 1.17 -> 1.20
        webkitgtk3: upgrade 2.42.3 -> 2.42.4
        xmlsec1: upgrade 1.3.2 -> 1.3.3
        python3-argh: upgrade 0.30.5 -> 0.31.0
        python3-cvxopt: upgrade 1.2.7 -> 1.3.2
        python3-sqlalchemy: upgrade 2.0.24 -> 2.0.25
        python3-aiohttp-jinja2: upgrade 1.5.1 -> 1.6
        python3-bitarray: upgrade 2.9.1 -> 2.9.2
        python3-google-api-python-client: upgrade 2.111.0 -> 2.112.0
        python3-google-auth: upgrade 2.25.2 -> 2.26.1
        python3-lz4: upgrade 4.3.2 -> 4.3.3
        python3-pdm: upgrade 2.11.1 -> 2.11.2
        python3-pyflakes: upgrade 3.1.0 -> 3.2.0
        python3-pymisp: upgrade 2.4.182 -> 2.4.183
        python3-pytest-asyncio: upgrade 0.23.2 -> 0.23.3
        python3-traitlets: upgrade 5.14.0 -> 5.14.1
        traceroute: upgrade 2.1.3 -> 2.1.5
        wolfssl: upgrade 5.6.4 -> 5.6.6
        xerces-c: upgrade 3.2.4 -> 3.2.5
        zenity: upgrade 4.0.0 -> 4.0.1
        daq: Fix install conflict when enable multilib.

  Yi Zhao (6):
        vsomeip: upgrade 3.3.8 -> 3.4.10
        libtdb: upgrade 1.4.8 -> 1.4.9
        libtalloc: upgrade 2.4.0 -> 2.4.1
        libtevent: upgrade 0.14.1 -> 0.16.0
        libldb: upgrade 2.7.2 -> 2.8.0
        samba: upgrade 4.18.9 -> 4.19.3

  alperak (10):
        libnvme: upgrade 1.6 -> 1.7.1
        libpaper: upgrade 2.1.0 -> 2.1.2
        onig: upgrade 6.9.8 -> 6.9.9
        clinfo: upgrade 3.0.21.02.21 -> 3.0.23.01.25
        opensc: upgrade 0.23.0 -> 0.24.0
        pcsc-lite: upgrade 2.0.0 -> 2.0.1
        pcsc-tools: upgrade 1.6.2 -> 1.7.1
        wavpack: upgrade 5.1.0 -> 5.6.0
        nginx: fix CVE-2023-44487
        grpc: upgrade 1.59.2 -> 1.60.0

meta-arm: 4d22f982bc..5712422011:
  Emekcan Aras (1):
        arm-bsp/linux-yocto: corstone1000: bump to v6.6%

  Jon Mason (8):
        arm-bsp/trusted-firmware-m: update libmetal and open-amp to a release
        arm-bsp/trusted-firmware-m: update libmetal and open-amp to 2023.04.0
        arm: modify patches to have email headers and correct date fields
        arm-bsp/optee-os: remove unused 3.18 files
        arm/optee-os: use sysroot in CFLAGS
        arm/optee-os: remove unneeded clang patches
        arm/scp-firmware: update git repository to new location
        arm-bsp/u-boot: rebase patches for v2024.01

  Ross Burton (1):
        arm-bsp/linux-yocto: add linux-yocto 6.5 temporarily

meta-raspberrypi: 4c033eb074..b859bc3eca:
  Leon Anavi (1):
        bcm2835: update 1.71 -> 1.73

poky: 4675bbb757..61182659c2:
  Adrian Freihofer (1):
        ref-manual: document cmake-qemu class

  Alassane Yattara (7):
        bitbake: toaster/tests: Bug-fix on TestProjectConfigTab::test_image_recipe_show_rows
        bitbake: toaster/tests: Bug-fix element click intercepted
        bitbake: toaster/tests: Delay driver first action on create new project page
        bitbake: toaster/tests: Setup delay after driver action self.get(url)
        bitbake: toaster/tests: bug-fix "#hint-error-project-name" should be visible
        bitbake: toaster/tests: Bug-fix "element not interactable" in TestLayerDetailsPage::test_edit_layerdetails
        bitbake: toaster/tests: Bug-fix ToasterTable show_rows testcases

  Alexander Kanavin (16):
        speexdsp: enable native variant
        devtool/standard: correctly escape \
        bitbake: fetch/checkstatus(): do not print the URI twice in FetchError exception
        bitbake: fetch/wget/checkstatus(): include the URL in debugging output about status check failure
        bitbake: bitbake/runqueue: rework 'bitbake -S printdiff' logic
        selftest/sstatetests: fix up printdiff test to match rework of printdiff logic
        selftest/sstatetest: re-enable gcc printdiff test
        python3-pyyaml: make compatible with cython 3.x
        python3-cython: update 0.29.36 -> 3.0.7
        taglib: fix upstream version check
        libpcre2: fix upstream version check
        icon-naming-utils: take tarball from debian
        selftest/sstatetests: include fetcher diagnostics into CDN test failure message
        selftest/SStatePrintdiff: ensure all base signatures are present in sstate in test_image_minimal_vs_base_do_configure
        shadow: update 4.13 -> 4.14.2
        shadow: link executables statically for -native variant

  Chen Qi (5):
        gawk: upgrade from 5.2.2 to 5.3.0
        systemd-bootchart: upgrade from 234 to 235
        dbus-wait: bump srcrev
        sudo: upgrade from 1.9.15p2 to 1.9.15p5
        util-linux/util-linux-libuuid: ugprade from 2.39.2 to 2.39.3

  Corentin Guillevic (1):
        systemd: add udev-bash-completion package

  Enguerrand de Ribaucourt (1):
        manuals: document VSCode extension

  Fabio Estevam (5):
        libusb1: Do not match on -rc versions
        usbutils: Update to version 017
        u-boot: Upgrade to 2024.01
        kmscube: Change header file to <GLES3/gl3.h>
        kmscube: Add package version

  Ilya A. Kriveshko (1):
        dev-manual: update license manifest path

  Jamin Lin (1):
        devtool: modify: fix exception

  Joshua Watt (1):
        syslinux: Allow mtools to be optional

  Jörg Sommer (1):
        documentation: Add UBOOT_BINARY, extend UBOOT_CONFIG

  Khem Raj (6):
        connman: Fix build with musl
        rpm: Fix build with musl
        gawk: Add coreutils to rdeps for ptests package
        tcl: Fix prepending to run-ptest script
        coreutils: Ignore line-bytes.sh and no-allocate tests on musl
        opkg-utils: Backport fix to drop --numeric-owner parameter

  Lee Chee Yang (1):
        migration-guide: add release notes for 4.3.2

  Mark Asselstine (2):
        bitbake: server/process: catch and expand multiprocessing connection exceptions
        bitbake: ui/knotty: properly handle exceptions when calling runCommand()

  Maxin B. John (1):
        ref-manual: classes: remove insserv bbclass

  Michael Opdenacker (2):
        contributor-guide: use "apt" instead of "aptitude"
        ref-manual: update tested and supported distros

  Mikko Rapeli (1):
        oeqa systemd.py: settle() using "running" or "degraded" state

  Ming Liu (1):
        qemu.bbclass: fix a python TypeError

  Mingli Yu (2):
        openssh: Add PACKAGECONFIG option to customize sshd mode
        gptfdisk: Make the version consistent

  Richard Purdie (2):
        bitbake: ast: Fix EXPORT_FUNCTIONS bug
        bitbake: runqueue: Fix runall all bug

  Robert Yang (2):
        bitbake: bitbake: event: Inject empty lines to make code match lineno in filename
        bitbake: bitbake: tests/event: Add test_lineno_in_eventhandler

  Rodrigo M. Duarte (1):
        linux-firmware: Fix the linux-firmware-bcm4373 FILES variable

  Ross Burton (12):
        glib-2.0: no need to depend on target gtk-doc
        autotools: append to EXTRA_AUTORECONF
        autotools: don't exclude gtkdocize
        gtk-doc: fix DEPENDS
        gtk-doc: remove obsolete logic
        gtk-doc: don't use docdir set in environment in gtkdocize
        gtk-doc: don't manually call gtkdocize
        kmod: fix configure with autopoint calling gtkdocize
        util-linux: enable gtk-doc
        meson: use pkg-config in the cross files
        cairo: upgrade to 1.18.0
        xmlcatalog: limit to native recipes only

  Simone Weiß (2):
        dev-manual: start.rst: update use of Download page
        glibc: Set status for CVE-2023-5156 & CVE-2023-0687

  Tim Orling (2):
        python3-bcrypt: upgrade 4.1.1 -> 4.1.2
        python3-attrs: enable ptest

  Wang Mingyu (13):
        ffmpeg: upgrade 6.1 -> 6.1.1
        meson: upgrade 1.3.0 -> 1.3.1
        ccache: upgrade 4.8.3 -> 4.9
        mesa: upgrade 23.3.1 -> 23.3.2
        subversion: upgrade 1.14.2 -> 1.14.3
        python3-dbusmock: upgrade 0.30.1 -> 0.30.2
        python3-hatch-fancy-pypi-readme: upgrade 23.1.0 -> 24.1.0
        python3-hypothesis: upgrade 6.92.1 -> 6.92.2
        python3-pycryptodome: upgrade 3.19.0 -> 3.19.1
        python3-pycryptodomex: upgrade 3.19.0 -> 3.19.1
        python3-pytest: upgrade 7.4.3 -> 7.4.4
        python3-attrs: upgrade 22.1.0 -> 23.2.0
        python3-lxml: upgrade 4.9.4 -> 45.0.0

  William Lyu (1):
        elfutils: Update license information

  Yang Xu (1):
        rootfs.py: check depmodwrapper execution result

  Yi Zhao (2):
        libcap-ng: upgrade 0.8.3 -> 0.8.4
        libcap-ng-python: upgrade 0.8.3 -> 0.8.4

  david d zuhn (1):
        rng-tools: remove obsolete build time dependency on sysfsutils

Change-Id: I43eda44bb889eedb45fae65caf2e5ed8d2c9de39
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/poky/bitbake/lib/bb/event.py b/poky/bitbake/lib/bb/event.py
index f8acacd..4761c86 100644
--- a/poky/bitbake/lib/bb/event.py
+++ b/poky/bitbake/lib/bb/event.py
@@ -257,14 +257,15 @@
         # handle string containing python code
         if isinstance(handler, str):
             tmp = "def %s(e, d):\n%s" % (name, handler)
+            # Inject empty lines to make code match lineno in filename
+            if lineno is not None:
+                tmp = "\n" * (lineno-1) + tmp
             try:
                 code = bb.methodpool.compile_cache(tmp)
                 if not code:
                     if filename is None:
                         filename = "%s(e, d)" % name
                     code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST)
-                    if lineno is not None:
-                        ast.increment_lineno(code, lineno-1)
                     code = compile(code, filename, "exec")
                     bb.methodpool.compile_cache_add(tmp, code)
             except SyntaxError:
diff --git a/poky/bitbake/lib/bb/fetch2/__init__.py b/poky/bitbake/lib/bb/fetch2/__init__.py
index 22a2f80..677968a 100644
--- a/poky/bitbake/lib/bb/fetch2/__init__.py
+++ b/poky/bitbake/lib/bb/fetch2/__init__.py
@@ -1947,7 +1947,7 @@
                     ret = m.try_mirrors(self, ud, self.d, mirrors, True)
 
             if not ret:
-                raise FetchError("URL %s doesn't work" % u, u)
+                raise FetchError("URL doesn't work", u)
 
     def unpack(self, root, urls=None):
         """
diff --git a/poky/bitbake/lib/bb/fetch2/wget.py b/poky/bitbake/lib/bb/fetch2/wget.py
index dc88317..dc02580 100644
--- a/poky/bitbake/lib/bb/fetch2/wget.py
+++ b/poky/bitbake/lib/bb/fetch2/wget.py
@@ -375,7 +375,7 @@
                     return self.checkstatus(fetch, ud, d, False)
                 else:
                     # debug for now to avoid spamming the logs in e.g. remote sstate searches
-                    logger.debug2("checkstatus() urlopen failed: %s" % e)
+                    logger.debug2("checkstatus() urlopen failed for %s: %s" % (uri,e))
                     return False
 
         return True
diff --git a/poky/bitbake/lib/bb/parse/ast.py b/poky/bitbake/lib/bb/parse/ast.py
index 6441c5c..d30b688 100644
--- a/poky/bitbake/lib/bb/parse/ast.py
+++ b/poky/bitbake/lib/bb/parse/ast.py
@@ -211,10 +211,12 @@
 
     def eval(self, data):
 
+        sentinel = "    # Export function set\n"
         for func in self.n:
             calledfunc = self.classname + "_" + func
 
-            if data.getVar(func, False) and not data.getVarFlag(func, 'export_func', False):
+            basevar = data.getVar(func, False)
+            if basevar and sentinel not in basevar:
                 continue
 
             if data.getVar(func, False):
@@ -231,12 +233,11 @@
             data.setVarFlag(func, "lineno", 1)
 
             if data.getVarFlag(calledfunc, "python", False):
-                data.setVar(func, "    bb.build.exec_func('" + calledfunc + "', d)\n", parsing=True)
+                data.setVar(func, sentinel + "    bb.build.exec_func('" + calledfunc + "', d)\n", parsing=True)
             else:
                 if "-" in self.classname:
                    bb.fatal("The classname %s contains a dash character and is calling an sh function %s using EXPORT_FUNCTIONS. Since a dash is illegal in sh function names, this cannot work, please rename the class or don't use EXPORT_FUNCTIONS." % (self.classname, calledfunc))
-                data.setVar(func, "    " + calledfunc + "\n", parsing=True)
-            data.setVarFlag(func, 'export_func', '1')
+                data.setVar(func, sentinel + "    " + calledfunc + "\n", parsing=True)
 
 class AddTaskNode(AstNode):
     def __init__(self, filename, lineno, func, before, after):
diff --git a/poky/bitbake/lib/bb/runqueue.py b/poky/bitbake/lib/bb/runqueue.py
index 5a45943..af11e9a 100644
--- a/poky/bitbake/lib/bb/runqueue.py
+++ b/poky/bitbake/lib/bb/runqueue.py
@@ -1004,26 +1004,32 @@
         # Handle --runall
         if self.cooker.configuration.runall:
             # re-run the mark_active and then drop unused tasks from new list
-            reduced_tasklist = set(self.runtaskentries.keys())
-            for tid in list(self.runtaskentries.keys()):
-                if tid not in runq_build:
-                   reduced_tasklist.remove(tid)
-            runq_build = {}
 
-            for task in self.cooker.configuration.runall:
-                if not task.startswith("do_"):
-                    task = "do_{0}".format(task)
+            runall_tids = set()
+            added = True
+            while added:
+                reduced_tasklist = set(self.runtaskentries.keys())
+                for tid in list(self.runtaskentries.keys()):
+                    if tid not in runq_build:
+                       reduced_tasklist.remove(tid)
+                runq_build = {}
+
+                orig = runall_tids
                 runall_tids = set()
-                for tid in reduced_tasklist:
-                    wanttid = "{0}:{1}".format(fn_from_tid(tid), task)
-                    if wanttid in self.runtaskentries:
-                        runall_tids.add(wanttid)
+                for task in self.cooker.configuration.runall:
+                    if not task.startswith("do_"):
+                        task = "do_{0}".format(task)
+                    for tid in reduced_tasklist:
+                        wanttid = "{0}:{1}".format(fn_from_tid(tid), task)
+                        if wanttid in self.runtaskentries:
+                            runall_tids.add(wanttid)
 
-                for tid in list(runall_tids):
-                    mark_active(tid, 1)
-                    self.target_tids.append(tid)
-                    if self.cooker.configuration.force:
-                        invalidate_task(tid, False)
+                    for tid in list(runall_tids):
+                        mark_active(tid, 1)
+                        self.target_tids.append(tid)
+                        if self.cooker.configuration.force:
+                            invalidate_task(tid, False)
+                added = runall_tids - orig
 
         delcount = set()
         for tid in list(self.runtaskentries.keys()):
@@ -1685,6 +1691,17 @@
         return
 
     def print_diffscenetasks(self):
+        def get_root_invalid_tasks(task, taskdepends, valid, noexec, visited_invalid):
+            invalidtasks = []
+            for t in taskdepends[task].depends:
+                if t not in valid and t not in visited_invalid:
+                    invalidtasks.extend(get_root_invalid_tasks(t, taskdepends, valid, noexec, visited_invalid))
+                    visited_invalid.add(t)
+
+            direct_invalid = [t for t in taskdepends[task].depends if t not in valid]
+            if not direct_invalid and task not in noexec:
+                invalidtasks = [task]
+            return invalidtasks
 
         noexec = []
         tocheck = set()
@@ -1718,35 +1735,35 @@
                     valid_new.add(dep)
 
         invalidtasks = set()
-        for tid in self.rqdata.runtaskentries:
-            if tid not in valid_new and tid not in noexec:
-                invalidtasks.add(tid)
 
-        found = set()
-        processed = set()
-        for tid in invalidtasks:
+        toptasks = set(["{}:{}".format(t[3], t[2]) for t in self.rqdata.targets])
+        for tid in toptasks:
             toprocess = set([tid])
             while toprocess:
                 next = set()
+                visited_invalid = set()
                 for t in toprocess:
-                    for dep in self.rqdata.runtaskentries[t].depends:
-                        if dep in invalidtasks:
-                            found.add(tid)
-                        if dep not in processed:
-                            processed.add(dep)
+                    if t not in valid_new and t not in noexec:
+                        invalidtasks.update(get_root_invalid_tasks(t, self.rqdata.runtaskentries, valid_new, noexec, visited_invalid))
+                        continue
+                    if t in self.rqdata.runq_setscene_tids:
+                        for dep in self.rqexe.sqdata.sq_deps[t]:
                             next.add(dep)
+                        continue
+
+                    for dep in self.rqdata.runtaskentries[t].depends:
+                        next.add(dep)
+
                 toprocess = next
-                if tid in found:
-                    toprocess = set()
 
         tasklist = []
-        for tid in invalidtasks.difference(found):
+        for tid in invalidtasks:
             tasklist.append(tid)
 
         if tasklist:
             bb.plain("The differences between the current build and any cached tasks start at the following tasks:\n" + "\n".join(tasklist))
 
-        return invalidtasks.difference(found)
+        return invalidtasks
 
     def write_diffscenetasks(self, invalidtasks):
         bb.siggen.check_siggen_version(bb.siggen)
diff --git a/poky/bitbake/lib/bb/server/process.py b/poky/bitbake/lib/bb/server/process.py
index d495ac6..6d77ce4 100644
--- a/poky/bitbake/lib/bb/server/process.py
+++ b/poky/bitbake/lib/bb/server/process.py
@@ -500,12 +500,18 @@
         self.recv = recv
 
     def runCommand(self, command):
-        self.connection.send(command)
+        try:
+            self.connection.send(command)
+        except BrokenPipeError as e:
+            raise BrokenPipeError("bitbake-server might have died or been forcibly stopped, ie. OOM killed") from e
         if not self.recv.poll(30):
             logger.info("No reply from server in 30s (for command %s at %s)" % (command[0], currenttime()))
             if not self.recv.poll(30):
                 raise ProcessTimeout("Timeout while waiting for a reply from the bitbake server (60s at %s)" % currenttime())
-        ret, exc = self.recv.get()
+        try:
+            ret, exc = self.recv.get()
+        except EOFError as e:
+            raise EOFError("bitbake-server might have died or been forcibly stopped, ie. OOM killed") from e
         # Should probably turn all exceptions in exc back into exceptions?
         # For now, at least handle BBHandledException
         if exc and ("BBHandledException" in exc or "SystemExit" in exc):
diff --git a/poky/bitbake/lib/bb/tests/event.py b/poky/bitbake/lib/bb/tests/event.py
index d959f2d..ef61891 100644
--- a/poky/bitbake/lib/bb/tests/event.py
+++ b/poky/bitbake/lib/bb/tests/event.py
@@ -13,6 +13,7 @@
 import threading
 import time
 import unittest
+import tempfile
 from unittest.mock import Mock
 from unittest.mock import call
 
@@ -468,6 +469,8 @@
 
     def setUp(self):
         bb.event.worker_pid = EventClassesTest._worker_pid
+        self.d = bb.data.init()
+        bb.parse.siggen = bb.siggen.init(self.d)
 
     def test_Event(self):
         """ Test the Event base class """
@@ -950,3 +953,24 @@
         event = bb.event.FindSigInfoResult(result)
         self.assertEqual(event.result, result)
         self.assertEqual(event.pid, EventClassesTest._worker_pid)
+
+    def test_lineno_in_eventhandler(self):
+        # The error lineno is 5, not 4 since the first line is '\n'
+        error_line = """
+# Comment line1
+# Comment line2
+python test_lineno_in_eventhandler() {
+    This is an error line
+}
+addhandler test_lineno_in_eventhandler
+test_lineno_in_eventhandler[eventmask] = "bb.event.ConfigParsed"
+"""
+
+        with self.assertLogs() as logs:
+            f = tempfile.NamedTemporaryFile(suffix = '.bb')
+            f.write(bytes(error_line, "utf-8"))
+            f.flush()
+            d = bb.parse.handle(f.name, self.d)['']
+
+        output = "".join(logs.output)
+        self.assertTrue(" line 5\n" in output)
diff --git a/poky/bitbake/lib/bb/tests/parse.py b/poky/bitbake/lib/bb/tests/parse.py
index 304bbbe..72d1962 100644
--- a/poky/bitbake/lib/bb/tests/parse.py
+++ b/poky/bitbake/lib/bb/tests/parse.py
@@ -243,3 +243,101 @@
         with self.assertRaises(bb.parse.ParseError):
             d = bb.parse.handle(f.name, self.d)['']
 
+    export_function_recipe = """
+inherit someclass
+"""
+
+    export_function_recipe2 = """
+inherit someclass
+
+do_compile () {
+    false
+}
+
+python do_compilepython () {
+    bb.note("Something else")
+}
+
+"""
+    export_function_class = """
+someclass_do_compile() {
+    true
+}
+
+python someclass_do_compilepython () {
+    bb.note("Something")
+}
+
+EXPORT_FUNCTIONS do_compile do_compilepython
+"""
+
+    export_function_class2 = """
+secondclass_do_compile() {
+    true
+}
+
+python secondclass_do_compilepython () {
+    bb.note("Something")
+}
+
+EXPORT_FUNCTIONS do_compile do_compilepython
+"""
+
+    def test_parse_export_functions(self):
+        def check_function_flags(d):
+            self.assertEqual(d.getVarFlag("do_compile", "func"), 1)
+            self.assertEqual(d.getVarFlag("do_compilepython", "func"), 1)
+            self.assertEqual(d.getVarFlag("do_compile", "python"), None)
+            self.assertEqual(d.getVarFlag("do_compilepython", "python"), "1")
+
+        with tempfile.TemporaryDirectory() as tempdir:
+            self.d.setVar("__bbclasstype", "recipe")
+            recipename = tempdir + "/recipe.bb"
+            os.makedirs(tempdir + "/classes")
+            with open(tempdir + "/classes/someclass.bbclass", "w") as f:
+                f.write(self.export_function_class)
+                f.flush()
+            with open(tempdir + "/classes/secondclass.bbclass", "w") as f:
+                f.write(self.export_function_class2)
+                f.flush()
+
+            with open(recipename, "w") as f:
+                f.write(self.export_function_recipe)
+                f.flush()
+            os.chdir(tempdir)
+            d = bb.parse.handle(recipename, bb.data.createCopy(self.d))['']
+            self.assertIn("someclass_do_compile", d.getVar("do_compile"))
+            self.assertIn("someclass_do_compilepython", d.getVar("do_compilepython"))
+            check_function_flags(d)
+
+            recipename2 = tempdir + "/recipe2.bb"
+            with open(recipename2, "w") as f:
+                f.write(self.export_function_recipe2)
+                f.flush()
+
+            d = bb.parse.handle(recipename2, bb.data.createCopy(self.d))['']
+            self.assertNotIn("someclass_do_compile", d.getVar("do_compile"))
+            self.assertNotIn("someclass_do_compilepython", d.getVar("do_compilepython"))
+            self.assertIn("false", d.getVar("do_compile"))
+            self.assertIn("else", d.getVar("do_compilepython"))
+            check_function_flags(d)
+
+            with open(recipename, "a+") as f:
+                f.write("\ninherit secondclass\n")
+                f.flush()
+            with open(recipename2, "a+") as f:
+                f.write("\ninherit secondclass\n")
+                f.flush()
+
+            d = bb.parse.handle(recipename, bb.data.createCopy(self.d))['']
+            self.assertIn("secondclass_do_compile", d.getVar("do_compile"))
+            self.assertIn("secondclass_do_compilepython", d.getVar("do_compilepython"))
+            check_function_flags(d)
+
+            d = bb.parse.handle(recipename2, bb.data.createCopy(self.d))['']
+            self.assertNotIn("someclass_do_compile", d.getVar("do_compile"))
+            self.assertNotIn("someclass_do_compilepython", d.getVar("do_compilepython"))
+            self.assertIn("false", d.getVar("do_compile"))
+            self.assertIn("else", d.getVar("do_compilepython"))
+            check_function_flags(d)
+
diff --git a/poky/bitbake/lib/bb/ui/knotty.py b/poky/bitbake/lib/bb/ui/knotty.py
index 431baa1..5a97d04 100644
--- a/poky/bitbake/lib/bb/ui/knotty.py
+++ b/poky/bitbake/lib/bb/ui/knotty.py
@@ -420,6 +420,11 @@
     except bb.BBHandledException:
         drain_events_errorhandling(eventHandler)
         return 1
+    except Exception as e:
+        # bitbake-server comms failure
+        early_logger = bb.msg.logger_create('bitbake', sys.stdout)
+        early_logger.fatal("Attempting to set server environment: %s", e)
+        return 1
 
     if params.options.quiet == 0:
         console_loglevel = loglevel
@@ -585,7 +590,12 @@
         return
 
     llevel, debug_domains = bb.msg.constructLogOptions()
-    server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list])
+    try:
+        server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list])
+    except (BrokenPipeError, EOFError) as e:
+        # bitbake-server comms failure
+        logger.fatal("Attempting to set event mask: %s", e)
+        return 1
 
     # The logging_tree module is *extremely* helpful in debugging logging
     # domains. Uncomment here to dump the logging tree when bitbake starts
@@ -594,7 +604,11 @@
 
     universe = False
     if not params.observe_only:
-        params.updateFromServer(server)
+        try:
+            params.updateFromServer(server)
+        except Exception as e:
+            logger.fatal("Fetching command line: %s", e)
+            return 1
         cmdline = params.parseActions()
         if not cmdline:
             print("Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.")
@@ -605,7 +619,12 @@
         if cmdline['action'][0] == "buildTargets" and "universe" in cmdline['action'][1]:
             universe = True
 
-        ret, error = server.runCommand(cmdline['action'])
+        try:
+            ret, error = server.runCommand(cmdline['action'])
+        except (BrokenPipeError, EOFError) as e:
+            # bitbake-server comms failure
+            logger.fatal("Command '{}' failed: %s".format(cmdline), e)
+            return 1
         if error:
             logger.error("Command '%s' failed: %s" % (cmdline, error))
             return 1
@@ -854,15 +873,26 @@
 
             logger.error("Unknown event: %s", event)
 
+        except (BrokenPipeError, EOFError) as e:
+            # bitbake-server comms failure, don't attempt further comms and exit
+            logger.fatal("Executing event: %s", e)
+            return_value = 1
+            errors = errors + 1
+            main.shutdown = 3
         except EnvironmentError as ioerror:
             termfilter.clearFooter()
             # ignore interrupted io
             if ioerror.args[0] == 4:
                 continue
             sys.stderr.write(str(ioerror))
-            if not params.observe_only:
-                _, error = server.runCommand(["stateForceShutdown"])
             main.shutdown = 2
+            if not params.observe_only:
+                try:
+                    _, error = server.runCommand(["stateForceShutdown"])
+                except (BrokenPipeError, EOFError) as e:
+                    # bitbake-server comms failure, don't attempt further comms and exit
+                    logger.fatal("Unable to force shutdown: %s", e)
+                    main.shutdown = 3
         except KeyboardInterrupt:
             termfilter.clearFooter()
             if params.observe_only:
@@ -871,9 +901,13 @@
 
             def state_force_shutdown():
                 print("\nSecond Keyboard Interrupt, stopping...\n")
-                _, error = server.runCommand(["stateForceShutdown"])
-                if error:
-                    logger.error("Unable to cleanly stop: %s" % error)
+                try:
+                    _, error = server.runCommand(["stateForceShutdown"])
+                    if error:
+                        logger.error("Unable to cleanly stop: %s" % error)
+                except (BrokenPipeError, EOFError) as e:
+                    # bitbake-server comms failure
+                    logger.fatal("Unable to cleanly stop: %s", e)
 
             if not params.observe_only and main.shutdown == 1:
                 state_force_shutdown()
@@ -886,6 +920,9 @@
                     _, error = server.runCommand(["stateShutdown"])
                     if error:
                         logger.error("Unable to cleanly shutdown: %s" % error)
+                except (BrokenPipeError, EOFError) as e:
+                    # bitbake-server comms failure
+                    logger.fatal("Unable to cleanly shutdown: %s", e)
                 except KeyboardInterrupt:
                     state_force_shutdown()
 
@@ -893,9 +930,14 @@
         except Exception as e:
             import traceback
             sys.stderr.write(traceback.format_exc())
-            if not params.observe_only:
-                _, error = server.runCommand(["stateForceShutdown"])
             main.shutdown = 2
+            if not params.observe_only:
+                try:
+                    _, error = server.runCommand(["stateForceShutdown"])
+                except (BrokenPipeError, EOFError) as e:
+                    # bitbake-server comms failure, don't attempt further comms and exit
+                    logger.fatal("Unable to force shutdown: %s", e)
+                    main.shudown = 3
             return_value = 1
     try:
         termfilter.clearFooter()
diff --git a/poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py b/poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py
index 562fede..393be75 100644
--- a/poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py
+++ b/poky/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py
@@ -182,6 +182,13 @@
         abs_url = '%s%s' % (self.live_server_url, url)
         self.driver.get(abs_url)
 
+        try:  # Ensure page is loaded before proceeding
+            self.wait_until_visible("#global-nav", poll=3)
+        except NoSuchElementException:
+            self.driver.implicitly_wait(3)
+        except TimeoutException:
+            self.driver.implicitly_wait(3)
+
     def find(self, selector):
         """ Find single element by CSS selector """
         return self.driver.find_element(By.CSS_SELECTOR, selector)
diff --git a/poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py b/poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py
index 7019b3d..b9356a0 100644
--- a/poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py
+++ b/poky/bitbake/lib/toaster/tests/browser/test_all_builds_page.py
@@ -224,6 +224,7 @@
 
         url = reverse('all-builds')
         self.get(url)
+        self.wait_until_visible('#allbuildstable', poll=3)
 
         # get the project name cells from the table
         cells = self.find_all('#allbuildstable td[class="project"]')
@@ -232,7 +233,7 @@
 
         for cell in cells:
             content = cell.get_attribute('innerHTML')
-            help_icons = cell.find_elements_by_css_selector(selector)
+            help_icons = cell.find_elements(By.CSS_SELECTOR, selector)
 
             if re.search(self.PROJECT_NAME, content):
                 # no help icon next to non-cli project name
@@ -256,6 +257,7 @@
 
         url = reverse('all-builds')
         self.get(url)
+        self.wait_until_visible('#allbuildstable', poll=3)
 
         # test recent builds area for successful build
         element = self._get_build_time_element(build1)
@@ -450,9 +452,10 @@
         def test_show_rows(row_to_show, show_row_link):
             # Check that we can show rows == row_to_show
             show_row_link.select_by_value(str(row_to_show))
-            self.wait_until_visible('#allbuildstable tbody tr', poll=2)
+            self.wait_until_visible('#allbuildstable tbody tr', poll=3)
+            # check at least some rows are visible
             self.assertTrue(
-                len(self.find_all('#allbuildstable tbody tr')) == row_to_show
+                len(self.find_all('#allbuildstable tbody tr')) > 0
             )
 
         url = reverse('all-builds')
diff --git a/poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py b/poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
index 6540dfa..9ed1901 100644
--- a/poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
+++ b/poky/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
@@ -314,8 +314,9 @@
             # Check that we can show rows == row_to_show
             show_row_link.select_by_value(str(row_to_show))
             self.wait_until_visible('#projectstable tbody tr', poll=3)
+            # check at least some rows are visible
             self.assertTrue(
-                len(self.find_all('#projectstable tbody tr')) == row_to_show
+                len(self.find_all('#projectstable tbody tr')) > 0
             )
 
         url = reverse('all-projects')
diff --git a/poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py b/poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py
index b713f30..d838ce3 100644
--- a/poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py
+++ b/poky/bitbake/lib/toaster/tests/browser/test_builddashboard_page.py
@@ -162,6 +162,7 @@
         """
         url = reverse('builddashboard', args=(build.id,))
         self.get(url)
+        self.wait_until_visible('#global-nav', poll=3)
 
     def _get_build_dashboard_errors(self, build):
         """
diff --git a/poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py b/poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py
index 9deef67..5c29548 100644
--- a/poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py
+++ b/poky/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py
@@ -64,7 +64,7 @@
                            args=(self.project.pk,
                                  self.imported_layer_version.pk))
 
-    def test_edit_layerdetails(self):
+    def _edit_layerdetails(self):
         """ Edit all the editable fields for the layer refresh the page and
         check that the new values exist"""
 
@@ -168,6 +168,13 @@
                         "Expected %s in the dir value for layer directory" %
                         new_dir)
 
+    def test_edit_layerdetails_page(self):
+        try:
+            self._edit_layerdetails()
+        except ElementClickInterceptedException:
+            self.skipTest(
+                "ElementClickInterceptedException occured. Element not visible or maybe covered by another element.")
+
     def test_delete_layer(self):
         """ Delete the layer """
 
diff --git a/poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py b/poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py
index 4ad22c7..9f0b639 100644
--- a/poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py
+++ b/poky/bitbake/lib/toaster/tests/browser/test_new_custom_image_page.py
@@ -90,6 +90,7 @@
         """
         url = reverse('newcustomimage', args=(self.project.id,))
         self.get(url)
+        self.wait_until_visible('#global-nav', poll=3)
 
         self.click('button[data-recipe="%s"]' % self.recipe.id)
 
diff --git a/poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py b/poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py
index 0c33c44..458bb65 100644
--- a/poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py
+++ b/poky/bitbake/lib/toaster/tests/browser/test_new_project_page.py
@@ -47,6 +47,7 @@
 
         url = reverse('newproject')
         self.get(url)
+        self.wait_until_visible('#new-project-name', poll=3)
         self.enter_text('#new-project-name', project_name)
 
         select = Select(self.find('#projectversion'))
@@ -78,6 +79,7 @@
 
         url = reverse('newproject')
         self.get(url)
+        self.wait_until_visible('#new-project-name', poll=3)
 
         self.enter_text('#new-project-name', project_name)
 
@@ -89,7 +91,8 @@
 
         self.click("#create-project-button")
 
-        element = self.wait_until_visible('#hint-error-project-name', poll=3)
+        self.wait_until_present('#hint-error-project-name', poll=3)
+        element = self.find('#hint-error-project-name')
 
         self.assertTrue(("Project names must be unique" in element.text),
                         "Did not find unique project name error message")
diff --git a/poky/bitbake/lib/toaster/tests/functional/test_create_new_project.py b/poky/bitbake/lib/toaster/tests/functional/test_create_new_project.py
index 9f88010..94d9045 100644
--- a/poky/bitbake/lib/toaster/tests/functional/test_create_new_project.py
+++ b/poky/bitbake/lib/toaster/tests/functional/test_create_new_project.py
@@ -32,6 +32,7 @@
           - Merge Toaster settings: True or False
         """
         self.get(reverse('newproject'))
+        self.wait_until_visible('#new-project-name', poll=3)
         self.driver.find_element(By.ID,
                                  "new-project-name").send_keys(project_name)
 
@@ -111,7 +112,7 @@
         """
         release = '5'
         release_title = 'Yocto Project 3.1 "Dunfell"'
-        project_name = 'projectdunfull'
+        project_name = 'projectdunfell'
         self._create_test_new_project(
             project_name,
             release,
diff --git a/poky/bitbake/lib/toaster/tests/functional/test_project_page.py b/poky/bitbake/lib/toaster/tests/functional/test_project_page.py
index 31177cc..adbe358 100644
--- a/poky/bitbake/lib/toaster/tests/functional/test_project_page.py
+++ b/poky/bitbake/lib/toaster/tests/functional/test_project_page.py
@@ -192,9 +192,10 @@
         def test_show_rows(row_to_show, show_row_link):
             # Check that we can show rows == row_to_show
             show_row_link.select_by_value(str(row_to_show))
-            self.wait_until_visible(f'#{table_selector} tbody tr', poll=2)
+            self.wait_until_visible(f'#{table_selector} tbody tr', poll=3)
+            # check at least some rows are visible
             self.assertTrue(
-                len(self.find_all(f'#{table_selector} tbody tr')) == row_to_show
+                len(self.find_all(f'#{table_selector} tbody tr')) > 0
             )
         self.wait_until_present(f'#{table_selector} tbody tr')
         show_rows = self.driver.find_elements(
diff --git a/poky/bitbake/lib/toaster/tests/functional/test_project_page_tab_config.py b/poky/bitbake/lib/toaster/tests/functional/test_project_page_tab_config.py
index ee1f5c4..eb905dd 100644
--- a/poky/bitbake/lib/toaster/tests/functional/test_project_page_tab_config.py
+++ b/poky/bitbake/lib/toaster/tests/functional/test_project_page_tab_config.py
@@ -12,7 +12,7 @@
 from django.urls import reverse
 from selenium.webdriver import Keys
 from selenium.webdriver.support.select import Select
-from selenium.common.exceptions import NoSuchElementException, TimeoutException
+from selenium.common.exceptions import ElementClickInterceptedException, NoSuchElementException, TimeoutException
 from orm.models import Project
 from tests.functional.functional_helpers import SeleniumFunctionalTestCase
 from selenium.webdriver.common.by import By
@@ -253,9 +253,10 @@
         def test_show_rows(row_to_show, show_row_link):
             # Check that we can show rows == row_to_show
             show_row_link.select_by_value(str(row_to_show))
-            self.wait_until_visible('#imagerecipestable tbody tr')
+            self.wait_until_visible('#imagerecipestable tbody tr', poll=3)
+            # check at least some rows are visible
             self.assertTrue(
-                len(self.find_all('#imagerecipestable tbody tr')) == row_to_show
+                len(self.find_all('#imagerecipestable tbody tr'))  > 0
             )
 
         self._navigate_to_project_page()
@@ -361,7 +362,11 @@
             By.XPATH,
             '//*[@id="layer-container"]/form/div/span/div'
         )
-        dropdown_item.click()
+        try:
+            dropdown_item.click()
+        except ElementClickInterceptedException:
+            self.skipTest(
+                "layer-container dropdown item click intercepted. Element not properly visible.")
         add_layer_btn = layers.find_element(By.ID, 'add-layer-btn')
         add_layer_btn.click()
         self.wait_until_visible('#layers-in-project-list')