diff --git a/meta/classes/sanity.bbclass b/meta/classes/sanity.bbclass
new file mode 100644
index 0000000..2eb744f
--- /dev/null
+++ b/meta/classes/sanity.bbclass
@@ -0,0 +1,945 @@
+#
+# Sanity check the users setup for common misconfigurations
+#
+
+SANITY_REQUIRED_UTILITIES ?= "patch diffstat makeinfo git bzip2 tar \
+    gzip gawk chrpath wget cpio perl"
+
+def bblayers_conf_file(d):
+    return os.path.join(d.getVar('TOPDIR', True), 'conf/bblayers.conf')
+
+def sanity_conf_read(fn):
+    with open(fn, 'r') as f:
+        lines = f.readlines()
+    return lines
+
+def sanity_conf_find_line(pattern, lines):
+    import re
+    return next(((index, line)
+        for index, line in enumerate(lines)
+        if re.search(pattern, line)), (None, None))
+
+def sanity_conf_update(fn, lines, version_var_name, new_version):
+    index, line = sanity_conf_find_line(version_var_name, lines)
+    lines[index] = '%s = "%d"\n' % (version_var_name, new_version)
+    with open(fn, "w") as f:
+        f.write(''.join(lines))
+
+# Functions added to this variable MUST throw an exception (or sys.exit()) unless they
+# successfully changed LCONF_VERSION in bblayers.conf
+BBLAYERS_CONF_UPDATE_FUNCS += "oecore_update_bblayers"
+
+python oecore_update_bblayers() {
+    # bblayers.conf is out of date, so see if we can resolve that
+
+    current_lconf = int(d.getVar('LCONF_VERSION', True))
+    if not current_lconf:
+        sys.exit()
+    lconf_version = int(d.getVar('LAYER_CONF_VERSION', True))
+    lines = []
+
+    if current_lconf < 4:
+        sys.exit()
+
+    bblayers_fn = bblayers_conf_file(d)
+    lines = sanity_conf_read(bblayers_fn)
+
+    if current_lconf == 4 and lconf_version > 4:
+        topdir_var = '$' + '{TOPDIR}'
+        index, bbpath_line = sanity_conf_find_line('BBPATH', lines)
+        if bbpath_line:
+            start = bbpath_line.find('"')
+            if start != -1 and (len(bbpath_line) != (start + 1)):
+                if bbpath_line[start + 1] == '"':
+                    lines[index] = (bbpath_line[:start + 1] +
+                                    topdir_var + bbpath_line[start + 1:])
+                else:
+                    if not topdir_var in bbpath_line:
+                        lines[index] = (bbpath_line[:start + 1] +
+                                    topdir_var + ':' + bbpath_line[start + 1:])
+            else:
+                sys.exit()
+        else:
+            index, bbfiles_line = sanity_conf_find_line('BBFILES', lines)
+            if bbfiles_line:
+                lines.insert(index, 'BBPATH = "' + topdir_var + '"\n')
+            else:
+                sys.exit()
+
+        current_lconf += 1
+        sanity_conf_update(bblayers_fn, lines, 'LCONF_VERSION', current_lconf)
+        return
+
+    elif current_lconf == 5 and lconf_version > 5:
+        # Null update, to avoid issues with people switching between poky and other distros
+        current_lconf = 6
+        sanity_conf_update(bblayers_fn, lines, 'LCONF_VERSION', current_lconf)
+        return
+
+    sys.exit()
+}
+
+def raise_sanity_error(msg, d, network_error=False):
+    if d.getVar("SANITY_USE_EVENTS", True) == "1":
+        try:
+            bb.event.fire(bb.event.SanityCheckFailed(msg, network_error), d)
+        except TypeError:
+            bb.event.fire(bb.event.SanityCheckFailed(msg), d)
+        return
+
+    bb.fatal(""" OE-core's config sanity checker detected a potential misconfiguration.
+    Either fix the cause of this error or at your own risk disable the checker (see sanity.conf).
+    Following is the list of potential problems / advisories:
+    
+    %s""" % msg)
+
+# Check flags associated with a tuning.
+def check_toolchain_tune_args(data, tune, multilib, errs):
+    found_errors = False
+    if check_toolchain_args_present(data, tune, multilib, errs, 'CCARGS'):
+        found_errors = True
+    if check_toolchain_args_present(data, tune, multilib, errs, 'ASARGS'):
+        found_errors = True
+    if check_toolchain_args_present(data, tune, multilib, errs, 'LDARGS'):
+        found_errors = True
+
+    return found_errors
+
+def check_toolchain_args_present(data, tune, multilib, tune_errors, which):
+    args_set = (data.getVar("TUNE_%s" % which, True) or "").split()
+    args_wanted = (data.getVar("TUNEABI_REQUIRED_%s_tune-%s" % (which, tune), True) or "").split()
+    args_missing = []
+
+    # If no args are listed/required, we are done.
+    if not args_wanted:
+        return
+    for arg in args_wanted:
+        if arg not in args_set:
+            args_missing.append(arg)
+
+    found_errors = False
+    if args_missing:
+        found_errors = True
+        tune_errors.append("TUNEABI for %s requires '%s' in TUNE_%s (%s)." %
+                       (tune, ' '.join(args_missing), which, ' '.join(args_set)))
+    return found_errors
+
+# Check a single tune for validity.
+def check_toolchain_tune(data, tune, multilib):
+    tune_errors = []
+    if not tune:
+        return "No tuning found for %s multilib." % multilib
+    localdata = bb.data.createCopy(data)
+    if multilib != "default":
+        # Apply the overrides so we can look at the details.
+        overrides = localdata.getVar("OVERRIDES", False) + ":virtclass-multilib-" + multilib
+        localdata.setVar("OVERRIDES", overrides)
+    bb.data.update_data(localdata)
+    bb.debug(2, "Sanity-checking tuning '%s' (%s) features:" % (tune, multilib))
+    features = (localdata.getVar("TUNE_FEATURES_tune-%s" % tune, True) or "").split()
+    if not features:
+        return "Tuning '%s' has no defined features, and cannot be used." % tune
+    valid_tunes = localdata.getVarFlags('TUNEVALID') or {}
+    conflicts = localdata.getVarFlags('TUNECONFLICTS') or {}
+    # [doc] is the documentation for the variable, not a real feature
+    if 'doc' in valid_tunes:
+        del valid_tunes['doc']
+    if 'doc' in conflicts:
+        del conflicts['doc']
+    for feature in features:
+        if feature in conflicts:
+            for conflict in conflicts[feature].split():
+                if conflict in features:
+                    tune_errors.append("Feature '%s' conflicts with '%s'." %
+                        (feature, conflict))
+        if feature in valid_tunes:
+            bb.debug(2, "  %s: %s" % (feature, valid_tunes[feature]))
+        else:
+            tune_errors.append("Feature '%s' is not defined." % feature)
+    whitelist = localdata.getVar("TUNEABI_WHITELIST", True)
+    if whitelist:
+        tuneabi = localdata.getVar("TUNEABI_tune-%s" % tune, True)
+        if not tuneabi:
+            tuneabi = tune
+        if True not in [x in whitelist.split() for x in tuneabi.split()]:
+            tune_errors.append("Tuning '%s' (%s) cannot be used with any supported tuning/ABI." %
+                (tune, tuneabi))
+        else:
+            if not check_toolchain_tune_args(localdata, tuneabi, multilib, tune_errors):
+                bb.debug(2, "Sanity check: Compiler args OK for %s." % tune)
+    if tune_errors:
+        return "Tuning '%s' has the following errors:\n" % tune + '\n'.join(tune_errors)
+
+def check_toolchain(data):
+    tune_error_set = []
+    deftune = data.getVar("DEFAULTTUNE", True)
+    tune_errors = check_toolchain_tune(data, deftune, 'default')
+    if tune_errors:
+        tune_error_set.append(tune_errors)
+
+    multilibs = (data.getVar("MULTILIB_VARIANTS", True) or "").split()
+    global_multilibs = (data.getVar("MULTILIB_GLOBAL_VARIANTS", True) or "").split()
+
+    if multilibs:
+        seen_libs = []
+        seen_tunes = []
+        for lib in multilibs:
+            if lib in seen_libs:
+                tune_error_set.append("The multilib '%s' appears more than once." % lib)
+            else:
+                seen_libs.append(lib)
+            if not lib in global_multilibs:
+                tune_error_set.append("Multilib %s is not present in MULTILIB_GLOBAL_VARIANTS" % lib)
+            tune = data.getVar("DEFAULTTUNE_virtclass-multilib-%s" % lib, True)
+            if tune in seen_tunes:
+                tune_error_set.append("The tuning '%s' appears in more than one multilib." % tune)
+            else:
+                seen_libs.append(tune)
+            if tune == deftune:
+                tune_error_set.append("Multilib '%s' (%s) is also the default tuning." % (lib, deftune))
+            else:
+                tune_errors = check_toolchain_tune(data, tune, lib)
+            if tune_errors:
+                tune_error_set.append(tune_errors)
+    if tune_error_set:
+        return "Toolchain tunings invalid:\n" + '\n'.join(tune_error_set) + "\n"
+
+    return ""
+
+def check_conf_exists(fn, data):
+    bbpath = []
+    fn = data.expand(fn)
+    vbbpath = data.getVar("BBPATH", False)
+    if vbbpath:
+        bbpath += vbbpath.split(":")
+    for p in bbpath:
+        currname = os.path.join(data.expand(p), fn)
+        if os.access(currname, os.R_OK):
+            return True
+    return False
+
+def check_create_long_filename(filepath, pathname):
+    import string, random
+    testfile = os.path.join(filepath, ''.join(random.choice(string.ascii_letters) for x in range(200)))
+    try:
+        if not os.path.exists(filepath):
+            bb.utils.mkdirhier(filepath)
+        f = open(testfile, "w")
+        f.close()
+        os.remove(testfile)
+    except IOError as e:
+        import errno
+        err, strerror = e.args
+        if err == errno.ENAMETOOLONG:
+            return "Failed to create a file with a long name in %s. Please use a filesystem that does not unreasonably limit filename length.\n" % pathname
+        else:
+            return "Failed to create a file in %s: %s.\n" % (pathname, strerror)
+    except OSError as e:
+        errno, strerror = e.args
+        return "Failed to create %s directory in which to run long name sanity check: %s.\n" % (pathname, strerror)
+    return ""
+
+def check_path_length(filepath, pathname, limit):
+    if len(filepath) > limit:
+        return "The length of %s is longer than 410, this would cause unexpected errors, please use a shorter path.\n" % pathname
+    return ""
+
+def get_filesystem_id(path):
+    status, result = oe.utils.getstatusoutput("stat -f -c '%s' %s" % ("%t", path))
+    if status == 0:
+        return result
+    else:
+        bb.warn("Can't get the filesystem id of: %s" % path)
+        return None
+
+# Check that the path isn't located on nfs.
+def check_not_nfs(path, name):
+    # The nfs' filesystem id is 6969
+    if get_filesystem_id(path) == "6969":
+        return "The %s: %s can't be located on nfs.\n" % (name, path)
+    return ""
+
+# Check that path isn't a broken symlink
+def check_symlink(lnk, data):
+    if os.path.islink(lnk) and not os.path.exists(lnk):
+        raise_sanity_error("%s is a broken symlink." % lnk, data)
+
+def check_connectivity(d):
+    # URI's to check can be set in the CONNECTIVITY_CHECK_URIS variable
+    # using the same syntax as for SRC_URI. If the variable is not set
+    # the check is skipped
+    test_uris = (d.getVar('CONNECTIVITY_CHECK_URIS', True) or "").split()
+    retval = ""
+
+    # Only check connectivity if network enabled and the
+    # CONNECTIVITY_CHECK_URIS are set
+    network_enabled = not d.getVar('BB_NO_NETWORK', True)
+    check_enabled = len(test_uris)
+    # Take a copy of the data store and unset MIRRORS and PREMIRRORS
+    data = bb.data.createCopy(d)
+    data.delVar('PREMIRRORS')
+    data.delVar('MIRRORS')
+    if check_enabled and network_enabled:
+        try:
+            fetcher = bb.fetch2.Fetch(test_uris, data)
+            fetcher.checkstatus()
+        except Exception as err:
+            # Allow the message to be configured so that users can be
+            # pointed to a support mechanism.
+            msg = data.getVar('CONNECTIVITY_CHECK_MSG', True) or ""
+            if len(msg) == 0:
+                msg = "%s. Please ensure your network is configured correctly.\n" % err
+            retval = msg
+
+    return retval
+
+def check_supported_distro(sanity_data):
+    from fnmatch import fnmatch
+
+    tested_distros = sanity_data.getVar('SANITY_TESTED_DISTROS', True)
+    if not tested_distros:
+        return
+
+    try:
+        distro = oe.lsb.distro_identifier()
+    except Exception:
+        distro = None
+
+    if not distro:
+        bb.warn('Host distribution could not be determined; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.')
+
+    for supported in [x.strip() for x in tested_distros.split('\\n')]:
+        if fnmatch(distro, supported):
+            return
+
+    bb.warn('Host distribution "%s" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.' % distro)
+
+# Checks we should only make if MACHINE is set correctly
+def check_sanity_validmachine(sanity_data):
+    messages = ""
+
+    # Check TUNE_ARCH is set
+    if sanity_data.getVar('TUNE_ARCH', True) == 'INVALID':
+        messages = messages + 'TUNE_ARCH is unset. Please ensure your MACHINE configuration includes a valid tune configuration file which will set this correctly.\n'
+
+    # Check TARGET_OS is set
+    if sanity_data.getVar('TARGET_OS', True) == 'INVALID':
+        messages = messages + 'Please set TARGET_OS directly, or choose a MACHINE or DISTRO that does so.\n'
+
+    # Check that we don't have duplicate entries in PACKAGE_ARCHS & that TUNE_PKGARCH is in PACKAGE_ARCHS
+    pkgarchs = sanity_data.getVar('PACKAGE_ARCHS', True)
+    tunepkg = sanity_data.getVar('TUNE_PKGARCH', True)
+    tunefound = False
+    seen = {}
+    dups = []
+
+    for pa in pkgarchs.split():
+        if seen.get(pa, 0) == 1:
+            dups.append(pa)
+        else:
+            seen[pa] = 1
+        if pa == tunepkg:
+            tunefound = True
+
+    if len(dups):
+        messages = messages + "Error, the PACKAGE_ARCHS variable contains duplicates. The following archs are listed more than once: %s" % " ".join(dups)
+
+    if tunefound == False:
+        messages = messages + "Error, the PACKAGE_ARCHS variable does not contain TUNE_PKGARCH (%s)." % tunepkg
+
+    return messages
+
+# Checks if necessary to add option march to host gcc
+def check_gcc_march(sanity_data):
+    result = True
+    message = ""
+
+    # Check if -march not in BUILD_CFLAGS
+    if sanity_data.getVar("BUILD_CFLAGS",True).find("-march") < 0:
+        result = False
+
+        # Construct a test file
+        f = open("gcc_test.c", "w")
+        f.write("int main (){ volatile int atomic = 2; __sync_bool_compare_and_swap (&atomic, 2, 3); return 0; }\n")
+        f.close()
+
+        # Check if GCC could work without march
+        if not result:
+            status,res = oe.utils.getstatusoutput("${BUILD_PREFIX}gcc gcc_test.c -o gcc_test")
+            if status == 0:
+                result = True;
+
+        if not result:
+            status,res = oe.utils.getstatusoutput("${BUILD_PREFIX}gcc -march=native gcc_test.c -o gcc_test")
+            if status == 0:
+                message = "BUILD_CFLAGS_append = \" -march=native\""
+                result = True;
+
+        if not result:
+            build_arch = sanity_data.getVar('BUILD_ARCH', True)
+            status,res = oe.utils.getstatusoutput("${BUILD_PREFIX}gcc -march=%s gcc_test.c -o gcc_test" % build_arch)
+            if status == 0:
+                message = "BUILD_CFLAGS_append = \" -march=%s\"" % build_arch
+                result = True;
+
+        os.remove("gcc_test.c")
+        if os.path.exists("gcc_test"):
+            os.remove("gcc_test")
+
+    return (result, message)
+
+# Unpatched versions of make 3.82 are known to be broken.  See GNU Savannah Bug 30612.
+# Use a modified reproducer from http://savannah.gnu.org/bugs/?30612 to validate.
+def check_make_version(sanity_data):
+    from distutils.version import LooseVersion
+    status, result = oe.utils.getstatusoutput("make --version")
+    if status != 0:
+        return "Unable to execute make --version, exit code %s\n" % status
+    version = result.split()[2]
+    if LooseVersion(version) == LooseVersion("3.82"):
+        # Construct a test file
+        f = open("makefile_test", "w")
+        f.write("makefile_test.a: makefile_test_a.c makefile_test_b.c makefile_test.a( makefile_test_a.c makefile_test_b.c)\n")
+        f.write("\n")
+        f.write("makefile_test_a.c:\n")
+        f.write("	touch $@\n")
+        f.write("\n")
+        f.write("makefile_test_b.c:\n")
+        f.write("	touch $@\n")
+        f.close()
+
+        # Check if make 3.82 has been patched
+        status,result = oe.utils.getstatusoutput("make -f makefile_test")
+
+        os.remove("makefile_test")
+        if os.path.exists("makefile_test_a.c"):
+            os.remove("makefile_test_a.c")
+        if os.path.exists("makefile_test_b.c"):
+            os.remove("makefile_test_b.c")
+        if os.path.exists("makefile_test.a"):
+            os.remove("makefile_test.a")
+
+        if status != 0:
+            return "Your version of make 3.82 is broken. Please revert to 3.81 or install a patched version.\n"
+    return None
+
+
+# Tar version 1.24 and onwards handle overwriting symlinks correctly
+# but earlier versions do not; this needs to work properly for sstate
+def check_tar_version(sanity_data):
+    from distutils.version import LooseVersion
+    status, result = oe.utils.getstatusoutput("tar --version")
+    if status != 0:
+        return "Unable to execute tar --version, exit code %s\n" % status
+    version = result.split()[3]
+    if LooseVersion(version) < LooseVersion("1.24"):
+        return "Your version of tar is older than 1.24 and has bugs which will break builds. Please install a newer version of tar.\n"
+    return None
+
+# We use git parameters and functionality only found in 1.7.8 or later
+def check_git_version(sanity_data):
+    from distutils.version import LooseVersion
+    status, result = oe.utils.getstatusoutput("git --version 2> /dev/null")
+    if status != 0:
+        return "Unable to execute git --version, exit code %s\n" % status
+    version = result.split()[2]
+    if LooseVersion(version) < LooseVersion("1.7.8"):
+        return "Your version of git is older than 1.7.8 and has bugs which will break builds. Please install a newer version of git.\n"
+    return None
+
+# Check the required perl modules which may not be installed by default
+def check_perl_modules(sanity_data):
+    ret = ""
+    modules = ( "Text::ParseWords", "Thread::Queue", "Data::Dumper" )
+    for m in modules:
+        status, result = oe.utils.getstatusoutput("perl -e 'use %s' 2> /dev/null" % m)
+        if status != 0:
+            ret += "%s " % m
+    if ret:
+        return "Required perl module(s) not found: %s\n" % ret
+    return None
+
+def sanity_check_conffiles(status, d):
+    # Check we are using a valid local.conf
+    current_conf  = d.getVar('CONF_VERSION', True)
+    conf_version =  d.getVar('LOCALCONF_VERSION', True)
+
+    if current_conf != conf_version:
+        status.addresult("Your version of local.conf was generated from an older/newer version of local.conf.sample and there have been updates made to this file. Please compare the two files and merge any changes before continuing.\nMatching the version numbers will remove this message.\n\"meld conf/local.conf ${COREBASE}/meta*/conf/local.conf.sample\" is a good way to visualise the changes.\n")
+
+    # Check bblayers.conf is valid
+    current_lconf = d.getVar('LCONF_VERSION', True)
+    lconf_version = d.getVar('LAYER_CONF_VERSION', True)
+    if current_lconf != lconf_version:
+        funcs = d.getVar('BBLAYERS_CONF_UPDATE_FUNCS', True).split()
+        for func in funcs:
+            success = True
+            try:
+                bb.build.exec_func(func, d)
+            except Exception:
+                success = False
+            if success:
+                bb.note("Your conf/bblayers.conf has been automatically updated.")
+                status.reparse = True
+        if not status.reparse:
+            status.addresult("Your version of bblayers.conf has the wrong LCONF_VERSION (has %s, expecting %s).\nPlease compare the your file against bblayers.conf.sample and merge any changes before continuing.\n\"meld conf/bblayers.conf ${COREBASE}/meta*/conf/bblayers.conf.sample\" is a good way to visualise the changes.\n" % (current_lconf, lconf_version))
+
+    # If we have a site.conf, check it's valid
+    if check_conf_exists("conf/site.conf", d):
+        current_sconf = d.getVar('SCONF_VERSION', True)
+        sconf_version = d.getVar('SITE_CONF_VERSION', True)
+        if current_sconf != sconf_version:
+            status.addresult("Your version of site.conf was generated from an older version of site.conf.sample and there have been updates made to this file. Please compare the two files and merge any changes before continuing.\nMatching the version numbers will remove this message.\n\"meld conf/site.conf ${COREBASE}/meta*/conf/site.conf.sample\" is a good way to visualise the changes.\n")
+
+
+def sanity_handle_abichanges(status, d):
+    #
+    # Check the 'ABI' of TMPDIR
+    #
+    import subprocess
+
+    current_abi = d.getVar('OELAYOUT_ABI', True)
+    abifile = d.getVar('SANITY_ABIFILE', True)
+    if os.path.exists(abifile):
+        with open(abifile, "r") as f:
+            abi = f.read().strip()
+        if not abi.isdigit():
+            with open(abifile, "w") as f:
+                f.write(current_abi)
+        elif abi == "2" and current_abi == "3":
+            bb.note("Converting staging from layout version 2 to layout version 3")
+            subprocess.call(d.expand("mv ${TMPDIR}/staging ${TMPDIR}/sysroots"), shell=True)
+            subprocess.call(d.expand("ln -s sysroots ${TMPDIR}/staging"), shell=True)
+            subprocess.call(d.expand("cd ${TMPDIR}/stamps; for i in */*do_populate_staging; do new=`echo $i | sed -e 's/do_populate_staging/do_populate_sysroot/'`; mv $i $new; done"), shell=True)
+            with open(abifile, "w") as f:
+                f.write(current_abi)
+        elif abi == "3" and current_abi == "4":
+            bb.note("Converting staging layout from version 3 to layout version 4")
+            if os.path.exists(d.expand("${STAGING_DIR_NATIVE}${bindir_native}/${MULTIMACH_HOST_SYS}")):
+                subprocess.call(d.expand("mv ${STAGING_DIR_NATIVE}${bindir_native}/${MULTIMACH_HOST_SYS} ${STAGING_BINDIR_CROSS}"), shell=True)
+                subprocess.call(d.expand("ln -s ${STAGING_BINDIR_CROSS} ${STAGING_DIR_NATIVE}${bindir_native}/${MULTIMACH_HOST_SYS}"), shell=True)
+            with open(abifile, "w") as f:
+                f.write(current_abi)
+        elif abi == "4":
+            status.addresult("Staging layout has changed. The cross directory has been deprecated and cross packages are now built under the native sysroot.\nThis requires a rebuild.\n")
+        elif abi == "5" and current_abi == "6":
+            bb.note("Converting staging layout from version 5 to layout version 6")
+            subprocess.call(d.expand("mv ${TMPDIR}/pstagelogs ${SSTATE_MANIFESTS}"), shell=True)
+            with open(abifile, "w") as f:
+                f.write(current_abi)
+        elif abi == "7" and current_abi == "8":
+            status.addresult("Your configuration is using stamp files including the sstate hash but your build directory was built with stamp files that do not include this.\nTo continue, either rebuild or switch back to the OEBasic signature handler with BB_SIGNATURE_HANDLER = 'OEBasic'.\n")
+        elif (abi != current_abi and current_abi == "9"):
+            status.addresult("The layout of the TMPDIR STAMPS directory has changed. Please clean out TMPDIR and rebuild (sstate will be still be valid and reused)\n")
+        elif (abi != current_abi and current_abi == "10" and (abi == "8" or abi == "9")):
+            bb.note("Converting staging layout from version 8/9 to layout version 10")
+            cmd = d.expand("grep -r -l sysroot-providers/virtual_kernel ${SSTATE_MANIFESTS}")
+            ret, result = oe.utils.getstatusoutput(cmd)
+            result = result.split()
+            for f in result:
+                bb.note("Uninstalling manifest file %s" % f)
+                sstate_clean_manifest(f, d)
+            with open(abifile, "w") as f:
+                f.write(current_abi)
+        elif abi == "10" and current_abi == "11":
+            bb.note("Converting staging layout from version 10 to layout version 11")
+            # Files in xf86-video-modesetting moved to xserver-xorg and bitbake can't currently handle that:
+            subprocess.call(d.expand("rm ${TMPDIR}/sysroots/*/usr/lib/xorg/modules/drivers/modesetting_drv.so ${TMPDIR}/sysroots/*/pkgdata/runtime/xf86-video-modesetting* ${TMPDIR}/sysroots/*/pkgdata/runtime-reverse/xf86-video-modesetting* ${TMPDIR}/sysroots/*/pkgdata/shlibs2/xf86-video-modesetting*"), shell=True)
+            with open(abifile, "w") as f:
+                f.write(current_abi)
+        elif (abi != current_abi):
+            # Code to convert from one ABI to another could go here if possible.
+            status.addresult("Error, TMPDIR has changed its layout version number (%s to %s) and you need to either rebuild, revert or adjust it at your own risk.\n" % (abi, current_abi))
+    else:
+        with open(abifile, "w") as f:
+            f.write(current_abi)
+
+def check_sanity_sstate_dir_change(sstate_dir, data):
+    # Sanity checks to be done when the value of SSTATE_DIR changes
+
+    # Check that SSTATE_DIR isn't on a filesystem with limited filename length (eg. eCryptFS)
+    testmsg = ""
+    if sstate_dir != "":
+        testmsg = check_create_long_filename(sstate_dir, "SSTATE_DIR")
+        # If we don't have permissions to SSTATE_DIR, suggest the user set it as an SSTATE_MIRRORS
+        try:
+            err = testmsg.split(': ')[1].strip()
+            if err == "Permission denied.":
+                testmsg = testmsg + "You could try using %s in SSTATE_MIRRORS rather than as an SSTATE_CACHE.\n" % (sstate_dir)
+        except IndexError:
+            pass
+    return testmsg
+       
+def check_sanity_version_change(status, d):
+    # Sanity checks to be done when SANITY_VERSION changes
+    # In other words, these tests run once in a given build directory and then 
+    # never again until the sanity version changes.
+
+    # Check the python install is complete. glib-2.0-natives requries
+    # xml.parsers.expat
+    try:
+        import xml.parsers.expat
+    except ImportError:
+        status.addresult('Your python is not a full install. Please install the module xml.parsers.expat (python-xml on openSUSE and SUSE Linux).\n')
+    import stat
+
+    status.addresult(check_make_version(d))
+    status.addresult(check_tar_version(d))
+    status.addresult(check_git_version(d))
+    status.addresult(check_perl_modules(d))
+
+    missing = ""
+
+    if not check_app_exists("${MAKE}", d):
+        missing = missing + "GNU make,"
+
+    if not check_app_exists('${BUILD_PREFIX}gcc', d):
+        missing = missing + "C Compiler (%sgcc)," % d.getVar("BUILD_PREFIX", True)
+
+    if not check_app_exists('${BUILD_PREFIX}g++', d):
+        missing = missing + "C++ Compiler (%sg++)," % d.getVar("BUILD_PREFIX", True)
+
+    required_utilities = d.getVar('SANITY_REQUIRED_UTILITIES', True)
+
+    for util in required_utilities.split():
+        if not check_app_exists(util, d):
+            missing = missing + "%s," % util
+
+    if missing:
+        missing = missing.rstrip(',')
+        status.addresult("Please install the following missing utilities: %s\n" % missing)
+
+    assume_provided = d.getVar('ASSUME_PROVIDED', True).split()
+    # Check user doesn't have ASSUME_PROVIDED = instead of += in local.conf
+    if "diffstat-native" not in assume_provided:
+        status.addresult('Please use ASSUME_PROVIDED +=, not ASSUME_PROVIDED = in your local.conf\n')
+
+    if "qemu-native" in assume_provided:
+        if not check_app_exists("qemu-arm", d):
+            status.addresult("qemu-native was in ASSUME_PROVIDED but the QEMU binaries (qemu-arm) can't be found in PATH")
+
+    if "libsdl-native" in assume_provided:
+        if not check_app_exists("sdl-config", d):
+            status.addresult("libsdl-native is set to be ASSUME_PROVIDED but sdl-config can't be found in PATH. Please either install it, or configure qemu not to require sdl.")
+
+    (result, message) = check_gcc_march(d)
+    if result and message:
+        status.addresult("Your gcc version is older than 4.5, please add the following param to local.conf\n \
+        %s\n" % message)
+    if not result:
+        status.addresult("Your gcc version is older than 4.5 or is not working properly.  Please verify you can build")
+        status.addresult(" and link something that uses atomic operations, such as: \n")
+        status.addresult("        __sync_bool_compare_and_swap (&atomic, 2, 3);\n")
+
+    # Check that TMPDIR isn't on a filesystem with limited filename length (eg. eCryptFS)
+    tmpdir = d.getVar('TMPDIR', True)
+    status.addresult(check_create_long_filename(tmpdir, "TMPDIR"))
+    tmpdirmode = os.stat(tmpdir).st_mode
+    if (tmpdirmode & stat.S_ISGID):
+        status.addresult("TMPDIR is setgid, please don't build in a setgid directory")
+    if (tmpdirmode & stat.S_ISUID):
+        status.addresult("TMPDIR is setuid, please don't build in a setuid directory")
+
+    # Some third-party software apparently relies on chmod etc. being suid root (!!)
+    import stat
+    suid_check_bins = "chown chmod mknod".split()
+    for bin_cmd in suid_check_bins:
+        bin_path = bb.utils.which(os.environ["PATH"], bin_cmd)
+        if bin_path:
+            bin_stat = os.stat(bin_path)
+            if bin_stat.st_uid == 0 and bin_stat.st_mode & stat.S_ISUID:
+                status.addresult('%s has the setuid bit set. This interferes with pseudo and may cause other issues that break the build process.\n' % bin_path)
+
+    # Check that we can fetch from various network transports
+    netcheck = check_connectivity(d)
+    status.addresult(netcheck)
+    if netcheck:
+        status.network_error = True
+
+    nolibs = d.getVar('NO32LIBS', True)
+    if not nolibs:
+        lib32path = '/lib'
+        if os.path.exists('/lib64') and ( os.path.islink('/lib64') or os.path.islink('/lib') ):
+           lib32path = '/lib32'
+
+        if os.path.exists('%s/libc.so.6' % lib32path) and not os.path.exists('/usr/include/gnu/stubs-32.h'):
+            status.addresult("You have a 32-bit libc, but no 32-bit headers.  You must install the 32-bit libc headers.\n")
+
+    bbpaths = d.getVar('BBPATH', True).split(":")
+    if ("." in bbpaths or "./" in bbpaths or "" in bbpaths) and not status.reparse:
+        status.addresult("BBPATH references the current directory, either through "    \
+                "an empty entry, a './' or a '.'.\n\t This is unsafe and means your "\
+                "layer configuration is adding empty elements to BBPATH.\n\t "\
+                "Please check your layer.conf files and other BBPATH "        \
+                "settings to remove the current working directory "           \
+                "references.\n" \
+                "Parsed BBPATH is" + str(bbpaths));
+
+    oes_bb_conf = d.getVar( 'OES_BITBAKE_CONF', True)
+    if not oes_bb_conf:
+        status.addresult('You are not using the OpenEmbedded version of conf/bitbake.conf. This means your environment is misconfigured, in particular check BBPATH.\n')
+
+    # The length of TMPDIR can't be longer than 410
+    status.addresult(check_path_length(tmpdir, "TMPDIR", 410))
+
+    # Check that TMPDIR isn't located on nfs
+    status.addresult(check_not_nfs(tmpdir, "TMPDIR"))
+
+def check_sanity_everybuild(status, d):
+    import os, stat
+    # Sanity tests which test the users environment so need to run at each build (or are so cheap
+    # it makes sense to always run them.
+
+    if 0 == os.getuid():
+        raise_sanity_error("Do not use Bitbake as root.", d)
+
+    # Check the Python version, we now have a minimum of Python 2.7.3
+    import sys
+    if sys.hexversion < 0x020703F0:
+        status.addresult('The system requires at least Python 2.7.3 to run. Please update your Python interpreter.\n')
+
+    # Check the bitbake version meets minimum requirements
+    from distutils.version import LooseVersion
+    minversion = d.getVar('BB_MIN_VERSION', True)
+    if (LooseVersion(bb.__version__) < LooseVersion(minversion)):
+        status.addresult('Bitbake version %s is required and version %s was found\n' % (minversion, bb.__version__))
+
+    sanity_check_conffiles(status, d)
+
+    paths = d.getVar('PATH', True).split(":")
+    if "." in paths or "./" in paths or "" in paths:
+        status.addresult("PATH contains '.', './' or '' (empty element), which will break the build, please remove this.\nParsed PATH is " + str(paths) + "\n")
+
+    # Check that the DISTRO is valid, if set
+    # need to take into account DISTRO renaming DISTRO
+    distro = d.getVar('DISTRO', True)
+    if distro and distro != "nodistro":
+        if not ( check_conf_exists("conf/distro/${DISTRO}.conf", d) or check_conf_exists("conf/distro/include/${DISTRO}.inc", d) ):
+            status.addresult("DISTRO '%s' not found. Please set a valid DISTRO in your local.conf\n" % d.getVar("DISTRO", True))
+
+    # Check that DL_DIR is set, exists and is writable. In theory, we should never even hit the check if DL_DIR isn't 
+    # set, since so much relies on it being set.
+    dldir = d.getVar('DL_DIR', True)
+    if not dldir:
+        status.addresult("DL_DIR is not set. Your environment is misconfigured, check that DL_DIR is set, and if the directory exists, that it is writable. \n")
+    if os.path.exists(dldir) and not os.access(dldir, os.W_OK):
+        status.addresult("DL_DIR: %s exists but you do not appear to have write access to it. \n" % dldir)
+    check_symlink(dldir, d)
+
+    # Check that the MACHINE is valid, if it is set
+    machinevalid = True
+    if d.getVar('MACHINE', True):
+        if not check_conf_exists("conf/machine/${MACHINE}.conf", d):
+            status.addresult('Please set a valid MACHINE in your local.conf or environment\n')
+            machinevalid = False
+        else:
+            status.addresult(check_sanity_validmachine(d))
+    else:
+        status.addresult('Please set a MACHINE in your local.conf or environment\n')
+        machinevalid = False
+    if machinevalid:
+        status.addresult(check_toolchain(d))
+
+    # Check that the SDKMACHINE is valid, if it is set
+    if d.getVar('SDKMACHINE', True):
+        if not check_conf_exists("conf/machine-sdk/${SDKMACHINE}.conf", d):
+            status.addresult('Specified SDKMACHINE value is not valid\n')
+        elif d.getVar('SDK_ARCH', False) == "${BUILD_ARCH}":
+            status.addresult('SDKMACHINE is set, but SDK_ARCH has not been changed as a result - SDKMACHINE may have been set too late (e.g. in the distro configuration)\n')
+
+    check_supported_distro(d)
+
+    # Check if DISPLAY is set if TEST_IMAGE is set
+    if d.getVar('TEST_IMAGE', True) == '1' or d.getVar('DEFAULT_TEST_SUITES', True):
+        testtarget = d.getVar('TEST_TARGET', True)
+        if testtarget == 'qemu' or testtarget == 'QemuTarget':
+            display = d.getVar("BB_ORIGENV", False).getVar("DISPLAY", True)
+            if not display:
+                status.addresult('testimage needs an X desktop to start qemu, please set DISPLAY correctly (e.g. DISPLAY=:1.0)\n')
+
+    omask = os.umask(022)
+    if omask & 0755:
+        status.addresult("Please use a umask which allows a+rx and u+rwx\n")
+    os.umask(omask)
+
+    if d.getVar('TARGET_ARCH', True) == "arm":
+        # This path is no longer user-readable in modern (very recent) Linux
+        try:
+            if os.path.exists("/proc/sys/vm/mmap_min_addr"):
+                f = open("/proc/sys/vm/mmap_min_addr", "r")
+                try:
+                    if (int(f.read().strip()) > 65536):
+                        status.addresult("/proc/sys/vm/mmap_min_addr is not <= 65536. This will cause problems with qemu so please fix the value (as root).\n\nTo fix this in later reboots, set vm.mmap_min_addr = 65536 in /etc/sysctl.conf.\n")
+                finally:
+                    f.close()
+        except:
+            pass
+
+    oeroot = d.getVar('COREBASE', True)
+    if oeroot.find('+') != -1:
+        status.addresult("Error, you have an invalid character (+) in your COREBASE directory path. Please move the installation to a directory which doesn't include any + characters.")
+    if oeroot.find('@') != -1:
+        status.addresult("Error, you have an invalid character (@) in your COREBASE directory path. Please move the installation to a directory which doesn't include any @ characters.")
+    if oeroot.find(' ') != -1:
+        status.addresult("Error, you have a space in your COREBASE directory path. Please move the installation to a directory which doesn't include a space since autotools doesn't support this.")
+
+    # Check the format of MIRRORS, PREMIRRORS and SSTATE_MIRRORS
+    import re
+    mirror_vars = ['MIRRORS', 'PREMIRRORS', 'SSTATE_MIRRORS']
+    protocols = ['http', 'ftp', 'file', 'https', \
+                 'git', 'gitsm', 'hg', 'osc', 'p4', 'svn', \
+                 'bzr', 'cvs']
+    for mirror_var in mirror_vars:
+        mirrors = (d.getVar(mirror_var, True) or '').replace('\\n', '\n').split('\n')
+        for mirror_entry in mirrors:
+            mirror_entry = mirror_entry.strip()
+            if not mirror_entry:
+                # ignore blank lines
+                continue
+
+            try:
+                pattern, mirror = mirror_entry.split()
+            except ValueError:
+                bb.warn('Invalid %s: %s, should be 2 members.' % (mirror_var, mirror_entry.strip()))
+                continue
+
+            decoded = bb.fetch2.decodeurl(pattern)
+            try:
+                pattern_scheme = re.compile(decoded[0])
+            except re.error as exc:
+                bb.warn('Invalid scheme regex (%s) in %s; %s' % (pattern, mirror_var, mirror_entry))
+                continue
+
+            if not any(pattern_scheme.match(protocol) for protocol in protocols):
+                bb.warn('Invalid protocol (%s) in %s: %s' % (decoded[0], mirror_var, mirror_entry))
+                continue
+
+            if not any(mirror.startswith(protocol + '://') for protocol in protocols):
+                bb.warn('Invalid protocol in %s: %s' % (mirror_var, mirror_entry))
+                continue
+
+            if mirror.startswith('file://'):
+                import urlparse
+                check_symlink(urlparse.urlparse(mirror).path, d)
+                # SSTATE_MIRROR ends with a /PATH string
+                if mirror.endswith('/PATH'):
+                    # remove /PATH$ from SSTATE_MIRROR to get a working
+                    # base directory path
+                    mirror_base = urlparse.urlparse(mirror[:-1*len('/PATH')]).path
+                    check_symlink(mirror_base, d)
+
+    # Check that TMPDIR hasn't changed location since the last time we were run
+    tmpdir = d.getVar('TMPDIR', True)
+    checkfile = os.path.join(tmpdir, "saved_tmpdir")
+    if os.path.exists(checkfile):
+        with open(checkfile, "r") as f:
+            saved_tmpdir = f.read().strip()
+            if (saved_tmpdir != tmpdir):
+                status.addresult("Error, TMPDIR has changed location. You need to either move it back to %s or rebuild\n" % saved_tmpdir)
+    else:
+        bb.utils.mkdirhier(tmpdir)
+        # Remove setuid, setgid and sticky bits from TMPDIR
+        os.chmod(tmpdir, os.stat(tmpdir).st_mode & ~ stat.S_ISUID)
+        os.chmod(tmpdir, os.stat(tmpdir).st_mode & ~ stat.S_ISGID)
+        os.chmod(tmpdir, os.stat(tmpdir).st_mode & ~ stat.S_ISVTX)
+        with open(checkfile, "w") as f:
+            f.write(tmpdir)
+
+    # Check vmdk and live can't be built together.
+    if 'vmdk' in d.getVar('IMAGE_FSTYPES', True) and 'live' in d.getVar('IMAGE_FSTYPES', True):
+        status.addresult("Error, IMAGE_FSTYPES vmdk and live can't be built together\n")
+
+    # Check vdi and live can't be built together.
+    if 'vdi' in d.getVar('IMAGE_FSTYPES', True) and 'live' in d.getVar('IMAGE_FSTYPES', True):
+        status.addresult("Error, IMAGE_FSTYPES vdi and live can't be built together\n")
+
+    # Check qcow2 and live can't be built together.
+    if 'qcow2' in d.getVar('IMAGE_FSTYPES', True) and 'live' in d.getVar('IMAGE_FSTYPES', True):
+        status.addresult("Error, IMAGE_FSTYPES qcow2 and live can't be built together\n")
+
+    # Check /bin/sh links to dash or bash
+    real_sh = os.path.realpath('/bin/sh')
+    if not real_sh.endswith('/dash') and not real_sh.endswith('/bash'):
+        status.addresult("Error, /bin/sh links to %s, must be dash or bash\n" % real_sh)
+
+def check_sanity(sanity_data):
+    class SanityStatus(object):
+        def __init__(self):
+            self.messages = ""
+            self.network_error = False
+            self.reparse = False
+
+        def addresult(self, message):
+            if message:
+                self.messages = self.messages + message
+
+    status = SanityStatus()
+
+    tmpdir = sanity_data.getVar('TMPDIR', True)
+    sstate_dir = sanity_data.getVar('SSTATE_DIR', True)
+
+    check_symlink(sstate_dir, sanity_data)
+
+    # Check saved sanity info
+    last_sanity_version = 0
+    last_tmpdir = ""
+    last_sstate_dir = ""
+    sanityverfile = sanity_data.expand("${TOPDIR}/conf/sanity_info")
+    if os.path.exists(sanityverfile):
+        with open(sanityverfile, 'r') as f:
+            for line in f:
+                if line.startswith('SANITY_VERSION'):
+                    last_sanity_version = int(line.split()[1])
+                if line.startswith('TMPDIR'):
+                    last_tmpdir = line.split()[1]
+                if line.startswith('SSTATE_DIR'):
+                    last_sstate_dir = line.split()[1]
+
+    check_sanity_everybuild(status, sanity_data)
+    
+    sanity_version = int(sanity_data.getVar('SANITY_VERSION', True) or 1)
+    network_error = False
+    if last_sanity_version < sanity_version: 
+        check_sanity_version_change(status, sanity_data)
+        status.addresult(check_sanity_sstate_dir_change(sstate_dir, sanity_data))
+    else: 
+        if last_sstate_dir != sstate_dir:
+            status.addresult(check_sanity_sstate_dir_change(sstate_dir, sanity_data))
+
+    if os.path.exists(os.path.dirname(sanityverfile)) and not status.messages:
+        with open(sanityverfile, 'w') as f:
+            f.write("SANITY_VERSION %s\n" % sanity_version) 
+            f.write("TMPDIR %s\n" % tmpdir) 
+            f.write("SSTATE_DIR %s\n" % sstate_dir) 
+
+    sanity_handle_abichanges(status, sanity_data)
+
+    if status.messages != "":
+        raise_sanity_error(sanity_data.expand(status.messages), sanity_data, status.network_error)
+    return status.reparse
+
+# Create a copy of the datastore and finalise it to ensure appends and 
+# overrides are set - the datastore has yet to be finalised at ConfigParsed
+def copy_data(e):
+    sanity_data = bb.data.createCopy(e.data)
+    sanity_data.finalize()
+    return sanity_data
+
+addhandler check_sanity_eventhandler
+check_sanity_eventhandler[eventmask] = "bb.event.SanityCheck bb.event.NetworkTest"
+python check_sanity_eventhandler() {
+    if bb.event.getName(e) == "SanityCheck":
+        sanity_data = copy_data(e)
+        if e.generateevents:
+            sanity_data.setVar("SANITY_USE_EVENTS", "1")
+        reparse = check_sanity(sanity_data)
+        e.data.setVar("BB_INVALIDCONF", reparse)
+        bb.event.fire(bb.event.SanityCheckPassed(), e.data)
+    elif bb.event.getName(e) == "NetworkTest":
+        sanity_data = copy_data(e)
+        if e.generateevents:
+            sanity_data.setVar("SANITY_USE_EVENTS", "1")
+        bb.event.fire(bb.event.NetworkTestFailed() if check_connectivity(sanity_data) else bb.event.NetworkTestPassed(), e.data)
+
+    return
+}
