subtree updates

poky: 492205ea83..94dfcaff64:
  Alejandro Hernandez Samaniego (1):
        baremetal-helloworld: Enable RISC-V 32 port

  Alexandre Belloni (1):
        oeqa/runtime/cases: make date.DateTest.test_date more reliable

  Anton Blanchard (3):
        libjpeg-turbo: Handle powerpc64le without Altivec
        kmod: use nonarch_base_libdir for depmod.d and modprobe.d
        pixman: Handle PowerPC without Altivec

  Changqing Li (1):
        libconvert-asn1-perl: 0.27 -> 0.31

  Chen Qi (4):
        convert-overrides.py: also convert comments without a leading whitespace
        meta: use new override syntax in comments
        multilib.bbclass: fix new override syntax for virtclass-multilib
        util-linux: add back manpages related settings

  Daniel Gomez (1):
        docs: fix typo in releases

  Dmitry Baryshkov (1):
        linux-firmware: add more Qualcomm firmware packages

  Dragos-Marian Panait (1):
        util-linux: fix CVE-2021-37600

  Joe Slater (1):
        terminal.bbclass: force bash for devshell

  Jon Mason (1):
        tune-cortexm*: add support for all Arm Cortex-M processors

  Jose Quaresma (1):
        sstate.bbclass: fix error handling when sstate mirrors is ro

  Joshua Watt (2):
        classes/cve-check: Move get_patches_cves to library
        lib/packagedata: Fix for new overrides

  Khem Raj (4):
        glibc: Upgrade to 2.34 release
        glibc: Remove obsolete --enable-stackguard-randomization
        glibc: Drop DUMMY_LOCALE_T define patch
        glibc: Add missing symlinks for libpthread and librt dev files

  Michael Halstead (1):
        releases: update to include 3.1.10

  Michael Opdenacker (12):
        manuals: mention license information in footer
        manuals: further documentation for cve-check
        cve-check: remove deprecated CVE_CHECK_CVE_WHITELIST
        bsp-guide: overrides syntax updates
        dev-manual: overrides syntax updates
        kernel-dev manual: overrides syntax updates
        ref-manual: overrides syntax updates
        sdk-manual: overrides syntax updates
        test-manual: overrides syntax updates
        sdk-manual: reference obsolete reference to ADT
        Manuals: replace "file name" by "filename"
        dev-manual: fix grammar in post-install script explanations

  Nisha Parrakat (1):
        dbus_%.bbappend: stop using selinux_set_mapping

  Olaf Mandel (1):
        kickstart: document which options accept units

  Patrick Williams (3):
        pixman: re-disable iwmmxt
        systemd: add zstd PACKAGECONFIG
        systemd: set zstd as default PACKAGECONFIG

  Paul Barker (2):
        u-boot: Package extlinux.conf separately
        pypi: Allow override of PyPI archive name

  Quentin Schulz (3):
        insane.bbclass: fix new override syntax migration
        docs: fix new override syntax migration
        docs: overview-manual: concepts: remove long-gone BBHASHDEPS variable

  Richard Purdie (6):
        test-manual: Add extra detail to YP Compatible section
        migration-3.4: Add extra notes to override syntax changes
        ruby: Fix DEBUG_PREFIX_MAP in LDFLAGS issue
        gettext: Fix reproducibility issue with LDFLAGS
        curl: Fix reproducibility issue with LDFLAGS
        libtool: Fix lto option passing for reproducible builds

  Ross Burton (11):
        e2fsprogs: ensure small images have 256-byte inodes
        wic: don't forcibly pass -T default
        parted: drop unneeded ld-is-gold patch
        parted: update patch status
        buildtools-tarball: add testsdk task
        oeqa/sdk: add some buildtools tests
        bitbake: utils: add environment updating context manager
        bitbake: fetch2: expose environment variable names that need to be exported
        bitbake: fetch2/wget: ensure all variables are set when calling urllib
        bitbake: fetch2/wget: fetch securely by default
        tar: ignore node-tar CVEs

  Thomas Perrot (2):
        kernel-fitimage: images should not be signed with the same keys as the configurations
        oeqa/selftest/fitimage: update tests to use two keys

  Tim Orling (3):
        python3-scons{-native}: upgrade 4.1.0 -> 4.2.0
        perl: do_create_rdepends_inc override syntax
        package.bbclass: FILER* override syntax

  Tom Rini (2):
        common-tasks: Add a summary to the end of the bbappend example
        manuals: Rename the "Using .bbappend Files in Your Layer" section

  Tony Battersby (2):
        bitbake.conf: add DEBUG_PREFIX_MAP to TARGET_LDFLAGS
        ruby: Fix reproducibility issue with LDFLAGS

  Tony Tascioglu (1):
        valgrind: skip broken ptests for glibc 2.34

  Vyacheslav Yurkov (7):
        lib/oe: add generic functions for overlayfs
        overlayfs.bbclass: generate overlayfs mount units
        rootfs-postcommands: add QA check for overlayfs
        systemd-machine-units: add bbappend for meta-selftest
        overlayfs: meta-selftest recipe
        oeqa/selftest: overlayfs unit tests
        MAINTAINERS: add overlayfs maintainer

  Yi Zhao (3):
        dbus: add PACKAGECONFIG for audit and selinux
        glib-2.0: add PACKAGECONFIG for selinux
        shadow: add PACKAGECONFIG for audit and selinux

  hongxu (1):
        sdk: fix relocate symlink failed

  wangmy (1):
        ell: upgrade 0.41 -> 0.42

meta-raspberrypi: c7f4c739a3..32921fc9bd:
  Omer Akram (1):
        linux-firmware-rpidistro: fix wifi driver loading on cm4

  Otavio Salvador (1):
        rpi-config: Allow setting hdmi_cvt

meta-openembedded: 3cf2475ea0..a13db91f19:
  Changqing Li (1):
        ndpi: fix CVE-2021-36082

  Chen Qi (1):
        Convert to new override syntax using latest convert-overrides.py script

  Dmitry Baryshkov (1):
        image_types_sparse: fix sparse image generation

  Geoff Parker (1):
        cifs-utils: typo fix fakse --> false

  Kai Kang (2):
        libdbi-perl: fix CVE-2014-10402
        python3-m2crypto: fix for new overrides syntax

  Khem Raj (1):
        packagegroup-meta-oe: Add ttf-ipa

  Leon Anavi (15):
        python3-astroid: Upgrade 2.6.5 -> 2.6.6
        python3-gast: Upgrade 0.5.1 -> 0.5.2
        python3-greenlet: Upgrade 1.1.0 -> 1.1.1
        python3-bitarray: Upgrade 2.2.3 -> 2.2.5
        python3-send2trash: Upgrade 1.7.1 -> 1.8.0
        python3-zeroconf: Upgrade 0.33.2 -> 0.34.3
        python3-aiohue: Upgrade 2.5.1 -> 2.6.1
        python3-configargparse: Upgrade 1.5.1 -> 1.5.2
        python3-pycurl: Upgrade 7.43.0.6 -> 7.44.0
        python3-distro: Upgrade 1.5.0 -> 1.6.0
        python3-google-api-core: Upgrade 1.30.0 -> 1.31.1
        python3-google-auth: Upgrade 1.32.0 -> 1.34.0
        python3-google-api-python-client: Upgrade 2.12.0 -> 2.15.0
        python3-huey: Upgrade 2.3.2 -> 2.4.0
        python3-apply-defaults: Upgrade 0.1.4 -> 0.1.6

  Martin Jansa (1):
        python3-grpcio: make sure that GRPC_CFLAGS is expanded to empty

  Michael Opdenacker (3):
        vorbis-tools: update to 1.4.2 (latest in 1.4.x series)
        bigbuckbunny-1080p: fix sample video URL
        opus-tools: update to 0.2, move to meta-multimedia and fix license

  Mingli Yu (3):
        jemalloc: fix the race during do_install
        jemalloc: add ptest support
        jemalloc: improve the ptest output

  Naveen Saini (1):
        python3-defusedxml: extend recipe to add native support

  Philippe Coval (1):
        mycroft: Install more tools needed by scripts

  Tony Battersby (3):
        curlpp: fix QA Issue after LDFLAGS change
        ldns: fix QA Issue after LDFLAGS change
        tcsh: fix compile error after LDFLAGS change

  Yi Zhao (5):
        audit: upgrade 3.0.3 -> 3.0.4
        augeas: rename PACKAGECONFIG[libselinux] to PACKAGECONFIG[selinux]
        network-manager-applet: add selinux to PACKAGECONFIG if enable selinux distro feature
        networkmanager: add PACKAGECONFIG for audit and selinux
        augeas: add selinux to PACKAGECONFIG if enable selinux distro feature

  leimaohui (1):
        ttf-ipa: Added a new font.

  wangmy (1):
        iwd: upgrade 1.15 -> 1.16

  zangrc (1):
        python3-humanize: upgrade 3.10.0 -> 3.11.0

  zhengruoqin (3):
        python3-engineio: upgrade 4.2.0 -> 4.2.1
        python3-ipython: upgrade 7.25.0 -> 7.26.0
        python3-isort: upgrade 5.9.2 -> 5.9.3

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I7a8bd19709f465db51254ed3fcaf2486fe64dcaf
diff --git a/poky/meta/lib/oe/cve_check.py b/poky/meta/lib/oe/cve_check.py
index a1d7c29..0302bee 100644
--- a/poky/meta/lib/oe/cve_check.py
+++ b/poky/meta/lib/oe/cve_check.py
@@ -63,3 +63,86 @@
     else:
         _pre = float(pre_v) if pre_v else float('-inf')
     return _release, _patch, _pre
+
+
+def get_patched_cves(d):
+    """
+    Get patches that solve CVEs using the "CVE: " tag.
+    """
+
+    import re
+    import oe.patch
+
+    pn = d.getVar("PN")
+    cve_match = re.compile("CVE:( CVE\-\d{4}\-\d+)+")
+
+    # Matches the last "CVE-YYYY-ID" in the file name, also if written
+    # in lowercase. Possible to have multiple CVE IDs in a single
+    # file name, but only the last one will be detected from the file name.
+    # However, patch files contents addressing multiple CVE IDs are supported
+    # (cve_match regular expression)
+
+    cve_file_name_match = re.compile(".*([Cc][Vv][Ee]\-\d{4}\-\d+)")
+
+    patched_cves = set()
+    bb.debug(2, "Looking for patches that solves CVEs for %s" % pn)
+    for url in oe.patch.src_patches(d):
+        patch_file = bb.fetch.decodeurl(url)[2]
+
+        if not os.path.isfile(patch_file):
+            bb.error("File Not found: %s" % patch_file)
+            raise FileNotFoundError
+
+        # Check patch file name for CVE ID
+        fname_match = cve_file_name_match.search(patch_file)
+        if fname_match:
+            cve = fname_match.group(1).upper()
+            patched_cves.add(cve)
+            bb.debug(2, "Found CVE %s from patch file name %s" % (cve, patch_file))
+
+        with open(patch_file, "r", encoding="utf-8") as f:
+            try:
+                patch_text = f.read()
+            except UnicodeDecodeError:
+                bb.debug(1, "Failed to read patch %s using UTF-8 encoding"
+                        " trying with iso8859-1" %  patch_file)
+                f.close()
+                with open(patch_file, "r", encoding="iso8859-1") as f:
+                    patch_text = f.read()
+
+        # Search for one or more "CVE: " lines
+        text_match = False
+        for match in cve_match.finditer(patch_text):
+            # Get only the CVEs without the "CVE: " tag
+            cves = patch_text[match.start()+5:match.end()]
+            for cve in cves.split():
+                bb.debug(2, "Patch %s solves %s" % (patch_file, cve))
+                patched_cves.add(cve)
+                text_match = True
+
+        if not fname_match and not text_match:
+            bb.debug(2, "Patch %s doesn't solve CVEs" % patch_file)
+
+    return patched_cves
+
+
+def get_cpe_ids(cve_product, version):
+    """
+    Get list of CPE identifiers for the given product and version
+    """
+
+    version = version.split("+git")[0]
+
+    cpe_ids = []
+    for product in cve_product.split():
+        # CVE_PRODUCT in recipes may include vendor information for CPE identifiers. If not,
+        # use wildcard for vendor.
+        if ":" in product:
+            vendor, product = product.split(":", 1)
+        else:
+            vendor = "*"
+
+        cpe_id = f'cpe:2.3:a:{vendor}:{product}:{version}:*:*:*:*:*:*:*'
+        cpe_ids.append(cpe_id)
+
+    return cpe_ids
diff --git a/poky/meta/lib/oe/overlayfs.py b/poky/meta/lib/oe/overlayfs.py
new file mode 100644
index 0000000..21ef710
--- /dev/null
+++ b/poky/meta/lib/oe/overlayfs.py
@@ -0,0 +1,43 @@
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# This file contains common functions for overlayfs and its QA check
+
+# this function is based on https://github.com/systemd/systemd/blob/main/src/basic/unit-name.c
+def escapeSystemdUnitName(path):
+    escapeMap = {
+        '/': '-',
+        '-': "\\x2d",
+        '\\': "\\x5d"
+    }
+    return "".join([escapeMap.get(c, c) for c in path.strip('/')])
+
+def strForBash(s):
+    return s.replace('\\', '\\\\')
+
+def mountUnitName(unit):
+    return escapeSystemdUnitName(unit) + '.mount'
+
+def helperUnitName(unit):
+    return escapeSystemdUnitName(unit) + '-create-upper-dir.service'
+
+def unitFileList(d):
+    fileList = []
+    overlayMountPoints = d.getVarFlags("OVERLAYFS_MOUNT_POINT")
+
+    if not overlayMountPoints:
+        bb.fatal("A recipe uses overlayfs class but there is no OVERLAYFS_MOUNT_POINT set in your MACHINE configuration")
+
+    # check that we have required mount points set first
+    requiredMountPoints = d.getVarFlags('OVERLAYFS_WRITABLE_PATHS')
+    for mountPoint in requiredMountPoints:
+        if mountPoint not in overlayMountPoints:
+            bb.fatal("Missing required mount point for OVERLAYFS_MOUNT_POINT[%s] in your MACHINE configuration" % mountPoint)
+
+    for mountPoint in overlayMountPoints:
+        for path in d.getVarFlag('OVERLAYFS_WRITABLE_PATHS', mountPoint).split():
+            fileList.append(mountUnitName(path))
+            fileList.append(helperUnitName(path))
+
+    return fileList
+
diff --git a/poky/meta/lib/oe/packagedata.py b/poky/meta/lib/oe/packagedata.py
index 22261d2..0b17897 100644
--- a/poky/meta/lib/oe/packagedata.py
+++ b/poky/meta/lib/oe/packagedata.py
@@ -45,14 +45,14 @@
     return read_pkgdatafile(fn)
 
 #
-# Collapse FOO_pkg variables into FOO
+# Collapse FOO:pkg variables into FOO
 #
 def read_subpkgdata_dict(pkg, d):
     ret = {}
     subd = read_pkgdatafile(get_subpkgedata_fn(pkg, d))
     for var in subd:
-        newvar = var.replace("_" + pkg, "")
-        if newvar == var and var + "_" + pkg in subd:
+        newvar = var.replace(":" + pkg, "")
+        if newvar == var and var + ":" + pkg in subd:
             continue
         ret[newvar] = subd[var]
     return ret
diff --git a/poky/meta/lib/oeqa/runtime/cases/date.py b/poky/meta/lib/oeqa/runtime/cases/date.py
index e143229..bd65374 100644
--- a/poky/meta/lib/oeqa/runtime/cases/date.py
+++ b/poky/meta/lib/oeqa/runtime/cases/date.py
@@ -28,14 +28,13 @@
         self.assertEqual(status, 0, msg=msg)
         oldDate = output
 
-        sampleDate = '"2016-08-09 10:00:00"'
-        (status, output) = self.target.run("date -s %s" % sampleDate)
+        sampleTimestamp = 1488800000
+        (status, output) = self.target.run("date -s @%d" % sampleTimestamp)
         self.assertEqual(status, 0, msg='Date set failed, output: %s' % output)
 
-        (status, output) = self.target.run("date -R")
-        p = re.match('Tue, 09 Aug 2016 10:00:.. \+0000', output)
+        (status, output) = self.target.run('date +"%s"')
         msg = 'The date was not set correctly, output: %s' % output
-        self.assertTrue(p, msg=msg)
+        self.assertTrue(int(output) - sampleTimestamp < 300, msg=msg)
 
         (status, output) = self.target.run('date -s "%s"' % oldDate)
         msg = 'Failed to reset date, output: %s' % output
diff --git a/poky/meta/lib/oeqa/sdk/buildtools-cases/README b/poky/meta/lib/oeqa/sdk/buildtools-cases/README
new file mode 100644
index 0000000..d4f20fa
--- /dev/null
+++ b/poky/meta/lib/oeqa/sdk/buildtools-cases/README
@@ -0,0 +1,2 @@
+These test cases are used by buildtools-tarball, and are not used by the testsdk
+class.
diff --git a/poky/meta/lib/oeqa/sdk/buildtools-cases/build.py b/poky/meta/lib/oeqa/sdk/buildtools-cases/build.py
new file mode 100644
index 0000000..5a17ab9
--- /dev/null
+++ b/poky/meta/lib/oeqa/sdk/buildtools-cases/build.py
@@ -0,0 +1,23 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
+import os, tempfile
+from oeqa.sdk.case import OESDKTestCase
+from oeqa.utils.subprocesstweak import errors_have_output
+errors_have_output()
+
+class BuildTests(OESDKTestCase):
+    """
+    Verify that bitbake can build virtual/libc inside the buildtools.
+    """
+    def test_libc(self):
+        with tempfile.TemporaryDirectory(prefix='bitbake-build-', dir=self.tc.sdk_dir) as testdir:
+            corebase = self.td['COREBASE']
+
+            self._run('. %s/oe-init-build-env %s' % (corebase, testdir))
+            with open(os.path.join(testdir, 'conf', 'local.conf'), 'ta') as conf:
+                conf.write('\n')
+                conf.write('DL_DIR = "%s"\n' % self.td['DL_DIR'])
+
+            self._run('. %s/oe-init-build-env %s && bitbake virtual/libc' % (corebase, testdir))
diff --git a/poky/meta/lib/oeqa/sdk/buildtools-cases/sanity.py b/poky/meta/lib/oeqa/sdk/buildtools-cases/sanity.py
new file mode 100644
index 0000000..64baaa8
--- /dev/null
+++ b/poky/meta/lib/oeqa/sdk/buildtools-cases/sanity.py
@@ -0,0 +1,22 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
+import shutil
+import os.path
+from oeqa.sdk.case import OESDKTestCase
+
+class SanityTests(OESDKTestCase):
+    def test_tools(self):
+        """
+        Test that wget and tar come from the buildtools, not the host. This
+        verifies that the buildtools have installed correctly. We can't check
+        for gcc as that is only installed by buildtools-extended.
+        """
+        for command in ("tar", "wget"):
+            # Canonicalise the SDK root
+            sdk_base = os.path.realpath(self.tc.sdk_dir)
+            # Canonicalise the location of this command
+            tool_path = os.path.realpath(self._run("command -v %s" % command).strip())
+            # Assert that the tool was found inside the SDK root
+            self.assertEquals(os.path.commonprefix((sdk_base, tool_path)), sdk_base)
diff --git a/poky/meta/lib/oeqa/selftest/cases/fitimage.py b/poky/meta/lib/oeqa/selftest/cases/fitimage.py
index 815ee48..184c877 100644
--- a/poky/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/poky/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -114,7 +114,8 @@
 UBOOT_SIGN_ENABLE = "1"
 FIT_GENERATE_KEYS = "1"
 UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
 FIT_SIGN_INDIVIDUAL = "1"
 UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
 """
@@ -173,11 +174,11 @@
 
         reqsigvalues_image = {
             'algo': '"sha256,rsa2048"',
-            'key-name-hint': '"oe-selftest"',
+            'key-name-hint': '"img-oe-selftest"',
         }
         reqsigvalues_config = {
             'algo': '"sha256,rsa2048"',
-            'key-name-hint': '"oe-selftest"',
+            'key-name-hint': '"cfg-oe-selftest"',
             'sign-images': '"kernel", "fdt"',
         }
 
@@ -215,7 +216,10 @@
         self.assertIn('conf-am335x-boneblack.dtb', signed_sections)
         for signed_section, values in signed_sections.items():
             value = values.get('Sign algo', None)
-            self.assertEqual(value, 'sha256,rsa2048:oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
+            if signed_section.startswith("conf"):
+                self.assertEqual(value, 'sha256,rsa2048:cfg-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
+            else:
+                self.assertEqual(value, 'sha256,rsa2048:img-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
             value = values.get('Sign value', None)
             self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section)
 
@@ -266,7 +270,8 @@
 UBOOT_SIGN_ENABLE = "1"
 FIT_GENERATE_KEYS = "1"
 UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
 FIT_SIGN_INDIVIDUAL = "1"
 """
         self.write_config(config)
@@ -348,7 +353,8 @@
 UBOOT_SIGN_ENABLE = "1"
 FIT_GENERATE_KEYS = "1"
 UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
 FIT_SIGN_INDIVIDUAL = "1"
 UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot comment'"
 """
@@ -592,7 +598,8 @@
 UBOOT_SIGN_ENABLE = "1"
 FIT_GENERATE_KEYS = "1"
 UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
-UBOOT_SIGN_KEYNAME = "kernel-oe-selftest"
+UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
+UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
 FIT_SIGN_INDIVIDUAL = "1"
 """
         self.write_config(config)
diff --git a/poky/meta/lib/oeqa/selftest/cases/overlayfs.py b/poky/meta/lib/oeqa/selftest/cases/overlayfs.py
new file mode 100644
index 0000000..0184d52
--- /dev/null
+++ b/poky/meta/lib/oeqa/selftest/cases/overlayfs.py
@@ -0,0 +1,171 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu
+
+class OverlayFSTests(OESelftestTestCase):
+    """Overlayfs class usage tests"""
+
+    def getline(self, res, line):
+        for l in res.output.split('\n'):
+            if line in l:
+                return l
+
+    def add_overlay_conf_to_machine(self):
+        machine_inc = """
+OVERLAYFS_MOUNT_POINT[mnt-overlay] = "/mnt/overlay"
+"""
+        self.set_machine_config(machine_inc)
+
+    def test_distro_features_missing(self):
+        """
+        Summary:   Check that required DISTRO_FEATURES are set
+        Expected:  Fail when either systemd or overlayfs are not in DISTRO_FEATURES
+        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
+        """
+
+        config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+"""
+        overlayfs_recipe_append = """
+inherit overlayfs
+"""
+        self.write_config(config)
+        self.add_overlay_conf_to_machine()
+        self.write_recipeinc('overlayfs-user', overlayfs_recipe_append)
+
+        res = bitbake('core-image-minimal', ignore_status=True)
+        line = self.getline(res, "overlayfs-user was skipped: missing required distro features")
+        self.assertTrue("overlayfs" in res.output, msg=res.output)
+        self.assertTrue("systemd" in res.output, msg=res.output)
+        self.assertTrue("ERROR: Required build target 'core-image-minimal' has no buildable providers." in res.output, msg=res.output)
+
+    def test_not_all_units_installed(self):
+        """
+        Summary:   Test QA check that we have required mount units in the image
+        Expected:  Fail because mount unit for overlay partition is not installed
+        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
+        """
+
+        config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+DISTRO_FEATURES += "systemd overlayfs"
+"""
+
+        self.write_config(config)
+        self.add_overlay_conf_to_machine()
+
+        res = bitbake('core-image-minimal', ignore_status=True)
+        line = self.getline(res, "Unit name mnt-overlay.mount not found in systemd unit directories")
+        self.assertTrue(line and line.startswith("WARNING:"), msg=res.output)
+        line = self.getline(res, "Not all mount units are installed by the BSP")
+        self.assertTrue(line and line.startswith("ERROR:"), msg=res.output)
+
+    def test_mount_unit_not_set(self):
+        """
+        Summary:   Test whether mount unit was set properly
+        Expected:  Fail because mount unit was not set
+        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
+        """
+
+        config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+DISTRO_FEATURES += "systemd overlayfs"
+"""
+
+        self.write_config(config)
+
+        res = bitbake('core-image-minimal', ignore_status=True)
+        line = self.getline(res, "A recipe uses overlayfs class but there is no OVERLAYFS_MOUNT_POINT set in your MACHINE configuration")
+        self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
+
+    def test_wrong_mount_unit_set(self):
+        """
+        Summary:   Test whether mount unit was set properly
+        Expected:  Fail because not the correct flag used for mount unit
+        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
+        """
+
+        config = """
+IMAGE_INSTALL:append = " overlayfs-user"
+DISTRO_FEATURES += "systemd overlayfs"
+"""
+
+        wrong_machine_config = """
+OVERLAYFS_MOUNT_POINT[usr-share-overlay] = "/usr/share/overlay"
+"""
+
+        self.write_config(config)
+        self.set_machine_config(wrong_machine_config)
+
+        res = bitbake('core-image-minimal', ignore_status=True)
+        line = self.getline(res, "Missing required mount point for OVERLAYFS_MOUNT_POINT[mnt-overlay] in your MACHINE configuration")
+        self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
+
+    def test_correct_image(self):
+        """
+        Summary:   Check that we can create an image when all parameters are
+                   set correctly
+        Expected:  Image is created successfully
+        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
+        """
+
+        config = """
+IMAGE_INSTALL:append = " overlayfs-user systemd-machine-units"
+DISTRO_FEATURES += "systemd overlayfs"
+
+# Use systemd as init manager
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# enable overlayfs in the kernel
+KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
+"""
+
+        systemd_machine_unit_append = """
+SYSTEMD_SERVICE:${PN} += " \
+    mnt-overlay.mount \
+"
+
+do_install:append() {
+    install -d ${D}${systemd_system_unitdir}
+    cat <<EOT > ${D}${systemd_system_unitdir}/mnt-overlay.mount
+[Unit]
+Description=Tmpfs directory
+DefaultDependencies=no
+
+[Mount]
+What=tmpfs
+Where=/mnt/overlay
+Type=tmpfs
+Options=mode=1777,strictatime,nosuid,nodev
+
+[Install]
+WantedBy=multi-user.target
+EOT
+}
+
+"""
+
+        self.write_config(config)
+        self.add_overlay_conf_to_machine()
+        self.write_recipeinc('systemd-machine-units', systemd_machine_unit_append)
+
+        bitbake('core-image-minimal')
+
+        def getline_qemu(out, line):
+            for l in out.split('\n'):
+                if line in l:
+                    return l
+
+        with runqemu('core-image-minimal') as qemu:
+            # Check that we have /mnt/overlay fs mounted as tmpfs and
+            # /usr/share/my-application as an overlay (see overlayfs-user recipe)
+            status, output = qemu.run_serial("/bin/mount -t tmpfs,overlay")
+
+            line = getline_qemu(output, "on /mnt/overlay")
+            self.assertTrue(line and line.startswith("tmpfs"), msg=output)
+
+            line = getline_qemu(output, "upperdir=/mnt/overlay/upper/usr/share/my-application")
+            self.assertTrue(line and line.startswith("overlay"), msg=output)