Squashed 'import-layers/yocto-poky/' changes from dc8508f6099..67491b0c104

Yocto 2.2.2 (Morty)

Change-Id: Id9a452e28940d9f166957de243d9cb1d8818704e
git-subtree-dir: import-layers/yocto-poky
git-subtree-split: 67491b0c104101bb9f366d697edd23c895be4302
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/import-layers/yocto-poky/meta/lib/oe/copy_buildsystem.py b/import-layers/yocto-poky/meta/lib/oe/copy_buildsystem.py
index afaff68..29ac6d4 100644
--- a/import-layers/yocto-poky/meta/lib/oe/copy_buildsystem.py
+++ b/import-layers/yocto-poky/meta/lib/oe/copy_buildsystem.py
@@ -4,11 +4,15 @@
 import shutil
 
 def _smart_copy(src, dest):
+    import subprocess
     # smart_copy will choose the correct function depending on whether the
     # source is a file or a directory.
     mode = os.stat(src).st_mode
     if stat.S_ISDIR(mode):
-        shutil.copytree(src, dest, symlinks=True, ignore=shutil.ignore_patterns('.git'))
+        bb.utils.mkdirhier(dest)
+        cmd = "tar --exclude='.git' --xattrs --xattrs-include='*' -chf - -C %s -p . \
+        | tar --xattrs --xattrs-include='*' -xf - -C %s" % (src, dest)
+        subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
     else:
         shutil.copyfile(src, dest)
         shutil.copymode(src, dest)
diff --git a/import-layers/yocto-poky/meta/lib/oe/gpg_sign.py b/import-layers/yocto-poky/meta/lib/oe/gpg_sign.py
index 38eb0cb..ba61f98 100644
--- a/import-layers/yocto-poky/meta/lib/oe/gpg_sign.py
+++ b/import-layers/yocto-poky/meta/lib/oe/gpg_sign.py
@@ -10,6 +10,7 @@
         self.gpg_bin = d.getVar('GPG_BIN', True) or \
                   bb.utils.which(os.getenv('PATH'), 'gpg')
         self.gpg_path = d.getVar('GPG_PATH', True)
+        self.gpg_version = self.get_gpg_version()
         self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpm")
 
     def export_pubkey(self, output_file, keyid, armor=True):
@@ -31,15 +32,18 @@
 
         cmd = self.rpm_bin + " --addsign --define '_gpg_name %s'  " % keyid
         cmd += "--define '_gpg_passphrase %s' " % passphrase
+        if self.gpg_version > (2,1,):
+            cmd += "--define '_gpg_sign_cmd_extra_args --pinentry-mode=loopback' "
         if self.gpg_bin:
             cmd += "--define '%%__gpg %s' " % self.gpg_bin
         if self.gpg_path:
             cmd += "--define '_gpg_path %s' " % self.gpg_path
-        cmd += ' '.join(files)
 
-        status, output = oe.utils.getstatusoutput(cmd)
-        if status:
-            raise bb.build.FuncFailed("Failed to sign RPM packages: %s" % output)
+        # Sign in chunks of 100 packages
+        for i in range(0, len(files), 100):
+            status, output = oe.utils.getstatusoutput(cmd + ' '.join(files[i:i+100]))
+            if status:
+                raise bb.build.FuncFailed("Failed to sign RPM packages: %s" % output)
 
     def detach_sign(self, input_file, keyid, passphrase_file, passphrase=None, armor=True):
         """Create a detached signature of a file"""
@@ -58,9 +62,7 @@
 
         #gpg > 2.1 supports password pipes only through the loopback interface
         #gpg < 2.1 errors out if given unknown parameters
-        dots = self.get_gpg_version().split('.')
-        assert len(dots) >= 2
-        if int(dots[0]) >= 2 and int(dots[1]) >= 1:
+        if self.gpg_version > (2,1,):
             cmd += ['--pinentry-mode', 'loopback']
 
         cmd += [input_file]
@@ -87,10 +89,11 @@
 
 
     def get_gpg_version(self):
-        """Return the gpg version"""
+        """Return the gpg version as a tuple of ints"""
         import subprocess
         try:
-            return subprocess.check_output((self.gpg_bin, "--version")).split()[2].decode("utf-8")
+            ver_str = subprocess.check_output((self.gpg_bin, "--version")).split()[2].decode("utf-8")
+            return tuple([int(i) for i in ver_str.split('.')])
         except subprocess.CalledProcessError as e:
             raise bb.build.FuncFailed("Could not get gpg version: %s" % e)
 
diff --git a/import-layers/yocto-poky/meta/lib/oe/package_manager.py b/import-layers/yocto-poky/meta/lib/oe/package_manager.py
index 3cee973..13577b1 100644
--- a/import-layers/yocto-poky/meta/lib/oe/package_manager.py
+++ b/import-layers/yocto-poky/meta/lib/oe/package_manager.py
@@ -1673,13 +1673,15 @@
                                         self.d.getVar('FEED_DEPLOYDIR_BASE_URI', True),
                                         arch))
 
-                        if self.opkg_dir != '/var/lib/opkg':
+                        if self.d.getVar('OPKGLIBDIR', True) != '/var/lib':
                             # There is no command line option for this anymore, we need to add
                             # info_dir and status_file to config file, if OPKGLIBDIR doesn't have
                             # the default value of "/var/lib" as defined in opkg:
-                            # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_INFO_DIR      "/var/lib/opkg/info"
-                            # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_STATUS_FILE   "/var/lib/opkg/status"
+                            # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_LISTS_DIR     VARDIR "/lib/opkg/lists"
+                            # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_INFO_DIR      VARDIR "/lib/opkg/info"
+                            # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_STATUS_FILE   VARDIR "/lib/opkg/status"
                             cfg_file.write("option info_dir     %s\n" % os.path.join(self.d.getVar('OPKGLIBDIR', True), 'opkg', 'info'))
+                            cfg_file.write("option lists_dir    %s\n" % os.path.join(self.d.getVar('OPKGLIBDIR', True), 'opkg', 'lists'))
                             cfg_file.write("option status_file  %s\n" % os.path.join(self.d.getVar('OPKGLIBDIR', True), 'opkg', 'status'))
 
 
@@ -1698,13 +1700,15 @@
                     config_file.write("src oe-%s file:%s\n" %
                                       (arch, pkgs_dir))
 
-            if self.opkg_dir != '/var/lib/opkg':
+            if self.d.getVar('OPKGLIBDIR', True) != '/var/lib':
                 # There is no command line option for this anymore, we need to add
                 # info_dir and status_file to config file, if OPKGLIBDIR doesn't have
                 # the default value of "/var/lib" as defined in opkg:
-                # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_INFO_DIR      "/var/lib/opkg/info"
-                # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_STATUS_FILE   "/var/lib/opkg/status"
+                # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_LISTS_DIR     VARDIR "/lib/opkg/lists"
+                # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_INFO_DIR      VARDIR "/lib/opkg/info"
+                # libopkg/opkg_conf.h:#define OPKG_CONF_DEFAULT_STATUS_FILE   VARDIR "/lib/opkg/status"
                 config_file.write("option info_dir     %s\n" % os.path.join(self.d.getVar('OPKGLIBDIR', True), 'opkg', 'info'))
+                config_file.write("option lists_dir    %s\n" % os.path.join(self.d.getVar('OPKGLIBDIR', True), 'opkg', 'lists'))
                 config_file.write("option status_file  %s\n" % os.path.join(self.d.getVar('OPKGLIBDIR', True), 'opkg', 'status'))
 
     def insert_feeds_uris(self):
@@ -1776,7 +1780,7 @@
 
     def remove(self, pkgs, with_dependencies=True):
         if with_dependencies:
-            cmd = "%s %s --force-depends --force-remove --force-removal-of-dependent-packages remove %s" % \
+            cmd = "%s %s --force-remove --force-removal-of-dependent-packages remove %s" % \
                 (self.opkg_cmd, self.opkg_args, ' '.join(pkgs))
         else:
             cmd = "%s %s --force-depends remove %s" % \
@@ -1860,7 +1864,10 @@
 
         # Create an temp dir as opkg root for dummy installation
         temp_rootfs = self.d.expand('${T}/opkg')
-        temp_opkg_dir = os.path.join(temp_rootfs, 'var/lib/opkg')
+        opkg_lib_dir = self.d.getVar('OPKGLIBDIR', True)
+        if opkg_lib_dir[0] == "/":
+            opkg_lib_dir = opkg_lib_dir[1:]
+        temp_opkg_dir = os.path.join(temp_rootfs, opkg_lib_dir, 'opkg')
         bb.utils.mkdirhier(temp_opkg_dir)
 
         opkg_args = "-f %s -o %s " % (self.config_file, temp_rootfs)
diff --git a/import-layers/yocto-poky/meta/lib/oe/path.py b/import-layers/yocto-poky/meta/lib/oe/path.py
index 06a5af2..ed7fd1e 100644
--- a/import-layers/yocto-poky/meta/lib/oe/path.py
+++ b/import-layers/yocto-poky/meta/lib/oe/path.py
@@ -83,12 +83,14 @@
         if os.path.isdir(src):
             import glob
             if len(glob.glob('%s/.??*' % src)) > 0:
-                source = '%s/.??* ' % src
-            source = source + '%s/*' % src
+                source = './.??* '
+            source += './*'
+            s_dir = src
         else:
             source = src
-        cmd = 'cp -afl --preserve=xattr %s %s' % (source, dst)
-        subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
+            s_dir = os.getcwd()
+        cmd = 'cp -afl --preserve=xattr %s %s' % (source, os.path.realpath(dst))
+        subprocess.check_output(cmd, shell=True, cwd=s_dir, stderr=subprocess.STDOUT)
     else:
         copytree(src, dst)
 
diff --git a/import-layers/yocto-poky/meta/lib/oe/qa.py b/import-layers/yocto-poky/meta/lib/oe/qa.py
index fbe719d..22d76dc 100644
--- a/import-layers/yocto-poky/meta/lib/oe/qa.py
+++ b/import-layers/yocto-poky/meta/lib/oe/qa.py
@@ -1,4 +1,4 @@
-import os, struct
+import os, struct, mmap
 
 class NotELFFileError(Exception):
     pass
@@ -23,9 +23,9 @@
     EV_CURRENT   = 1
 
     # possible values for EI_DATA
-    ELFDATANONE  = 0
-    ELFDATA2LSB  = 1
-    ELFDATA2MSB  = 2
+    EI_DATA_NONE  = 0
+    EI_DATA_LSB  = 1
+    EI_DATA_MSB  = 2
 
     PT_INTERP = 3
 
@@ -34,51 +34,46 @@
             #print "'%x','%x' %s" % (ord(expectation), ord(result), self.name)
             raise NotELFFileError("%s is not an ELF" % self.name)
 
-    def __init__(self, name, bits = 0):
+    def __init__(self, name):
         self.name = name
-        self.bits = bits
         self.objdump_output = {}
 
+    # Context Manager functions to close the mmap explicitly
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.data.close()
+
     def open(self):
-        if not os.path.isfile(self.name):
-            raise NotELFFileError("%s is not a normal file" % self.name)
-
         with open(self.name, "rb") as f:
-            # Read 4k which should cover most of the headers we're after
-            self.data = f.read(4096)
+            try:
+                self.data = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
+            except ValueError:
+                # This means the file is empty
+                raise NotELFFileError("%s is empty" % self.name)
 
+        # Check the file has the minimum number of ELF table entries
         if len(self.data) < ELFFile.EI_NIDENT + 4:
             raise NotELFFileError("%s is not an ELF" % self.name)
 
+        # ELF header
         self.my_assert(self.data[0], 0x7f)
         self.my_assert(self.data[1], ord('E'))
         self.my_assert(self.data[2], ord('L'))
         self.my_assert(self.data[3], ord('F'))
-        if self.bits == 0:
-            if self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS32:
-                self.bits = 32
-            elif self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS64:
-                self.bits = 64
-            else:
-                # Not 32-bit or 64.. lets assert
-                raise NotELFFileError("ELF but not 32 or 64 bit.")
-        elif self.bits == 32:
-            self.my_assert(self.data[ELFFile.EI_CLASS], ELFFile.ELFCLASS32)
-        elif self.bits == 64:
-            self.my_assert(self.data[ELFFile.EI_CLASS], ELFFile.ELFCLASS64)
+        if self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS32:
+            self.bits = 32
+        elif self.data[ELFFile.EI_CLASS] == ELFFile.ELFCLASS64:
+            self.bits = 64
         else:
-            raise NotELFFileError("Must specify unknown, 32 or 64 bit size.")
+            # Not 32-bit or 64.. lets assert
+            raise NotELFFileError("ELF but not 32 or 64 bit.")
         self.my_assert(self.data[ELFFile.EI_VERSION], ELFFile.EV_CURRENT)
 
-        self.sex = self.data[ELFFile.EI_DATA]
-        if self.sex == ELFFile.ELFDATANONE:
-            raise NotELFFileError("self.sex == ELFDATANONE")
-        elif self.sex == ELFFile.ELFDATA2LSB:
-            self.sex = "<"
-        elif self.sex == ELFFile.ELFDATA2MSB:
-            self.sex = ">"
-        else:
-            raise NotELFFileError("Unknown self.sex")
+        self.endian = self.data[ELFFile.EI_DATA]
+        if self.endian not in (ELFFile.EI_DATA_LSB, ELFFile.EI_DATA_MSB):
+            raise NotELFFileError("Unexpected EI_DATA %x" % self.endian)
 
     def osAbi(self):
         return self.data[ELFFile.EI_OSABI]
@@ -90,16 +85,20 @@
         return self.bits
 
     def isLittleEndian(self):
-        return self.sex == "<"
+        return self.endian == ELFFile.EI_DATA_LSB
 
     def isBigEndian(self):
-        return self.sex == ">"
+        return self.endian == ELFFile.EI_DATA_MSB
+
+    def getStructEndian(self):
+        return {ELFFile.EI_DATA_LSB: "<",
+                ELFFile.EI_DATA_MSB: ">"}[self.endian]
 
     def getShort(self, offset):
-        return struct.unpack_from(self.sex+"H", self.data, offset)[0]
+        return struct.unpack_from(self.getStructEndian() + "H", self.data, offset)[0]
 
     def getWord(self, offset):
-        return struct.unpack_from(self.sex+"i", self.data, offset)[0]
+        return struct.unpack_from(self.getStructEndian() + "i", self.data, offset)[0]
 
     def isDynamic(self):
         """
@@ -118,7 +117,7 @@
 
     def machine(self):
         """
-        We know the sex stored in self.sex and we
+        We know the endian stored in self.endian and we
         know the position
         """
         return self.getShort(ELFFile.E_MACHINE)
@@ -166,6 +165,7 @@
 
 if __name__ == "__main__":
     import sys
-    elf = ELFFile(sys.argv[1])
-    elf.open()
-    print(elf.isDynamic())
+
+    with ELFFile(sys.argv[1]) as elf:
+        elf.open()
+        print(elf.isDynamic())
diff --git a/import-layers/yocto-poky/meta/lib/oe/rootfs.py b/import-layers/yocto-poky/meta/lib/oe/rootfs.py
index a348b97..f967883 100644
--- a/import-layers/yocto-poky/meta/lib/oe/rootfs.py
+++ b/import-layers/yocto-poky/meta/lib/oe/rootfs.py
@@ -186,10 +186,6 @@
 
         shutil.copytree(postinst_intercepts_dir, intercepts_dir)
 
-        shutil.copy(self.d.expand("${COREBASE}/meta/files/deploydir_readme.txt"),
-                    self.deploydir +
-                    "/README_-_DO_NOT_DELETE_FILES_IN_THIS_DIRECTORY.txt")
-
         execute_pre_post_process(self.d, pre_process_cmds)
 
         if self.progress_reporter:
@@ -477,8 +473,6 @@
 
         execute_pre_post_process(self.d, rpm_post_process_cmds)
 
-        self._log_check()
-
         if self.inc_rpm_image_gen == "1":
             self.pm.backup_packaging_data()
 
@@ -951,7 +945,9 @@
         if self.progress_reporter:
             self.progress_reporter.next_stage()
 
-        self._setup_dbg_rootfs(['/etc', '/var/lib/opkg', '/usr/lib/ssl'])
+        opkg_lib_dir = self.d.getVar('OPKGLIBDIR', True)
+        opkg_dir = os.path.join(opkg_lib_dir, 'opkg')
+        self._setup_dbg_rootfs(['/etc', opkg_dir, '/usr/lib/ssl'])
 
         execute_pre_post_process(self.d, opkg_post_process_cmds)
 
diff --git a/import-layers/yocto-poky/meta/lib/oe/terminal.py b/import-layers/yocto-poky/meta/lib/oe/terminal.py
index 3901ad3..3c8ef59 100644
--- a/import-layers/yocto-poky/meta/lib/oe/terminal.py
+++ b/import-layers/yocto-poky/meta/lib/oe/terminal.py
@@ -227,6 +227,8 @@
 
     pipe = terminal(sh_cmd, title, env, d)
     output = pipe.communicate()[0]
+    if output:
+        output = output.decode("utf-8")
     if pipe.returncode != 0:
         raise ExecutionError(sh_cmd, pipe.returncode, output)
 
diff --git a/import-layers/yocto-poky/meta/lib/oe/utils.py b/import-layers/yocto-poky/meta/lib/oe/utils.py
index d6545b1..36cf74f 100644
--- a/import-layers/yocto-poky/meta/lib/oe/utils.py
+++ b/import-layers/yocto-poky/meta/lib/oe/utils.py
@@ -230,6 +230,25 @@
 
     return '\n'.join(output)
 
+def host_gcc_version(d):
+    import re, subprocess
+
+    compiler = d.getVar("BUILD_CC", True)
+
+    try:
+        env = os.environ.copy()
+        env["PATH"] = d.getVar("PATH", True)
+        output = subprocess.check_output("%s --version" % compiler, shell=True, env=env).decode("utf-8")
+    except subprocess.CalledProcessError as e:
+        bb.fatal("Error running %s --version: %s" % (compiler, e.output.decode("utf-8")))
+
+    match = re.match(".* (\d\.\d)\.\d.*", output.split('\n')[0])
+    if not match:
+        bb.fatal("Can't get compiler version from %s --version output" % compiler)
+
+    version = match.group(1)
+    return "-%s" % version if version in ("4.8", "4.9") else ""
+
 #
 # Python 2.7 doesn't have threaded pools (just multiprocessing)
 # so implement a version here
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/controllers/testtargetloader.py b/import-layers/yocto-poky/meta/lib/oeqa/controllers/testtargetloader.py
index a1b7b1d..b51d04b 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/controllers/testtargetloader.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/controllers/testtargetloader.py
@@ -61,8 +61,6 @@
             obj = getattr(module, target)
             if obj: 
                 from oeqa.targetcontrol import BaseTarget
-                if (not isinstance(obj, (type, types.ClassType))):
-                    bb.warn("Target {0} found, but not of type Class".format(target))
                 if( not issubclass(obj, BaseTarget)):
                     bb.warn("Target {0} found, but subclass is not BaseTarget".format(target))
         except:
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/runtime/parselogs.py b/import-layers/yocto-poky/meta/lib/oeqa/runtime/parselogs.py
index 8efe2d1..aa5008b 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/runtime/parselogs.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/runtime/parselogs.py
@@ -43,6 +43,7 @@
     "controller can't do DEVSLP, turning off",
     "stmmac_dvr_probe: warning: cannot get CSR clock",
     "error: couldn\'t mount because of unsupported optional features",
+    "GPT: Use GNU Parted to correct GPT errors",
     ]
 
 video_related = [
@@ -58,6 +59,7 @@
     'failed to setup card detect gpio',
     'amd_nb: Cannot enumerate AMD northbridges',
     'failed to retrieve link info, disabling eDP',
+    'Direct firmware load for iwlwifi',
 ] + common_errors
 
 qemux86_common = [
@@ -69,7 +71,7 @@
     'tsc: HPET/PMTIMER calibration failed',
 ] + common_errors
 
-ignore_errors = { 
+ignore_errors = {
     'default' : common_errors,
     'qemux86' : [
         'Failed to access perfctr msr (MSR',
@@ -140,6 +142,7 @@
         'Failed to load firmware i915',
         'Failed to fetch GuC',
         'Failed to initialize GuC',
+        'Failed to load DMC firmware',
         'The driver is built-in, so to load the firmware you need to',
         ] + x86_common,
     'edgerouter' : [
@@ -200,7 +203,7 @@
         hwi += "*******************************\n"
         return hwi
 
-    #go through the log locations provided and if it's a folder create a list with all the .log files in it, if it's a file just add 
+    #go through the log locations provided and if it's a folder create a list with all the .log files in it, if it's a file just add
     #it to that list
     def getLogList(self, log_locations):
         logs = []
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py
index baae1e0..4ce935f 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/bbtests.py
@@ -37,7 +37,6 @@
 
     @testcase(103)
     def test_local_sstate(self):
-        bitbake('m4-native -ccleansstate')
         bitbake('m4-native')
         bitbake('m4-native -cclean')
         result = bitbake('m4-native')
@@ -83,8 +82,8 @@
         pkgsplit_dir = get_bb_var('PKGDEST', test_recipe)
         man_dir = get_bb_var('mandir', test_recipe)
 
-        bitbake('-c cleansstate %s' % test_recipe)
-        bitbake(test_recipe)
+        bitbake('-c clean %s' % test_recipe)
+        bitbake('-c package -f %s' % test_recipe)
         self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe)
 
         man_file = os.path.join(image_dir + man_dir, 'man3/zlib.3')
@@ -103,7 +102,6 @@
         # test 2 from bug 5875
         test_recipe = 'zlib'
 
-        bitbake('-c cleansstate %s' % test_recipe)
         bitbake(test_recipe)
         self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe)
 
@@ -221,7 +219,7 @@
         self.track_for_cleanup(os.path.join(self.builddir, "download-selftest"))
         self.write_recipeinc('man',"\ndo_fail_task () {\nexit 1 \n}\n\naddtask do_fail_task before do_fetch\n" )
         runCmd('bitbake -c cleanall man xcursor-transparent-theme')
-        result = runCmd('bitbake man xcursor-transparent-theme -k', ignore_status=True)
+        result = runCmd('bitbake -c unpack -k man xcursor-transparent-theme', ignore_status=True)
         errorpos = result.output.find('ERROR: Function failed: do_fail_task')
         manver = re.search("NOTE: recipe xcursor-transparent-theme-(.*?): task do_unpack: Started", result.output)
         continuepos = result.output.find('NOTE: recipe xcursor-transparent-theme-%s: task do_unpack: Started' % manver.group(1))
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py
index 9487898..4754955 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/buildoptions.py
@@ -35,9 +35,8 @@
         bitbake("ccache-native")
         self.assertTrue(os.path.isfile(os.path.join(get_bb_var('STAGING_BINDIR_NATIVE', 'ccache-native'), "ccache")), msg = "No ccache found under %s" % str(get_bb_var('STAGING_BINDIR_NATIVE', 'ccache-native')))
         self.write_config('INHERIT += "ccache"')
-        bitbake("m4 -c cleansstate")
-        bitbake("m4 -c compile")
-        self.addCleanup(bitbake, 'ccache-native -ccleansstate')
+        self.add_command_to_tearDown('bitbake -c clean m4')
+        bitbake("m4 -f -c compile")
         res = runCmd("grep ccache %s" % (os.path.join(get_bb_var("WORKDIR","m4"),"temp/log.do_compile")), ignore_status=True)
         self.assertEqual(0, res.status, msg="No match for ccache in m4 log.do_compile. For further details: %s" % os.path.join(get_bb_var("WORKDIR","m4"),"temp/log.do_compile"))
 
@@ -71,14 +70,14 @@
 
     @testcase(927)
     def test_options_warnqa_errorqa_switch(self):
-        bitbake("xcursor-transparent-theme -ccleansstate")
 
         self.write_config("INHERIT_remove = \"report-error\"")
         if "packages-list" not in get_bb_var("ERROR_QA"):
             self.append_config("ERROR_QA_append = \" packages-list\"")
 
         self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"')
-        res = bitbake("xcursor-transparent-theme", ignore_status=True)
+        self.add_command_to_tearDown('bitbake -c clean xcursor-transparent-theme')
+        res = bitbake("xcursor-transparent-theme -f -c package", ignore_status=True)
         self.delete_recipeinc('xcursor-transparent-theme')
         line = self.getline(res, "QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors.")
         self.assertTrue(line and line.startswith("ERROR:"), msg=res.output)
@@ -86,8 +85,7 @@
         self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"')
         self.append_config('ERROR_QA_remove = "packages-list"')
         self.append_config('WARN_QA_append = " packages-list"')
-        bitbake("xcursor-transparent-theme -ccleansstate")
-        res = bitbake("xcursor-transparent-theme")
+        res = bitbake("xcursor-transparent-theme -f -c package")
         self.delete_recipeinc('xcursor-transparent-theme')
         line = self.getline(res, "QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors.")
         self.assertTrue(line and line.startswith("WARNING:"), msg=res.output)
@@ -96,8 +94,8 @@
     def test_sanity_unsafe_script_references(self):
         self.write_config('WARN_QA_append = " unsafe-references-in-scripts"')
 
-        bitbake("-ccleansstate gzip")
-        res = bitbake("gzip")
+        self.add_command_to_tearDown('bitbake -c clean gzip')
+        res = bitbake("gzip -f -c package_qa")
         line = self.getline(res, "QA Issue: gzip")
         self.assertFalse(line, "WARNING: QA Issue: gzip message is present in bitbake's output and shouldn't be: %s" % res.output)
 
@@ -106,29 +104,10 @@
 	echo "\n${bindir}/test" >> ${D}${bindir}/zcat
 }
 """)
-        res = bitbake("gzip")
+        res = bitbake("gzip -f -c package_qa")
         line = self.getline(res, "QA Issue: gzip")
         self.assertTrue(line and line.startswith("WARNING:"), "WARNING: QA Issue: gzip message is not present in bitbake's output: %s" % res.output)
 
-    @testcase(1434)
-    def test_sanity_unsafe_binary_references(self):
-        self.write_config('WARN_QA_append = " unsafe-references-in-binaries"')
-
-        bitbake("-ccleansstate nfs-utils")
-        #res = bitbake("nfs-utils")
-        # FIXME when nfs-utils passes this test
-        #line = self.getline(res, "QA Issue: nfs-utils")
-        #self.assertFalse(line, "WARNING: QA Issue: nfs-utils message is present in bitbake's output and shouldn't be: %s" % res.output)
-
-#        self.append_config("""
-#do_install_append_pn-nfs-utils () {
-#	echo "\n${bindir}/test" >> ${D}${base_sbindir}/osd_login
-#}
-#""")
-        res = bitbake("nfs-utils")
-        line = self.getline(res, "QA Issue: nfs-utils")
-        self.assertTrue(line and line.startswith("WARNING:"), "WARNING: QA Issue: nfs-utils message is not present in bitbake's output: %s" % res.output)
-
     @testcase(1421)
     def test_layer_without_git_dir(self):
         """
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py
index e992dcf..302ec5d 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/devtool.py
@@ -9,7 +9,8 @@
 
 import oeqa.utils.ftools as ftools
 from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer, runqemu, get_test_layer
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
+from oeqa.utils.commands import get_bb_vars, runqemu, get_test_layer
 from oeqa.utils.decorators import testcase
 
 class DevtoolBase(oeSelfTest):
@@ -114,6 +115,20 @@
 
 class DevtoolTests(DevtoolBase):
 
+    @classmethod
+    def setUpClass(cls):
+        bb_vars = get_bb_vars(['TOPDIR', 'SSTATE_DIR'])
+        cls.original_sstate = bb_vars['SSTATE_DIR']
+        cls.devtool_sstate = os.path.join(bb_vars['TOPDIR'], 'sstate_devtool')
+        cls.sstate_conf  = 'SSTATE_DIR = "%s"\n' % cls.devtool_sstate
+        cls.sstate_conf += ('SSTATE_MIRRORS += "file://.* file:///%s/PATH"\n'
+                            % cls.original_sstate)
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.log.debug('Deleting devtool sstate cache on %s' % cls.devtool_sstate)
+        runCmd('rm -rf %s' % cls.devtool_sstate)
+
     def setUp(self):
         """Test case setup function"""
         super(DevtoolTests, self).setUp()
@@ -121,6 +136,7 @@
         self.assertTrue(not os.path.exists(self.workspacedir),
                         'This test cannot be run with a workspace directory '
                         'under the build directory')
+        self.append_config(self.sstate_conf)
 
     def _check_src_repo(self, repo_dir):
         """Check srctree git repository"""
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py
index 31cd508..28345dc 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/oescripts.py
@@ -17,12 +17,8 @@
         path = os.path.dirname(get_bb_var('WORKDIR', 'gzip'))
         old_version_recipe = os.path.join(get_bb_var('COREBASE'), 'meta/recipes-extended/gzip/gzip_1.3.12.bb')
         old_version = '1.3.12'
-        bitbake("-ccleansstate gzip")
-        bitbake("-ccleansstate -b %s" % old_version_recipe)
-        if os.path.exists(get_bb_var('WORKDIR', "-b %s" % old_version_recipe)):
-            shutil.rmtree(get_bb_var('WORKDIR', "-b %s" % old_version_recipe))
-        if os.path.exists(get_bb_var('WORKDIR', 'gzip')):
-            shutil.rmtree(get_bb_var('WORKDIR', 'gzip'))
+        bitbake("-c clean gzip")
+        bitbake("-c clean -b %s" % old_version_recipe)
 
         if os.path.exists(path):
             initial_contents = os.listdir(path)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py
index 1b9a510..0b2dfe6 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/prservice.py
@@ -37,7 +37,6 @@
     def increment_package_pr(self, package_name):
         inc_data = "do_package_append() {\n    bb.build.exec_func('do_test_prserv', d)\n}\ndo_test_prserv() {\necho \"The current date is: %s\"\n}" % datetime.datetime.now()
         self.write_recipeinc(package_name, inc_data)
-        bitbake("-ccleansstate %s" % package_name)
         res = bitbake(package_name, ignore_status=True)
         self.delete_recipeinc(package_name)
         self.assertEqual(res.status, 0, msg=res.output)
@@ -60,7 +59,6 @@
         pr_2 = self.get_pr_version(package_name)
         stamp_2 = self.get_task_stamp(package_name, track_task)
 
-        bitbake("-ccleansstate %s" % package_name)
         self.assertTrue(pr_2 - pr_1 == 1, "Step between same pkg. revision is greater than 1")
         self.assertTrue(stamp_1 != stamp_2, "Different pkg rev. but same stamp: %s" % stamp_1)
 
@@ -86,7 +84,6 @@
         self.increment_package_pr(package_name)
         pr_2 = self.get_pr_version(package_name)
 
-        bitbake("-ccleansstate %s" % package_name)
         self.assertTrue(pr_2 - pr_1 == 1, "Step between same pkg. revision is greater than 1")
 
     @testcase(930)
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py
index db1f8de..9b66924 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/recipetool.py
@@ -71,11 +71,6 @@
         logger.info('Running bitbake to generate pkgdata')
         bitbake('-c packagedata base-files coreutils busybox selftest-recipetool-appendfile')
 
-    @classmethod
-    def tearDownClass(cls):
-        # Shouldn't leave any traces of this artificial recipe behind
-        bitbake('-c cleansstate selftest-recipetool-appendfile')
-
     def _try_recipetool_appendfile(self, testrecipe, destfile, newfile, options, expectedlines, expectedfiles):
         cmd = 'recipetool appendfile %s %s %s %s' % (self.templayerdir, destfile, newfile, options)
         return self._try_recipetool_appendcmd(cmd, testrecipe, expectedfiles, expectedlines)
@@ -369,15 +364,15 @@
         tempsrc = os.path.join(self.tempdir, 'srctree')
         os.makedirs(tempsrc)
         recipefile = os.path.join(self.tempdir, 'logrotate_3.8.7.bb')
-        srcuri = 'https://fedorahosted.org/releases/l/o/logrotate/logrotate-3.8.7.tar.gz'
+        srcuri = 'https://github.com/logrotate/logrotate/archive/r3-8-7.tar.gz'
         result = runCmd('recipetool create -o %s %s -x %s' % (recipefile, srcuri, tempsrc))
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
         checkvars['LICENSE'] = 'GPLv2'
         checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=18810669f13b87348459e611d31ab760'
-        checkvars['SRC_URI'] = 'https://fedorahosted.org/releases/l/o/logrotate/logrotate-${PV}.tar.gz'
-        checkvars['SRC_URI[md5sum]'] = '99e08503ef24c3e2e3ff74cc5f3be213'
-        checkvars['SRC_URI[sha256sum]'] = 'f6ba691f40e30e640efa2752c1f9499a3f9738257660994de70a45fe00d12b64'
+        checkvars['SRC_URI'] = 'https://github.com/logrotate/logrotate/archive/r3-8-7.tar.gz'
+        checkvars['SRC_URI[md5sum]'] = '6b1aa0e0d07eda3c9a2526520850397a'
+        checkvars['SRC_URI[sha256sum]'] = 'dece4bfeb9d8374a0ecafa34be139b5a697db5c926dcc69a9b8715431a22e733'
         self._test_recipe_contents(recipefile, checkvars, [])
 
     @testcase(1194)
@@ -447,8 +442,8 @@
         temprecipe = os.path.join(self.tempdir, 'recipe')
         os.makedirs(temprecipe)
         recipefile = os.path.join(temprecipe, 'meson_git.bb')
-        srcuri = 'https://github.com/mesonbuild/meson'
-        result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
+        srcuri = 'https://github.com/mesonbuild/meson;rev=0.32.0'
+        result = runCmd(['recipetool', 'create', '-o', temprecipe, srcuri])
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
         checkvars['LICENSE'] = set(['Apache-2.0'])
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py
index 4c12d6d..606bfd3 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/signing.py
@@ -54,8 +54,9 @@
 
         self.write_config(feature)
 
-        bitbake('-c cleansstate %s' % test_recipe)
-        bitbake(test_recipe)
+        bitbake('-c clean %s' % test_recipe)
+        bitbake('-f -c package_write_rpm %s' % test_recipe)
+
         self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe)
 
         pkgdatadir = get_bb_var('PKGDATA_DIR', test_recipe)
@@ -98,7 +99,6 @@
         sstatedir = os.path.join(builddir, 'test-sstate')
 
         self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe)
-        self.add_command_to_tearDown('bitbake -c cleansstate %s' % test_recipe)
         self.add_command_to_tearDown('rm -rf %s' % sstatedir)
 
         # Determine the pub key signature
@@ -112,10 +112,12 @@
         feature += 'SSTATE_VERIFY_SIG ?= "1"\n'
         feature += 'GPG_PATH = "%s"\n' % self.gpg_dir
         feature += 'SSTATE_DIR = "%s"\n' % sstatedir
+        # Any mirror might have partial sstate without .sig files, triggering failures
+        feature += 'SSTATE_MIRRORS_forcevariable = ""\n'
 
         self.write_config(feature)
 
-        bitbake('-c cleansstate %s' % test_recipe)
+        bitbake('-c clean %s' % test_recipe)
         bitbake(test_recipe)
 
         recipe_sig = glob.glob(sstatedir + '/*/*:ed:*_package.tgz.sig')
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py
index 6642539..f99d746 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/sstatetests.py
@@ -16,7 +16,7 @@
 
     # Test sstate files creation and their location
     def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True):
-        self.config_sstate(temp_sstate_location)
+        self.config_sstate(temp_sstate_location, [self.sstate_path])
 
         if  self.temp_sstate_location:
             bitbake(['-cclean'] + targets)
@@ -60,7 +60,7 @@
 
     # Test the sstate files deletion part of the do_cleansstate task
     def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
-        self.config_sstate(temp_sstate_location)
+        self.config_sstate(temp_sstate_location, [self.sstate_path])
 
         bitbake(['-ccleansstate'] + targets)
 
@@ -92,7 +92,7 @@
 
     # Test rebuilding of distro-specific sstate files
     def run_test_rebuild_distro_specific_sstate(self, targets, temp_sstate_location=True):
-        self.config_sstate(temp_sstate_location)
+        self.config_sstate(temp_sstate_location, [self.sstate_path])
 
         bitbake(['-ccleansstate'] + targets)
 
diff --git a/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py b/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py
index faac11e..e652fad 100644
--- a/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py
+++ b/import-layers/yocto-poky/meta/lib/oeqa/selftest/wic.py
@@ -42,7 +42,8 @@
     def setUpLocal(self):
         """This code is executed before each test method."""
         self.write_config('IMAGE_FSTYPES += " hddimg"\n'
-                          'MACHINE_FEATURES_append = " efi"\n')
+                          'MACHINE_FEATURES_append = " efi"\n'
+                          'WKS_FILE = "wic-image-minimal"\n')
 
         # Do this here instead of in setUpClass as the base setUp does some
         # clean up which can result in the native tools built earlier in