reset upstream subtrees to yocto 2.6

Reset the following subtrees on thud HEAD:

  poky: 87e3a9739d
  meta-openembedded: 6094ae18c8
  meta-security: 31dc4e7532
  meta-raspberrypi: a48743dc36
  meta-xilinx: c42016e2e6

Also re-apply backports that didn't make it into thud:
  poky:
    17726d0 systemd-systemctl-native: handle Install wildcards

  meta-openembedded:
    4321a5d libtinyxml2: update to 7.0.1
    042f0a3 libcereal: Add native and nativesdk classes
    e23284f libcereal: Allow empty package
    030e8d4 rsyslog: curl-less build with fmhttp PACKAGECONFIG
    179a1b9 gtest: update to 1.8.1

Squashed OpenBMC subtree compatibility updates:
  meta-aspeed:
    Brad Bishop (1):
          aspeed: add yocto 2.6 compatibility

  meta-ibm:
    Brad Bishop (1):
          ibm: prepare for yocto 2.6

  meta-ingrasys:
    Brad Bishop (1):
          ingrasys: set layer compatibility to yocto 2.6

  meta-openpower:
    Brad Bishop (1):
          openpower: set layer compatibility to yocto 2.6

  meta-phosphor:
    Brad Bishop (3):
          phosphor: set layer compatibility to thud
          phosphor: libgpg-error: drop patches
          phosphor: react to fitimage artifact rename

    Ed Tanous (4):
          Dropbear: upgrade options for latest upgrade
          yocto2.6: update openssl options
          busybox: remove upstream watchdog patch
          systemd: Rebase CONFIG_CGROUP_BPF patch

Change-Id: I7b1fe71cca880d0372a82d94b5fd785323e3a9e7
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/poky/scripts/lib/build_perf/html/report.html b/poky/scripts/lib/build_perf/html/report.html
index 291ad9d..d1ba6f2 100644
--- a/poky/scripts/lib/build_perf/html/report.html
+++ b/poky/scripts/lib/build_perf/html/report.html
@@ -136,10 +136,13 @@
             {% else %}
               {% set result_style = "color: orange" %}
             {%endif %}
+            {% if measurement.reldiff|abs > 2 %}
+              {% set result_style = result_style + "; font-weight: bold" %}
+            {% endif %}
             <td>{{ measurement.description }}</td>
             <td style="font-weight: bold">{{ measurement.value.mean }}</td>
             <td style="{{ result_style }}">{{ measurement.absdiff_str }}</td>
-            <td style="{{ result_style }}">{{ measurement.reldiff }}</td>
+            <td style="{{ result_style }}">{{ measurement.reldiff_str }}</td>
           </tr>
         {% endfor %}
       {% else %}
@@ -167,7 +170,7 @@
             {% else %}
             <span style="color: orange">
             {% endif %}
-            {{ measurement.absdiff_str }} ({{measurement.reldiff}})
+            {{ measurement.absdiff_str }} ({{measurement.reldiff_str}})
             </span></span>
           </div>
           {# Table for trendchart and the statistics #}
diff --git a/poky/scripts/lib/devtool/build.py b/poky/scripts/lib/devtool/build.py
index 252379e..ba9593f 100644
--- a/poky/scripts/lib/devtool/build.py
+++ b/poky/scripts/lib/devtool/build.py
@@ -54,7 +54,11 @@
     """Entry point for the devtool 'build' subcommand"""
     workspacepn = check_workspace_recipe(workspace, args.recipename, bbclassextend=True)
 
-    build_tasks = _get_build_tasks(config)
+    if args.clean:
+        # use clean instead of cleansstate to avoid messing things up in eSDK
+        build_tasks = ['do_clean']
+    else:
+        build_tasks = _get_build_tasks(config)
 
     bbappend = workspace[workspacepn]['bbappend']
     if args.disable_parallel_make:
@@ -83,4 +87,5 @@
                                          group='working', order=50)
     parser_build.add_argument('recipename', help='Recipe to build')
     parser_build.add_argument('-s', '--disable-parallel-make', action="store_true", help='Disable make parallelism')
+    parser_build.add_argument('-c', '--clean', action='store_true', help='clean up recipe building results')
     parser_build.set_defaults(func=build)
diff --git a/poky/scripts/lib/devtool/export.py b/poky/scripts/lib/devtool/export.py
index 13ee258..35349e2 100644
--- a/poky/scripts/lib/devtool/export.py
+++ b/poky/scripts/lib/devtool/export.py
@@ -84,7 +84,7 @@
 
     # if all workspace is excluded, quit
     if not len(set(workspace.keys()).difference(set(args.exclude))):
-        logger.warn('All recipes in workspace excluded, nothing to export')
+        logger.warning('All recipes in workspace excluded, nothing to export')
         return 0
 
     exported = []
diff --git a/poky/scripts/lib/devtool/import.py b/poky/scripts/lib/devtool/import.py
index c13a180..4264b7d 100644
--- a/poky/scripts/lib/devtool/import.py
+++ b/poky/scripts/lib/devtool/import.py
@@ -81,7 +81,7 @@
                     break
             else:
                 non_importables.append(fn)
-                logger.warn('No recipe to append %s.bbapppend, skipping' % fn)
+                logger.warning('No recipe to append %s.bbapppend, skipping' % fn)
 
         # Extract
         imported = []
@@ -104,9 +104,9 @@
                         try:
                             tar.extract(member, path=config.workspace_path)
                         except PermissionError as pe:
-                            logger.warn(pe)
+                            logger.warning(pe)
                     else:
-                        logger.warn('File already present. Use --overwrite/-o to overwrite it: %s' % member.name)
+                        logger.warning('File already present. Use --overwrite/-o to overwrite it: %s' % member.name)
                         continue
                 else:
                     tar.extract(member, path=config.workspace_path)
@@ -129,7 +129,7 @@
     if imported:
         logger.info('Imported recipes into workspace %s: %s' % (config.workspace_path, ', '.join(imported)))
     else:
-        logger.warn('No recipes imported into the workspace')
+        logger.warning('No recipes imported into the workspace')
 
     return 0
 
diff --git a/poky/scripts/lib/devtool/standard.py b/poky/scripts/lib/devtool/standard.py
index a1e8e1d..d14b7a6 100644
--- a/poky/scripts/lib/devtool/standard.py
+++ b/poky/scripts/lib/devtool/standard.py
@@ -66,7 +66,7 @@
             args.srctree = args.recipename
             args.recipename = None
         elif os.path.isdir(args.recipename):
-            logger.warn('Ambiguous argument "%s" - assuming you mean it to be the recipe name' % args.recipename)
+            logger.warning('Ambiguous argument "%s" - assuming you mean it to be the recipe name' % args.recipename)
 
     if not args.fetchuri:
         if args.srcrev:
@@ -82,7 +82,7 @@
         if args.fetchuri:
             raise DevtoolError('URI specified as positional argument as well as -f/--fetch')
         else:
-            logger.warn('-f/--fetch option is deprecated - you can now simply specify the URL to fetch as a positional argument instead')
+            logger.warning('-f/--fetch option is deprecated - you can now simply specify the URL to fetch as a positional argument instead')
             args.fetchuri = args.fetch
 
     if args.recipename:
@@ -217,7 +217,7 @@
             raise DevtoolError('Command \'%s\' did not create any recipe file:\n%s' % (e.command, e.stdout))
         attic_recipe = os.path.join(config.workspace_path, 'attic', recipename, os.path.basename(recipefile))
         if os.path.exists(attic_recipe):
-            logger.warn('A modified recipe from a previous invocation exists in %s - you may wish to move this over the top of the new recipe if you had changes in it that you want to continue with' % attic_recipe)
+            logger.warning('A modified recipe from a previous invocation exists in %s - you may wish to move this over the top of the new recipe if you had changes in it that you want to continue with' % attic_recipe)
     finally:
         if tmpsrcdir and os.path.exists(tmpsrcdir):
             shutil.rmtree(tmpsrcdir)
@@ -295,7 +295,7 @@
                     with open(layerconf_file, 'a') as f:
                         f.write('%s = "%s"\n' % (preferred_provider, recipe_name))
                 else:
-                    logger.warn('Set \'%s\' in order to use the recipe' % preferred_provider)
+                    logger.warning('Set \'%s\' in order to use the recipe' % preferred_provider)
                 break
 
         _add_md5(config, recipename, appendfile)
@@ -704,7 +704,7 @@
                     if splitline[2] != md5:
                         bb.utils.mkdirhier(preservepath)
                         preservefile = os.path.basename(removefile)
-                        logger.warn('File %s modified since it was written, preserving in %s' % (preservefile, preservepath))
+                        logger.warning('File %s modified since it was written, preserving in %s' % (preservefile, preservepath))
                         shutil.move(removefile, os.path.join(preservepath, preservefile))
                     else:
                         os.remove(removefile)
@@ -795,7 +795,7 @@
                 if branchname.startswith(override_branch_prefix):
                     branches.append(branchname)
             if branches:
-                logger.warn('SRC_URI is conditionally overridden in this recipe, thus several %s* branches have been created, one for each override that makes changes to SRC_URI. It is recommended that you make changes to the %s branch first, then checkout and rebase each %s* branch and update any unique patches there (duplicates on those branches will be ignored by devtool finish/update-recipe)' % (override_branch_prefix, args.branch, override_branch_prefix))
+                logger.warning('SRC_URI is conditionally overridden in this recipe, thus several %s* branches have been created, one for each override that makes changes to SRC_URI. It is recommended that you make changes to the %s branch first, then checkout and rebase each %s* branch and update any unique patches there (duplicates on those branches will be ignored by devtool finish/update-recipe)' % (override_branch_prefix, args.branch, override_branch_prefix))
             branches.insert(0, args.branch)
             seen_patches = []
             for branch in branches:
@@ -1720,7 +1720,7 @@
         if updated:
             rf = rd.getVar('FILE')
             if rf.startswith(config.workspace_path):
-                logger.warn('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf)
+                logger.warning('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf)
     finally:
         tinfoil.shutdown()
 
@@ -1803,7 +1803,7 @@
             if os.path.exists(origdir):
                 for root, dirs, files in os.walk(origdir):
                     for fn in files:
-                        logger.warn('Preserving %s in %s' % (fn, preservepath))
+                        logger.warning('Preserving %s in %s' % (fn, preservepath))
                         _move_file(os.path.join(origdir, fn),
                                    os.path.join(preservepath, fn))
                     for dn in dirs:
diff --git a/poky/scripts/lib/devtool/upgrade.py b/poky/scripts/lib/devtool/upgrade.py
index c3fd866..2020077 100644
--- a/poky/scripts/lib/devtool/upgrade.py
+++ b/poky/scripts/lib/devtool/upgrade.py
@@ -264,7 +264,7 @@
     if no_patch:
         patches = oe.recipeutils.get_recipe_patches(crd)
         if patches:
-            logger.warn('By user choice, the following patches will NOT be applied to the new source tree:\n  %s' % '\n  '.join([os.path.basename(patch) for patch in patches]))
+            logger.warning('By user choice, the following patches will NOT be applied to the new source tree:\n  %s' % '\n  '.join([os.path.basename(patch) for patch in patches]))
     else:
         __run('git checkout devtool-patched -b %s' % branch)
         skiptag = False
@@ -273,9 +273,9 @@
         except bb.process.ExecutionError as e:
             skiptag = True
             if 'conflict' in e.stdout:
-                logger.warn('Command \'%s\' failed:\n%s\n\nYou will need to resolve conflicts in order to complete the upgrade.' % (e.command, e.stdout.rstrip()))
+                logger.warning('Command \'%s\' failed:\n%s\n\nYou will need to resolve conflicts in order to complete the upgrade.' % (e.command, e.stdout.rstrip()))
             else:
-                logger.warn('Command \'%s\' failed:\n%s' % (e.command, e.stdout))
+                logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout))
         if not skiptag:
             if uri.startswith('git://'):
                 suffix = 'new'
@@ -420,7 +420,10 @@
                 logger.info('Source subdirectory has changed, updating S value')
 
     if license_diff:
-        newlicchksum = " ".join(["file://{};md5={}".format(l["path"], l["actual_md5"]) + (";beginline={}".format(l["beginline"]) if l["beginline"] else "") + (";endline={}".format(l["endline"]) if l["endline"] else "") for l in new_licenses])
+        newlicchksum = " ".join(["file://{}".format(l['path']) +
+                                 (";beginline={}".format(l['beginline']) if l['beginline'] else "") +
+                                 (";endline={}".format(l['endline']) if l['endline'] else "") +
+                                 (";md5={}".format(l['actual_md5'])) for l in new_licenses])
         newvalues["LIC_FILES_CHKSUM"] = newlicchksum
         _add_license_diff_to_recipe(fullpath, license_diff)
 
diff --git a/poky/scripts/lib/recipetool/append.py b/poky/scripts/lib/recipetool/append.py
index 69c8bb7..3f2c134 100644
--- a/poky/scripts/lib/recipetool/append.py
+++ b/poky/scripts/lib/recipetool/append.py
@@ -238,7 +238,7 @@
     if stdout:
         logger.debug('file command output: %s' % stdout.rstrip())
         if ('executable' in stdout and not 'shell script' in stdout) or 'shared object' in stdout:
-            logger.warn('This file looks like it is a binary or otherwise the output of compilation. If it is, you should consider building it properly instead of substituting a binary file directly.')
+            logger.warning('This file looks like it is a binary or otherwise the output of compilation. If it is, you should consider building it properly instead of substituting a binary file directly.')
 
     if args.recipe:
         recipes = {args.targetpath: [args.recipe],}
@@ -275,7 +275,7 @@
     if selectpn:
         logger.debug('Selecting recipe %s for file %s' % (selectpn, args.targetpath))
         if postinst_pns:
-            logger.warn('%s be modified by postinstall scripts for the following recipes:\n  %s\nThis may or may not be an issue depending on what modifications these postinstall scripts make.' % (args.targetpath, '\n  '.join(postinst_pns)))
+            logger.warning('%s be modified by postinstall scripts for the following recipes:\n  %s\nThis may or may not be an issue depending on what modifications these postinstall scripts make.' % (args.targetpath, '\n  '.join(postinst_pns)))
         rd = _parse_recipe(selectpn, tinfoil)
         if not rd:
             # Error message already shown
@@ -286,12 +286,12 @@
             sourcetype, sourcepath = sourcefile.split('://', 1)
             logger.debug('Original source file is %s (%s)' % (sourcepath, sourcetype))
             if sourcetype == 'patch':
-                logger.warn('File %s is added by the patch %s - you may need to remove or replace this patch in order to replace the file.' % (args.targetpath, sourcepath))
+                logger.warning('File %s is added by the patch %s - you may need to remove or replace this patch in order to replace the file.' % (args.targetpath, sourcepath))
                 sourcepath = None
         else:
             logger.debug('Unable to determine source file, proceeding anyway')
         if modpatches:
-            logger.warn('File %s is modified by the following patches:\n  %s' % (args.targetpath, '\n  '.join(modpatches)))
+            logger.warning('File %s is modified by the following patches:\n  %s' % (args.targetpath, '\n  '.join(modpatches)))
 
         if instelements and sourcepath:
             install = None
@@ -343,7 +343,7 @@
             if rd.getVar('S') == rd.getVar('STAGING_KERNEL_DIR'):
                 srcdir = os.path.join(workdir, 'git')
                 if not bb.data.inherits_class('kernel-yocto', rd):
-                    logger.warn('S == STAGING_KERNEL_DIR and non-kernel-yocto, unable to determine path to srcdir, defaulting to ${WORKDIR}/git')
+                    logger.warning('S == STAGING_KERNEL_DIR and non-kernel-yocto, unable to determine path to srcdir, defaulting to ${WORKDIR}/git')
             src_destdir = os.path.join(os.path.relpath(srcdir, workdir), src_destdir)
         src_destdir = os.path.normpath(src_destdir)
 
@@ -357,9 +357,9 @@
         if simple_str in simplified:
             existing = simplified[simple_str]
             if source_uri != existing:
-                logger.warn('{0!r} is already in SRC_URI, with different parameters: {1!r}, not adding'.format(source_uri, existing))
+                logger.warning('{0!r} is already in SRC_URI, with different parameters: {1!r}, not adding'.format(source_uri, existing))
             else:
-                logger.warn('{0!r} is already in SRC_URI, not adding'.format(source_uri))
+                logger.warning('{0!r} is already in SRC_URI, not adding'.format(source_uri))
         else:
             extralines.append('SRC_URI += {0}'.format(source_uri))
         copyfiles[newfile] = srcfile
diff --git a/poky/scripts/lib/recipetool/create.py b/poky/scripts/lib/recipetool/create.py
index a371028..1810c70 100644
--- a/poky/scripts/lib/recipetool/create.py
+++ b/poky/scripts/lib/recipetool/create.py
@@ -98,7 +98,7 @@
                             break
             except IOError as ioe:
                 if ioe.errno == 2:
-                    logger.warn('unable to find a pkgdata file for package %s' % pkg)
+                    logger.warning('unable to find a pkgdata file for package %s' % pkg)
                 else:
                     raise
 
@@ -437,7 +437,7 @@
     if scriptutils.is_src_url(source):
         # Warn about github archive URLs
         if re.match('https?://github.com/[^/]+/[^/]+/archive/.+(\.tar\..*|\.zip)$', source):
-            logger.warn('github archive files are not guaranteed to be stable and may be re-generated over time. If the latter occurs, the checksums will likely change and the recipe will fail at do_fetch. It is recommended that you point to an actual commit or tag in the repository instead (using the repository URL in conjunction with the -S/--srcrev option).')
+            logger.warning('github archive files are not guaranteed to be stable and may be re-generated over time. If the latter occurs, the checksums will likely change and the recipe will fail at do_fetch. It is recommended that you point to an actual commit or tag in the repository instead (using the repository URL in conjunction with the -S/--srcrev option).')
         # Fetch a URL
         fetchuri = reformat_git_uri(urldefrag(source)[0])
         if args.binary:
diff --git a/poky/scripts/lib/recipetool/create_kmod.py b/poky/scripts/lib/recipetool/create_kmod.py
index 4569b53..3982537 100644
--- a/poky/scripts/lib/recipetool/create_kmod.py
+++ b/poky/scripts/lib/recipetool/create_kmod.py
@@ -141,7 +141,7 @@
                 warnmsg = 'Unable to find means of passing kernel path into install makefile - if kernel path is hardcoded you will need to patch the makefile'
             if warnmsg:
                 warnmsg += '. Note that the variable KERNEL_SRC will be passed in as the kernel source path.'
-                logger.warn(warnmsg)
+                logger.warning(warnmsg)
                 lines_after.append('# %s' % warnmsg)
 
             return True
diff --git a/poky/scripts/lib/recipetool/create_npm.py b/poky/scripts/lib/recipetool/create_npm.py
index bb42a5c..0366788 100644
--- a/poky/scripts/lib/recipetool/create_npm.py
+++ b/poky/scripts/lib/recipetool/create_npm.py
@@ -90,7 +90,7 @@
             runenv = dict(os.environ, PATH=d.getVar('PATH'))
             bb.process.run('npm shrinkwrap', cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
         except bb.process.ExecutionError as e:
-            logger.warn('npm shrinkwrap failed:\n%s' % e.stdout)
+            logger.warning('npm shrinkwrap failed:\n%s' % e.stdout)
             return
 
         tmpfile = os.path.join(localfilesdir, 'npm-shrinkwrap.json')
@@ -107,12 +107,12 @@
                            cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
         relockbin = os.path.join(NpmRecipeHandler.lockdownpath, 'node_modules', 'lockdown', 'relock.js')
         if not os.path.exists(relockbin):
-            logger.warn('Could not find relock.js within lockdown directory; skipping lockdown')
+            logger.warning('Could not find relock.js within lockdown directory; skipping lockdown')
             return
         try:
             bb.process.run('node %s' % relockbin, cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
         except bb.process.ExecutionError as e:
-            logger.warn('lockdown-relock failed:\n%s' % e.stdout)
+            logger.warning('lockdown-relock failed:\n%s' % e.stdout)
             return
 
         tmpfile = os.path.join(localfilesdir, 'lockdown.json')
diff --git a/poky/scripts/lib/recipetool/edit.py b/poky/scripts/lib/recipetool/edit.py
new file mode 100644
index 0000000..c4789a9
--- /dev/null
+++ b/poky/scripts/lib/recipetool/edit.py
@@ -0,0 +1,54 @@
+# Recipe creation tool - edit plugin
+#
+# This sub-command edits the recipe and appends for the specified target
+#
+# Example: recipetool edit busybox
+#
+# Copyright (C) 2018 Mentor Graphics Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import argparse
+import errno
+import logging
+import os
+import re
+import subprocess
+import sys
+import scriptutils
+
+
+logger = logging.getLogger('recipetool')
+tinfoil = None
+
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+def edit(args):
+    import oe.recipeutils
+
+    recipe_path = tinfoil.get_recipe_file(args.target)
+    appends = tinfoil.get_file_appends(recipe_path)
+
+    return scriptutils.run_editor([recipe_path] + appends, logger)
+
+
+def register_commands(subparsers):
+    parser = subparsers.add_parser('edit',
+                                   help='Edit the recipe and appends for the specified target. This obeys $VISUAL if set, otherwise $EDITOR, otherwise vi.')
+    parser.add_argument('target', help='Target recipe/provide to edit')
+    parser.set_defaults(func=edit, parserecipes=True)
diff --git a/poky/scripts/lib/recipetool/newappend.py b/poky/scripts/lib/recipetool/newappend.py
index decce83..76707b4 100644
--- a/poky/scripts/lib/recipetool/newappend.py
+++ b/poky/scripts/lib/recipetool/newappend.py
@@ -58,11 +58,11 @@
         return 1
 
     if not path_ok:
-        logger.warn('Unable to determine correct subdirectory path for bbappend file - check that what %s adds to BBFILES also matches .bbappend files. Using %s for now, but until you fix this the bbappend will not be applied.', os.path.join(args.destlayer, 'conf', 'layer.conf'), os.path.dirname(append_path))
+        logger.warning('Unable to determine correct subdirectory path for bbappend file - check that what %s adds to BBFILES also matches .bbappend files. Using %s for now, but until you fix this the bbappend will not be applied.', os.path.join(args.destlayer, 'conf', 'layer.conf'), os.path.dirname(append_path))
 
     layerdirs = [os.path.abspath(layerdir) for layerdir in rd.getVar('BBLAYERS').split()]
     if not os.path.abspath(args.destlayer) in layerdirs:
-        logger.warn('Specified layer is not currently enabled in bblayers.conf, you will need to add it before this bbappend will be active')
+        logger.warning('Specified layer is not currently enabled in bblayers.conf, you will need to add it before this bbappend will be active')
 
     if not os.path.exists(append_path):
         bb.utils.mkdirhier(os.path.dirname(append_path))
diff --git a/poky/scripts/lib/scriptutils.py b/poky/scripts/lib/scriptutils.py
index 85b1c94..31e48ea 100644
--- a/poky/scripts/lib/scriptutils.py
+++ b/poky/scripts/lib/scriptutils.py
@@ -15,16 +15,17 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-import sys
-import os
-import logging
-import glob
 import argparse
-import subprocess
-import tempfile
-import shutil
+import glob
+import logging
+import os
 import random
+import shlex
+import shutil
 import string
+import subprocess
+import sys
+import tempfile
 
 def logger_create(name, stream=None):
     logger = logging.getLogger(name)
@@ -214,15 +215,14 @@
 
 def run_editor(fn, logger=None):
     if isinstance(fn, str):
-        params = '"%s"' % fn
+        files = [fn]
     else:
-        params = ''
-        for fnitem in fn:
-            params += ' "%s"' % fnitem
+        files = fn
 
     editor = os.getenv('VISUAL', os.getenv('EDITOR', 'vi'))
     try:
-        return subprocess.check_call('%s %s' % (editor, params), shell=True)
+        #print(shlex.split(editor) + files)
+        return subprocess.check_call(shlex.split(editor) + files)
     except subprocess.CalledProcessError as exc:
         logger.error("Execution of '%s' failed: %s" % (editor, exc))
         return 1
diff --git a/poky/scripts/lib/wic/canned-wks/mkhybridiso.wks b/poky/scripts/lib/wic/canned-wks/mkhybridiso.wks
index 9d34e9b..48c5ac4 100644
--- a/poky/scripts/lib/wic/canned-wks/mkhybridiso.wks
+++ b/poky/scripts/lib/wic/canned-wks/mkhybridiso.wks
@@ -2,6 +2,6 @@
 # long-description: Creates an EFI and legacy bootable hybrid ISO image
 # which can be used on optical media as well as USB media.
 
-part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi,image_name=HYBRID_ISO_IMG" --ondisk cd --label HYBRIDISO --fstype=ext4
+part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi,image_name=HYBRID_ISO_IMG" --ondisk cd --label HYBRIDISO
 
 bootloader  --timeout=15  --append=""
diff --git a/poky/scripts/lib/wic/engine.py b/poky/scripts/lib/wic/engine.py
index f0c5ff0..4662c66 100644
--- a/poky/scripts/lib/wic/engine.py
+++ b/poky/scripts/lib/wic/engine.py
@@ -191,7 +191,7 @@
     if not os.path.exists(options.outdir):
         os.makedirs(options.outdir)
 
-    pname = 'direct'
+    pname = options.imager
     plugin_class = PluginMgr.get_plugins('imager').get(pname)
     if not plugin_class:
         raise WicError('Unknown plugin: %s' % pname)
@@ -266,10 +266,15 @@
             out = exec_cmd("%s -sm %s unit B print" % (self.parted, self.imagepath))
             parttype = namedtuple("Part", "pnum start end size fstype")
             splitted = out.splitlines()
-            lsector_size, psector_size, self._ptable_format = splitted[1].split(":")[3:6]
+            # skip over possible errors in exec_cmd output
+            try:
+                idx =splitted.index("BYT;")
+            except ValueError:
+                raise WicError("Error getting partition information from %s" % (self.parted))
+            lsector_size, psector_size, self._ptable_format = splitted[idx + 1].split(":")[3:6]
             self._lsector_size = int(lsector_size)
             self._psector_size = int(psector_size)
-            for line in splitted[2:]:
+            for line in splitted[idx + 2:]:
                 pnum, start, end, size, fstype = line.split(':')[:5]
                 partition = parttype(int(pnum), int(start[:-1]), int(end[:-1]),
                                      int(size[:-1]), fstype)
@@ -340,9 +345,21 @@
         """Remove files/dirs from the partition."""
         partimg = self._get_part_image(pnum)
         if self.partitions[pnum].fstype.startswith('ext'):
-            exec_cmd("{} {} -wR 'rm {}'".format(self.debugfs,
+            cmd = "{} {} -wR 'rm {}'".format(self.debugfs,
                                                 self._get_part_image(pnum),
-                                                path), as_shell=True)
+                                                path)
+            out = exec_cmd(cmd , as_shell=True)
+            for line in out.splitlines():
+                if line.startswith("rm:"):
+                    if "file is a directory" in line:
+                        # Try rmdir to see if this is an empty directory. This won't delete
+                        # any non empty directory so let user know about any error that this might
+                        # generate.
+                        print(exec_cmd("{} {} -wR 'rmdir {}'".format(self.debugfs,
+                                                    self._get_part_image(pnum),
+                                                    path), as_shell=True))
+                    else:
+                        raise WicError("Could not complete operation: wic %s" % str(line))
         else: # fat
             cmd = "{} -i {} ::{}".format(self.mdel, partimg, path)
             try:
@@ -494,7 +511,7 @@
                     sparse_copy(partfname, target, seek=part['start'] * self._lsector_size)
                     os.unlink(partfname)
                 elif part['type'] != 'f':
-                    logger.warn("skipping partition {}: unsupported fstype {}".format(pnum, fstype))
+                    logger.warning("skipping partition {}: unsupported fstype {}".format(pnum, fstype))
 
 def wic_ls(args, native_sysroot):
     """List contents of partitioned image or vfat partition."""
diff --git a/poky/scripts/lib/wic/filemap.py b/poky/scripts/lib/wic/filemap.py
index a72fa09..abbf958 100644
--- a/poky/scripts/lib/wic/filemap.py
+++ b/poky/scripts/lib/wic/filemap.py
@@ -22,6 +22,7 @@
 #   * Too many instance attributes (R0902)
 # pylint: disable=R0902
 
+import errno
 import os
 import struct
 import array
@@ -189,9 +190,9 @@
     except OSError as err:
         # The 'lseek' system call returns the ENXIO if there is no data or
         # hole starting from the specified offset.
-        if err.errno == os.errno.ENXIO:
+        if err.errno == errno.ENXIO:
             return -1
-        elif err.errno == os.errno.EINVAL:
+        elif err.errno == errno.EINVAL:
             raise ErrorNotSupp("the kernel or file-system does not support "
                                "\"SEEK_HOLE\" and \"SEEK_DATA\"")
         else:
@@ -394,12 +395,12 @@
         except IOError as err:
             # Note, the FIEMAP ioctl is supported by the Linux kernel starting
             # from version 2.6.28 (year 2008).
-            if err.errno == os.errno.EOPNOTSUPP:
+            if err.errno == errno.EOPNOTSUPP:
                 errstr = "FilemapFiemap: the FIEMAP ioctl is not supported " \
                          "by the file-system"
                 self._log.debug(errstr)
                 raise ErrorNotSupp(errstr)
-            if err.errno == os.errno.ENOTTY:
+            if err.errno == errno.ENOTTY:
                 errstr = "FilemapFiemap: the FIEMAP ioctl is not supported " \
                          "by the kernel"
                 self._log.debug(errstr)
diff --git a/poky/scripts/lib/wic/help.py b/poky/scripts/lib/wic/help.py
index 842b868..64f0805 100644
--- a/poky/scripts/lib/wic/help.py
+++ b/poky/scripts/lib/wic/help.py
@@ -866,11 +866,11 @@
        Partitions with a <mountpoint> specified will be automatically mounted.
        This is achieved by wic adding entries to the fstab during image
        generation. In order for a valid fstab to be generated one of the
-       --ondrive, --ondisk or --use-uuid partition options must be used for
-       each partition that specifies a mountpoint.  Note that with --use-uuid
-       and non-root <mountpoint>, including swap, the mount program must
-       understand the PARTUUID syntax.  This currently excludes the busybox
-       versions of these applications.
+       --ondrive, --ondisk, --use-uuid or --use-label partition options must
+       be used for each partition that specifies a mountpoint.  Note that with
+       --use-{uuid,label} and non-root <mountpoint>, including swap, the mount
+       program must understand the PARTUUID or LABEL syntax.  This currently
+       excludes the busybox versions of these applications.
 
 
        The following are supported 'part' options:
@@ -945,6 +945,14 @@
                         label is already in use by another filesystem,
                         a new label is created for the partition.
 
+         --use-label: This option is specific to wic. It makes wic to use the
+                      label in /etc/fstab to specify a partition. If the
+                      --use-label and --use-uuid are used at the same time,
+                      we prefer the uuid because it is less likely to cause
+                      name confliction. We don't support using this parameter
+                      on the root partition since it requires an initramfs to
+                      parse this value and we do not currently support that.
+
          --active: Marks the partition as active.
 
          --align (in KBytes): This option is specific to wic and says
diff --git a/poky/scripts/lib/wic/ksparser.py b/poky/scripts/lib/wic/ksparser.py
index e590b2f..7e5a9c5 100644
--- a/poky/scripts/lib/wic/ksparser.py
+++ b/poky/scripts/lib/wic/ksparser.py
@@ -141,6 +141,7 @@
                                    'squashfs', 'vfat', 'msdos', 'swap'))
         part.add_argument('--mkfs-extraopts', default='')
         part.add_argument('--label')
+        part.add_argument('--use-label', action='store_true')
         part.add_argument('--no-table', action='store_true')
         part.add_argument('--ondisk', '--ondrive', dest='disk', default='sda')
         part.add_argument("--overhead-factor", type=overheadtype)
@@ -196,9 +197,18 @@
                         raise KickStartError('%s:%d: %s' % \
                                              (confpath, lineno, err))
                     if line.startswith('part'):
-                        # SquashFS does not support UUID
-                        if parsed.fstype == 'squashfs' and parsed.use_uuid:
-                            err = "%s:%d: SquashFS does not support UUID" \
+                        # SquashFS does not support filesystem UUID
+                        if parsed.fstype == 'squashfs':
+                            if parsed.fsuuid:
+                                err = "%s:%d: SquashFS does not support UUID" \
+                                       % (confpath, lineno)
+                                raise KickStartError(err)
+                            if parsed.label:
+                                err = "%s:%d: SquashFS does not support LABEL" \
+                                       % (confpath, lineno)
+                                raise KickStartError(err)
+                        if parsed.use_label and not parsed.label:
+                            err = "%s:%d: Must set the label with --label" \
                                   % (confpath, lineno)
                             raise KickStartError(err)
                         # using ArgumentParser one cannot easily tell if option
diff --git a/poky/scripts/lib/wic/partition.py b/poky/scripts/lib/wic/partition.py
index 3fe5c4e..3da7e23 100644
--- a/poky/scripts/lib/wic/partition.py
+++ b/poky/scripts/lib/wic/partition.py
@@ -47,6 +47,7 @@
         self.fsopts = args.fsopts
         self.fstype = args.fstype
         self.label = args.label
+        self.use_label = args.use_label
         self.mkfs_extraopts = args.mkfs_extraopts
         self.mountpoint = args.mountpoint
         self.no_table = args.no_table
@@ -66,7 +67,6 @@
 
         self.lineno = lineno
         self.source_file = ""
-        self.sourceparams_dict = {}
 
     def get_extra_block_count(self, current_blocks):
         """
@@ -211,7 +211,7 @@
         """
         p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot)
         p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR",
-                                         "%s/../pseudo" %  get_bitbake_var("IMAGE_ROOTFS"))
+                                         "%s/../pseudo" %  rootfs_dir)
         p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir)
         p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1")
         pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix
diff --git a/poky/scripts/lib/wic/plugins/imager/direct.py b/poky/scripts/lib/wic/plugins/imager/direct.py
index 1fa6b91..bb14a33 100644
--- a/poky/scripts/lib/wic/plugins/imager/direct.py
+++ b/poky/scripts/lib/wic/plugins/imager/direct.py
@@ -122,6 +122,10 @@
         if self._update_fstab(fstab_lines, self.parts):
             # copy rootfs dir to workdir to update fstab
             # as rootfs can be used by other tasks and can't be modified
+            new_pseudo = os.path.realpath(os.path.join(self.workdir, "pseudo"))
+            from_dir = os.path.join(os.path.join(image_rootfs, ".."), "pseudo")
+            from_dir = os.path.realpath(from_dir)
+            copyhardlinktree(from_dir, new_pseudo)
             new_rootfs = os.path.realpath(os.path.join(self.workdir, "rootfs_copy"))
             copyhardlinktree(image_rootfs, new_rootfs)
             fstab_path = os.path.join(new_rootfs, 'etc/fstab')
@@ -151,6 +155,8 @@
                         device_name = "UUID=%s" % part.fsuuid
                 else:
                     device_name = "PARTUUID=%s" % part.uuid
+            elif part.use_label:
+                device_name = "LABEL=%s" % part.label
             else:
                 # mmc device partitions are named mmcblk0p1, mmcblk0p2..
                 prefix = 'p' if  part.disk.startswith('mmcblk') else ''
diff --git a/poky/scripts/lib/wic/plugins/source/bootimg-partition.py b/poky/scripts/lib/wic/plugins/source/bootimg-partition.py
index b239fc0..ddc880b 100644
--- a/poky/scripts/lib/wic/plugins/source/bootimg-partition.py
+++ b/poky/scripts/lib/wic/plugins/source/bootimg-partition.py
@@ -30,6 +30,7 @@
 from glob import glob
 
 from wic import WicError
+from wic.engine import get_custom_config
 from wic.pluginbase import SourcePlugin
 from wic.misc import exec_cmd, get_bitbake_var
 
@@ -44,15 +45,11 @@
     name = 'bootimg-partition'
 
     @classmethod
-    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
+    def do_configure_partition(cls, part, source_params, cr, cr_workdir,
                              oe_builddir, bootimg_dir, kernel_dir,
-                             rootfs_dir, native_sysroot):
+                             native_sysroot):
         """
-        Called to do the actual content population for a partition i.e. it
-        'prepares' the partition to be incorporated into the image.
-        In this case, does the following:
-        - sets up a vfat partition
-        - copies all files listed in IMAGE_BOOT_FILES variable
+        Called before do_prepare_partition(), create u-boot specific boot config
         """
         hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
         install_cmd = "install -d %s" % hdddir
@@ -63,8 +60,6 @@
             if not kernel_dir:
                 raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
 
-        logger.debug('Kernel dir: %s', bootimg_dir)
-
         boot_files = None
         for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)):
             if fmt:
@@ -94,9 +89,9 @@
             logger.debug('Destination entry: %r', dst_entry)
             deploy_files.append(dst_entry)
 
+        cls.install_task = [];
         for deploy_entry in deploy_files:
             src, dst = deploy_entry
-            install_task = []
             if '*' in src:
                 # by default install files under their basename
                 entry_name_fn = os.path.basename
@@ -111,21 +106,101 @@
 
                 logger.debug('Globbed sources: %s', ', '.join(srcs))
                 for entry in srcs:
+                    src = os.path.relpath(entry, kernel_dir)
                     entry_dst_name = entry_name_fn(entry)
-                    install_task.append((entry,
-                                         os.path.join(hdddir,
-                                                      entry_dst_name)))
+                    cls.install_task.append((src, entry_dst_name))
             else:
-                install_task = [(os.path.join(kernel_dir, src),
-                                 os.path.join(hdddir, dst))]
+                cls.install_task.append((src, dst))
 
-            for task in install_task:
-                src_path, dst_path = task
-                logger.debug('Install %s as %s',
-                             os.path.basename(src_path), dst_path)
-                install_cmd = "install -m 0644 -D %s %s" \
-                              % (src_path, dst_path)
-                exec_cmd(install_cmd)
+        if source_params.get('loader') != "u-boot":
+            return
+
+        configfile = cr.ks.bootloader.configfile
+        custom_cfg = None
+        if configfile:
+            custom_cfg = get_custom_config(configfile)
+            if custom_cfg:
+                # Use a custom configuration for extlinux.conf
+                extlinux_conf = custom_cfg
+                logger.debug("Using custom configuration file "
+                             "%s for extlinux.cfg", configfile)
+            else:
+                raise WicError("configfile is specified but failed to "
+                               "get it from %s." % configfile)
+
+        if not custom_cfg:
+            # The kernel types supported by the sysboot of u-boot
+            kernel_types = ["zImage", "Image", "fitImage", "uImage", "vmlinux"]
+            has_dtb = False
+            fdt_dir = '/'
+            kernel_name = None
+
+            # Find the kernel image name, from the highest precedence to lowest
+            for image in kernel_types:
+                for task in cls.install_task:
+                    src, dst = task
+                    if re.match(image, src):
+                        kernel_name = os.path.join('/', dst)
+                        break
+                if kernel_name:
+                    break
+
+            for task in cls.install_task:
+                src, dst = task
+                # We suppose that all the dtb are in the same directory
+                if re.search(r'\.dtb', src) and fdt_dir == '/':
+                    has_dtb = True
+                    fdt_dir = os.path.join(fdt_dir, os.path.dirname(dst))
+                    break
+
+            if not kernel_name:
+                raise WicError('No kernel file founded')
+
+            # Compose the extlinux.conf
+            extlinux_conf = "default Yocto\n"
+            extlinux_conf += "label Yocto\n"
+            extlinux_conf += "   kernel %s\n" % kernel_name
+            if has_dtb:
+                extlinux_conf += "   fdtdir %s\n" % fdt_dir
+            bootloader = cr.ks.bootloader
+            extlinux_conf += "append root=%s rootwait %s\n" \
+                             % (cr.rootdev, bootloader.append if bootloader.append else '')
+
+        install_cmd = "install -d %s/extlinux/" % hdddir
+        exec_cmd(install_cmd)
+        cfg = open("%s/extlinux/extlinux.conf" % hdddir, "w")
+        cfg.write(extlinux_conf)
+        cfg.close()
+
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             rootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        In this case, does the following:
+        - sets up a vfat partition
+        - copies all files listed in IMAGE_BOOT_FILES variable
+        """
+        hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
+
+        if not kernel_dir:
+            kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not kernel_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+
+        logger.debug('Kernel dir: %s', bootimg_dir)
+
+
+        for task in cls.install_task:
+            src_path, dst_path = task
+            logger.debug('Install %s as %s', src_path, dst_path)
+            install_cmd = "install -m 0644 -D %s %s" \
+                          % (os.path.join(kernel_dir, src_path),
+                             os.path.join(hdddir, dst_path))
+            exec_cmd(install_cmd)
 
         logger.debug('Prepare boot partition using rootfs in %s', hdddir)
         part.prepare_rootfs(cr_workdir, oe_builddir, hdddir,
diff --git a/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py b/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py
index d599112..9347aa7 100644
--- a/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py
+++ b/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py
@@ -26,6 +26,7 @@
 
 import logging
 import os
+import re
 
 from wic import WicError
 from wic.engine import get_custom_config
@@ -47,10 +48,17 @@
         """
         Check if dirname exists in default bootimg_dir or in STAGING_DIR.
         """
-        for result in (bootimg_dir, get_bitbake_var("STAGING_DATADIR")):
+        staging_datadir = get_bitbake_var("STAGING_DATADIR")
+        for result in (bootimg_dir, staging_datadir):
             if os.path.exists("%s/%s" % (result, dirname)):
                 return result
 
+        # STAGING_DATADIR is expanded with MLPREFIX if multilib is enabled
+        # but dependency syslinux is still populated to original STAGING_DATADIR
+        nonarch_datadir = re.sub('/[^/]*recipe-sysroot', '/recipe-sysroot', staging_datadir)
+        if os.path.exists(os.path.join(nonarch_datadir, dirname)):
+            return nonarch_datadir
+
         raise WicError("Couldn't find correct bootimg_dir, exiting")
 
     @classmethod
diff --git a/poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py b/poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
index b119c9c..170077c 100644
--- a/poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
+++ b/poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
@@ -47,7 +47,7 @@
 
     Example kickstart file:
     part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\
-    image_name= IsoImage" --ondisk cd --label LIVECD --fstype=ext2
+    image_name= IsoImage" --ondisk cd --label LIVECD
     bootloader  --timeout=10  --append=" "
 
     In --sourceparams "loader" specifies the bootloader used for booting in EFI
@@ -191,10 +191,9 @@
             else:
                 raise WicError("Couldn't find or build initrd, exiting.")
 
-            exec_cmd("cd %s && find . | cpio -o -H newc -R +0:+0 >./initrd.cpio " \
-                    % initrd_dir, as_shell=True)
-            exec_cmd("gzip -f -9 -c %s/initrd.cpio > %s" \
-                    % (cr_workdir, initrd), as_shell=True)
+            exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \
+                     % (initrd_dir, cr_workdir), as_shell=True)
+            exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True)
             shutil.rmtree(initrd_dir)
 
         return initrd
@@ -253,33 +252,8 @@
             raise WicError("Couldn't find IMAGE_ROOTFS, exiting.")
 
         part.rootfs_dir = rootfs_dir
-
-        # Prepare rootfs.img
         deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
         img_iso_dir = get_bitbake_var("ISODIR")
-        rootfs_img = "%s/rootfs.img" % img_iso_dir
-        if not os.path.isfile(rootfs_img):
-            # check if rootfs.img is in deploydir
-            deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
-            image_name = get_bitbake_var("IMAGE_LINK_NAME")
-            rootfs_img = "%s/%s.%s" \
-                % (deploy_dir, image_name, part.fstype)
-
-        if not os.path.isfile(rootfs_img):
-            # create image file with type specified by --fstype
-            # which contains rootfs
-            du_cmd = "du -bks %s" % rootfs_dir
-            out = exec_cmd(du_cmd)
-            part.size = int(out.split()[0])
-            part.extra_space = 0
-            part.overhead_factor = 1.2
-            part.prepare_rootfs(cr_workdir, oe_builddir, rootfs_dir, \
-                                native_sysroot)
-            rootfs_img = part.source_file
-
-        install_cmd = "install -m 0644 %s %s/rootfs.img" \
-            % (rootfs_img, isodir)
-        exec_cmd(install_cmd)
 
         # Remove the temporary file created by part.prepare_rootfs()
         if os.path.isfile(part.source_file):
@@ -342,7 +316,7 @@
                     grub_src = os.path.join(deploy_dir, grub_src_image)
                     if not os.path.exists(grub_src):
                         raise WicError("Grub loader %s is not found in %s. "
-                                       "Please build grub-efi first" % (grub_image, deploy_dir))
+                                       "Please build grub-efi first" % (grub_src_image, deploy_dir))
                     shutil.copy(grub_src, grub_target)
 
                 if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):