#!/usr/bin/env python3

# Handle running OE images standalone with QEMU
#
# Copyright (C) 2006-2011 Linux Foundation
# Copyright (c) 2016 Wind River Systems, Inc.
#
# 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 os
import sys
import logging
import subprocess
import re
import fcntl
import shutil
import glob
import configparser
import signal

class RunQemuError(Exception):
    """Custom exception to raise on known errors."""
    pass

class OEPathError(RunQemuError):
    """Custom Exception to give better guidance on missing binaries"""
    def __init__(self, message):
        super().__init__("In order for this script to dynamically infer paths\n \
kernels or filesystem images, you either need bitbake in your PATH\n \
or to source oe-init-build-env before running this script.\n\n \
Dynamic path inference can be avoided by passing a *.qemuboot.conf to\n \
runqemu, i.e. `runqemu /path/to/my-image-name.qemuboot.conf`\n\n %s" % message)


def create_logger():
    logger = logging.getLogger('runqemu')
    logger.setLevel(logging.INFO)

    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)

    # create formatter
    formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')

    # add formatter to ch
    ch.setFormatter(formatter)

    # add ch to logger
    logger.addHandler(ch)

    return logger

logger = create_logger()

def print_usage():
    print("""
Usage: you can run this script with any valid combination
of the following environment variables (in any order):
  KERNEL - the kernel image file to use
  ROOTFS - the rootfs image file or nfsroot directory to use
  DEVICE_TREE - the device tree blob to use
  MACHINE - the machine name (optional, autodetected from KERNEL filename if unspecified)
  Simplified QEMU command-line options can be passed with:
    nographic - disable video console
    serial - enable a serial console on /dev/ttyS0
    slirp - enable user networking, no root privileges is required
    kvm - enable KVM when running x86/x86_64 (VT-capable CPU required)
    kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required)
    publicvnc - enable a VNC server open to all hosts
    audio - enable audio
    [*/]ovmf* - OVMF firmware file or base name for booting with UEFI
  tcpserial=<port> - specify tcp serial port number
  biosdir=<dir> - specify custom bios dir
  biosfilename=<filename> - specify bios filename
  qemuparams=<xyz> - specify custom parameters to QEMU
  bootparams=<xyz> - specify custom kernel parameters during boot
  help, -h, --help: print this text
  -d, --debug: Enable debug output
  -q, --quite: Hide most output except error messages

Examples:
  runqemu
  runqemu qemuarm
  runqemu tmp/deploy/images/qemuarm
  runqemu tmp/deploy/images/qemux86/<qemuboot.conf>
  runqemu qemux86-64 core-image-sato ext4
  runqemu qemux86-64 wic-image-minimal wic
  runqemu path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial
  runqemu qemux86 iso/hddimg/wic.vmdk/wic.qcow2/wic.vdi/ramfs/cpio.gz...
  runqemu qemux86 qemuparams="-m 256"
  runqemu qemux86 bootparams="psplash=false"
  runqemu path/to/<image>-<machine>.wic
  runqemu path/to/<image>-<machine>.wic.vmdk
""")

def check_tun():
    """Check /dev/net/tun"""
    dev_tun = '/dev/net/tun'
    if not os.path.exists(dev_tun):
        raise RunQemuError("TUN control device %s is unavailable; you may need to enable TUN (e.g. sudo modprobe tun)" % dev_tun)

    if not os.access(dev_tun, os.W_OK):
        raise RunQemuError("TUN control device %s is not writable, please fix (e.g. sudo chmod 666 %s)" % (dev_tun, dev_tun))

def check_libgl(qemu_bin):
    cmd = 'ldd %s' % qemu_bin
    logger.debug('Running %s...' % cmd)
    need_gl = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
    if re.search('libGLU', need_gl):
        # We can't run without a libGL.so
        libgl = False
        check_files = (('/usr/lib/libGL.so', '/usr/lib/libGLU.so'), \
            ('/usr/lib64/libGL.so', '/usr/lib64/libGLU.so'), \
            ('/usr/lib/*-linux-gnu/libGL.so', '/usr/lib/*-linux-gnu/libGLU.so'))

        for (f1, f2) in check_files:
            if re.search('\*', f1):
                for g1 in glob.glob(f1):
                    if libgl:
                        break
                    if os.path.exists(g1):
                        for g2 in glob.glob(f2):
                            if os.path.exists(g2):
                                libgl = True
                                break
                if libgl:
                    break
            else:
                if os.path.exists(f1) and os.path.exists(f2):
                    libgl = True
                    break
        if not libgl:
            logger.error("You need libGL.so and libGLU.so to exist in your library path to run the QEMU emulator.")
            logger.error("Ubuntu package names are: libgl1-mesa-dev and libglu1-mesa-dev.")
            logger.error("Fedora package names are: mesa-libGL-devel mesa-libGLU-devel.")
            raise RunQemuError('%s requires libGLU, but not found' % qemu_bin)

def get_first_file(cmds):
    """Return first file found in wildcard cmds"""
    for cmd in cmds:
        all_files = glob.glob(cmd)
        if all_files:
            for f in all_files:
                if not os.path.isdir(f):
                    return f
    return ''

def check_free_port(host, port):
    """ Check whether the port is free or not """
    import socket
    from contextlib import closing

    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        if sock.connect_ex((host, port)) == 0:
            # Port is open, so not free
            return False
        else:
            # Port is not open, so free
            return True

class BaseConfig(object):
    def __init__(self):
        # The self.d saved vars from self.set(), part of them are from qemuboot.conf
        self.d = {'QB_KERNEL_ROOT': '/dev/vda'}

        # Supported env vars, add it here if a var can be got from env,
        # and don't use os.getenv in the code.
        self.env_vars = ('MACHINE',
                        'ROOTFS',
                        'KERNEL',
                        'DEVICE_TREE',
                        'DEPLOY_DIR_IMAGE',
                        'OE_TMPDIR',
                        'OECORE_NATIVE_SYSROOT',
                        )

        self.qemu_opt = ''
        self.qemu_opt_script = ''
        self.clean_nfs_dir = False
        self.nfs_server = ''
        self.rootfs = ''
        # File name(s) of a OVMF firmware file or variable store,
        # to be added with -drive if=pflash.
        # Found in the same places as the rootfs, with or without one of
        # these suffices: qcow2, bin.
        # Setting one also adds "-vga std" because that is all that
        # OVMF supports.
        self.ovmf_bios = []
        self.qemuboot = ''
        self.qbconfload = False
        self.kernel = ''
        self.kernel_cmdline = ''
        self.kernel_cmdline_script = ''
        self.bootparams = ''
        self.dtb = ''
        self.fstype = ''
        self.kvm_enabled = False
        self.vhost_enabled = False
        self.slirp_enabled = False
        self.nfs_instance = 0
        self.nfs_running = False
        self.serialstdio = False
        self.cleantap = False
        self.saved_stty = ''
        self.audio_enabled = False
        self.tcpserial_portnum = ''
        self.custombiosdir = ''
        self.lock = ''
        self.lock_descriptor = None
        self.bitbake_e = ''
        self.snapshot = False
        self.fstypes = ('ext2', 'ext3', 'ext4', 'jffs2', 'nfs', 'btrfs',
                        'cpio.gz', 'cpio', 'ramfs', 'tar.bz2', 'tar.gz')
        self.vmtypes = ('hddimg', 'hdddirect', 'wic', 'wic.vmdk',
                        'wic.qcow2', 'wic.vdi', 'iso')
        self.network_device = "-device e1000,netdev=net0,mac=@MAC@"
        # Use different mac section for tap and slirp to avoid
        # conflicts, e.g., when one is running with tap, the other is
        # running with slirp.
        # The last section is dynamic, which is for avoiding conflicts,
        # when multiple qemus are running, e.g., when multiple tap or
        # slirp qemus are running.
        self.mac_tap = "52:54:00:12:34:"
        self.mac_slirp = "52:54:00:12:35:"
        # pid of the actual qemu process
        self.qemupid = None
        # avoid cleanup twice
        self.cleaned = False

    def acquire_lock(self, error=True):
        logger.debug("Acquiring lockfile %s..." % self.lock)
        try:
            self.lock_descriptor = open(self.lock, 'w')
            fcntl.flock(self.lock_descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)
        except Exception as e:
            msg = "Acquiring lockfile %s failed: %s" % (self.lock, e)
            if error:
                logger.error(msg)
            else:
                logger.info(msg)
            if self.lock_descriptor:
                self.lock_descriptor.close()
                self.lock_descriptor = None
            return False
        return True

    def release_lock(self):
        if self.lock_descriptor:
            logger.debug("Releasing lockfile for tap device '%s'" % self.tap)
            fcntl.flock(self.lock_descriptor, fcntl.LOCK_UN)
            self.lock_descriptor.close()
            os.remove(self.lock)
            self.lock_descriptor = None

    def get(self, key):
        if key in self.d:
            return self.d.get(key)
        elif os.getenv(key):
            return os.getenv(key)
        else:
            return ''

    def set(self, key, value):
        self.d[key] = value

    def is_deploy_dir_image(self, p):
        if os.path.isdir(p):
            if not re.search('.qemuboot.conf$', '\n'.join(os.listdir(p)), re.M):
                logger.debug("Can't find required *.qemuboot.conf in %s" % p)
                return False
            if not any(map(lambda name: '-image-' in name, os.listdir(p))):
                logger.debug("Can't find *-image-* in %s" % p)
                return False
            return True
        else:
            return False

    def check_arg_fstype(self, fst):
        """Check and set FSTYPE"""
        if fst not in self.fstypes + self.vmtypes:
            logger.warning("Maybe unsupported FSTYPE: %s" % fst)
        if not self.fstype or self.fstype == fst:
            if fst == 'ramfs':
                fst = 'cpio.gz'
            if fst in ('tar.bz2', 'tar.gz'):
                fst = 'nfs'
            self.fstype = fst
        else:
            raise RunQemuError("Conflicting: FSTYPE %s and %s" % (self.fstype, fst))

    def set_machine_deploy_dir(self, machine, deploy_dir_image):
        """Set MACHINE and DEPLOY_DIR_IMAGE"""
        logger.debug('MACHINE: %s' % machine)
        self.set("MACHINE", machine)
        logger.debug('DEPLOY_DIR_IMAGE: %s' % deploy_dir_image)
        self.set("DEPLOY_DIR_IMAGE", deploy_dir_image)

    def check_arg_nfs(self, p):
        if os.path.isdir(p):
            self.rootfs = p
        else:
            m = re.match('(.*):(.*)', p)
            self.nfs_server = m.group(1)
            self.rootfs = m.group(2)
        self.check_arg_fstype('nfs')

    def check_arg_path(self, p):
        """
        - Check whether it is <image>.qemuboot.conf or contains <image>.qemuboot.conf
        - Check whether is a kernel file
        - Check whether is a image file
        - Check whether it is a nfs dir
        - Check whether it is a OVMF flash file
        """
        if p.endswith('.qemuboot.conf'):
            self.qemuboot = p
            self.qbconfload = True
        elif re.search('\.bin$', p) or re.search('bzImage', p) or \
             re.search('zImage', p) or re.search('vmlinux', p) or \
             re.search('fitImage', p) or re.search('uImage', p):
            self.kernel =  p
        elif os.path.exists(p) and (not os.path.isdir(p)) and '-image-' in os.path.basename(p):
            self.rootfs = p
            # Check filename against self.fstypes can hanlde <file>.cpio.gz,
            # otherwise, its type would be "gz", which is incorrect.
            fst = ""
            for t in self.fstypes:
                if p.endswith(t):
                    fst = t
                    break
            if not fst:
                m = re.search('.*\.(.*)$', self.rootfs)
                if m:
                    fst =  m.group(1)
            if fst:
                self.check_arg_fstype(fst)
                qb = re.sub('\.' + fst + "$", '', self.rootfs)
                qb = '%s%s' % (re.sub('\.rootfs$', '', qb), '.qemuboot.conf')
                if os.path.exists(qb):
                    self.qemuboot = qb
                    self.qbconfload = True
                else:
                    logger.warning("%s doesn't exist" % qb)
            else:
                raise RunQemuError("Can't find FSTYPE from: %s" % p)

        elif os.path.isdir(p) or re.search(':', p) and re.search('/', p):
            if self.is_deploy_dir_image(p):
                logger.debug('DEPLOY_DIR_IMAGE: %s' % p)
                self.set("DEPLOY_DIR_IMAGE", p)
            else:
                logger.debug("Assuming %s is an nfs rootfs" % p)
                self.check_arg_nfs(p)
        elif os.path.basename(p).startswith('ovmf'):
            self.ovmf_bios.append(p)
        else:
            raise RunQemuError("Unknown path arg %s" % p)

    def check_arg_machine(self, arg):
        """Check whether it is a machine"""
        if self.get('MACHINE') == arg:
            return
        elif self.get('MACHINE') and self.get('MACHINE') != arg:
            raise RunQemuError("Maybe conflicted MACHINE: %s vs %s" % (self.get('MACHINE'), arg))
        elif re.search('/', arg):
            raise RunQemuError("Unknown arg: %s" % arg)

        logger.debug('Assuming MACHINE = %s' % arg)

        # if we're running under testimage, or similarly as a child
        # of an existing bitbake invocation, we can't invoke bitbake
        # to validate the MACHINE setting and must assume it's correct...
        # FIXME: testimage.bbclass exports these two variables into env,
        # are there other scenarios in which we need to support being
        # invoked by bitbake?
        deploy = self.get('DEPLOY_DIR_IMAGE')
        bbchild = deploy and self.get('OE_TMPDIR')
        if bbchild:
            self.set_machine_deploy_dir(arg, deploy)
            return
        # also check whether we're running under a sourced toolchain
        # environment file
        if self.get('OECORE_NATIVE_SYSROOT'):
            self.set("MACHINE", arg)
            return

        cmd = 'MACHINE=%s bitbake -e' % arg
        logger.info('Running %s...' % cmd)
        self.bitbake_e = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
        # bitbake -e doesn't report invalid MACHINE as an error, so
        # let's check DEPLOY_DIR_IMAGE to make sure that it is a valid
        # MACHINE.
        s = re.search('^DEPLOY_DIR_IMAGE="(.*)"', self.bitbake_e, re.M)
        if s:
            deploy_dir_image = s.group(1)
        else:
            raise RunQemuError("bitbake -e %s" % self.bitbake_e)
        if self.is_deploy_dir_image(deploy_dir_image):
            self.set_machine_deploy_dir(arg, deploy_dir_image)
        else:
            logger.error("%s not a directory valid DEPLOY_DIR_IMAGE" % deploy_dir_image)
            self.set("MACHINE", arg)

    def check_args(self):
        for debug in ("-d", "--debug"):
            if debug in sys.argv:
                logger.setLevel(logging.DEBUG)
                sys.argv.remove(debug)

        for quiet in ("-q", "--quiet"):
            if quiet in sys.argv:
                logger.setLevel(logging.ERROR)
                sys.argv.remove(quiet)

        unknown_arg = ""
        for arg in sys.argv[1:]:
            if arg in self.fstypes + self.vmtypes:
                self.check_arg_fstype(arg)
            elif arg == 'nographic':
                self.qemu_opt_script += ' -nographic'
                self.kernel_cmdline_script += ' console=ttyS0'
            elif arg == 'serial':
                self.kernel_cmdline_script += ' console=ttyS0'
                self.serialstdio = True
            elif arg == 'audio':
                logger.info("Enabling audio in qemu")
                logger.info("Please install sound drivers in linux host")
                self.audio_enabled = True
            elif arg == 'kvm':
                self.kvm_enabled = True
            elif arg == 'kvm-vhost':
                self.vhost_enabled = True
            elif arg == 'slirp':
                self.slirp_enabled = True
            elif arg == 'snapshot':
                self.snapshot = True
            elif arg == 'publicvnc':
                self.qemu_opt_script += ' -vnc :0'
            elif arg.startswith('tcpserial='):
                self.tcpserial_portnum = arg[len('tcpserial='):]
            elif arg.startswith('biosdir='):
                self.custombiosdir = arg[len('biosdir='):]
            elif arg.startswith('biosfilename='):
                self.qemu_opt_script += ' -bios %s' % arg[len('biosfilename='):]
            elif arg.startswith('qemuparams='):
                self.qemu_opt_script += ' %s' % arg[len('qemuparams='):]
            elif arg.startswith('bootparams='):
                self.bootparams = arg[len('bootparams='):]
            elif os.path.exists(arg) or (re.search(':', arg) and re.search('/', arg)):
                self.check_arg_path(os.path.abspath(arg))
            elif re.search(r'-image-|-image$', arg):
                # Lazy rootfs
                self.rootfs = arg
            elif arg.startswith('ovmf'):
                self.ovmf_bios.append(arg)
            else:
                # At last, assume it is the MACHINE
                if (not unknown_arg) or unknown_arg == arg:
                    unknown_arg = arg
                else:
                    raise RunQemuError("Can't handle two unknown args: %s %s\n"
                                       "Try 'runqemu help' on how to use it" % \
                                        (unknown_arg, arg))
        # Check to make sure it is a valid machine
        if unknown_arg and self.get('MACHINE') != unknown_arg:
            if self.get('DEPLOY_DIR_IMAGE'):
                machine = os.path.basename(self.get('DEPLOY_DIR_IMAGE'))
                if unknown_arg == machine:
                    self.set("MACHINE", machine)

            self.check_arg_machine(unknown_arg)

        if not (self.get('DEPLOY_DIR_IMAGE') or self.qbconfload):
            self.load_bitbake_env()
            s = re.search('^DEPLOY_DIR_IMAGE="(.*)"', self.bitbake_e, re.M)
            if s:
                self.set("DEPLOY_DIR_IMAGE", s.group(1))

    def check_kvm(self):
        """Check kvm and kvm-host"""
        if not (self.kvm_enabled or self.vhost_enabled):
            self.qemu_opt_script += ' %s %s' % (self.get('QB_MACHINE'), self.get('QB_CPU'))
            return

        if not self.get('QB_CPU_KVM'):
            raise RunQemuError("QB_CPU_KVM is NULL, this board doesn't support kvm")

        self.qemu_opt_script += ' %s %s' % (self.get('QB_MACHINE'), self.get('QB_CPU_KVM'))
        yocto_kvm_wiki = "https://wiki.yoctoproject.org/wiki/How_to_enable_KVM_for_Poky_qemu"
        yocto_paravirt_kvm_wiki = "https://wiki.yoctoproject.org/wiki/Running_an_x86_Yocto_Linux_image_under_QEMU_KVM"
        dev_kvm = '/dev/kvm'
        dev_vhost = '/dev/vhost-net'
        with open('/proc/cpuinfo', 'r') as f:
            kvm_cap = re.search('vmx|svm', "".join(f.readlines()))
        if not kvm_cap:
            logger.error("You are trying to enable KVM on a cpu without VT support.")
            logger.error("Remove kvm from the command-line, or refer:")
            raise RunQemuError(yocto_kvm_wiki)

        if not os.path.exists(dev_kvm):
            logger.error("Missing KVM device. Have you inserted kvm modules?")
            logger.error("For further help see:")
            raise RunQemuError(yocto_kvm_wiki)

        if os.access(dev_kvm, os.W_OK|os.R_OK):
            self.qemu_opt_script += ' -enable-kvm'
            if self.get('MACHINE') == "qemux86":
                # Workaround for broken APIC window on pre 4.15 host kernels which causes boot hangs
                # See YOCTO #12301
                # On 64 bit we use x2apic
                self.kernel_cmdline_script += " clocksource=kvm-clock hpet=disable noapic nolapic"
        else:
            logger.error("You have no read or write permission on /dev/kvm.")
            logger.error("Please change the ownership of this file as described at:")
            raise RunQemuError(yocto_kvm_wiki)

        if self.vhost_enabled:
            if not os.path.exists(dev_vhost):
                logger.error("Missing virtio net device. Have you inserted vhost-net module?")
                logger.error("For further help see:")
                raise RunQemuError(yocto_paravirt_kvm_wiki)

        if not os.access(dev_kvm, os.W_OK|os.R_OK):
                logger.error("You have no read or write permission on /dev/vhost-net.")
                logger.error("Please change the ownership of this file as described at:")
                raise RunQemuError(yocto_kvm_wiki)

    def check_fstype(self):
        """Check and setup FSTYPE"""
        if not self.fstype:
            fstype = self.get('QB_DEFAULT_FSTYPE')
            if fstype:
                self.fstype = fstype
            else:
                raise RunQemuError("FSTYPE is NULL!")

    def check_rootfs(self):
        """Check and set rootfs"""

        if self.fstype == "none":
            return

        if self.get('ROOTFS'):
            if not self.rootfs:
                self.rootfs = self.get('ROOTFS')
            elif self.get('ROOTFS') != self.rootfs:
                raise RunQemuError("Maybe conflicted ROOTFS: %s vs %s" % (self.get('ROOTFS'), self.rootfs))

        if self.fstype == 'nfs':
            return

        if self.rootfs and not os.path.exists(self.rootfs):
            # Lazy rootfs
            self.rootfs = "%s/%s-%s.%s" % (self.get('DEPLOY_DIR_IMAGE'),
                    self.rootfs, self.get('MACHINE'),
                    self.fstype)
        elif not self.rootfs:
            cmd_name = '%s/%s*.%s' % (self.get('DEPLOY_DIR_IMAGE'), self.get('IMAGE_NAME'), self.fstype)
            cmd_link = '%s/%s*.%s' % (self.get('DEPLOY_DIR_IMAGE'), self.get('IMAGE_LINK_NAME'), self.fstype)
            cmds = (cmd_name, cmd_link)
            self.rootfs = get_first_file(cmds)
            if not self.rootfs:
                raise RunQemuError("Failed to find rootfs: %s or %s" % cmds)

        if not os.path.exists(self.rootfs):
            raise RunQemuError("Can't find rootfs: %s" % self.rootfs)

    def check_ovmf(self):
        """Check and set full path for OVMF firmware and variable file(s)."""

        for index, ovmf in enumerate(self.ovmf_bios):
            if os.path.exists(ovmf):
                continue
            for suffix in ('qcow2', 'bin'):
                path = '%s/%s.%s' % (self.get('DEPLOY_DIR_IMAGE'), ovmf, suffix)
                if os.path.exists(path):
                    self.ovmf_bios[index] = path
                    break
            else:
                raise RunQemuError("Can't find OVMF firmware: %s" % ovmf)

    def check_kernel(self):
        """Check and set kernel"""
        # The vm image doesn't need a kernel
        if self.fstype in self.vmtypes:
            return

        # See if the user supplied a KERNEL option
        if self.get('KERNEL'):
            self.kernel = self.get('KERNEL')

        # QB_DEFAULT_KERNEL is always a full file path
        kernel_name = os.path.basename(self.get('QB_DEFAULT_KERNEL'))

        # The user didn't want a kernel to be loaded
        if kernel_name == "none" and not self.kernel:
            return

        deploy_dir_image = self.get('DEPLOY_DIR_IMAGE')
        if not self.kernel:
            kernel_match_name = "%s/%s" % (deploy_dir_image, kernel_name)
            kernel_match_link = "%s/%s" % (deploy_dir_image, self.get('KERNEL_IMAGETYPE'))
            kernel_startswith = "%s/%s*" % (deploy_dir_image, self.get('KERNEL_IMAGETYPE'))
            cmds = (kernel_match_name, kernel_match_link, kernel_startswith)
            self.kernel = get_first_file(cmds)
            if not self.kernel:
                raise RunQemuError('KERNEL not found: %s, %s or %s' % cmds)

        if not os.path.exists(self.kernel):
            raise RunQemuError("KERNEL %s not found" % self.kernel)

    def check_dtb(self):
        """Check and set dtb"""
        # Did the user specify a device tree?
        if self.get('DEVICE_TREE'):
            self.dtb = self.get('DEVICE_TREE')
            if not os.path.exists(self.dtb):
                raise RunQemuError('Specified DTB not found: %s' % self.dtb)
            return

        dtb = self.get('QB_DTB')
        if dtb:
            deploy_dir_image = self.get('DEPLOY_DIR_IMAGE')
            cmd_match = "%s/%s" % (deploy_dir_image, dtb)
            cmd_startswith = "%s/%s*" % (deploy_dir_image, dtb)
            cmd_wild = "%s/*.dtb" % deploy_dir_image
            cmds = (cmd_match, cmd_startswith, cmd_wild)
            self.dtb = get_first_file(cmds)
            if not os.path.exists(self.dtb):
                raise RunQemuError('DTB not found: %s, %s or %s' % cmds)

    def check_biosdir(self):
        """Check custombiosdir"""
        if not self.custombiosdir:
            return

        biosdir = ""
        biosdir_native = "%s/%s" % (self.get('STAGING_DIR_NATIVE'), self.custombiosdir)
        biosdir_host = "%s/%s" % (self.get('STAGING_DIR_HOST'), self.custombiosdir)
        for i in (self.custombiosdir, biosdir_native, biosdir_host):
            if os.path.isdir(i):
                biosdir = i
                break

        if biosdir:
            logger.debug("Assuming biosdir is: %s" % biosdir)
            self.qemu_opt_script += ' -L %s' % biosdir
        else:
            logger.error("Custom BIOS directory not found. Tried: %s, %s, and %s" % (self.custombiosdir, biosdir_native, biosdir_host))
            raise RunQemuError("Invalid custombiosdir: %s" % self.custombiosdir)

    def check_mem(self):
        s = re.search('-m +([0-9]+)', self.qemu_opt_script)
        if s:
            self.set('QB_MEM', '-m %s' % s.group(1))
        elif not self.get('QB_MEM'):
            logger.info('QB_MEM is not set, use 512M by default')
            self.set('QB_MEM', '-m 512')

        mach = self.get('MACHINE')
        if not mach.startswith('qemumips'):
            self.kernel_cmdline_script += ' mem=%s' % self.get('QB_MEM').replace('-m','').strip() + 'M'

        self.qemu_opt_script += ' %s' % self.get('QB_MEM')

    def check_tcpserial(self):
        if self.tcpserial_portnum:
            if self.get('QB_TCPSERIAL_OPT'):
                self.qemu_opt_script += ' ' + self.get('QB_TCPSERIAL_OPT').replace('@PORT@', self.tcpserial_portnum)
            else:
                self.qemu_opt_script += ' -serial tcp:127.0.0.1:%s' % self.tcpserial_portnum

    def check_and_set(self):
        """Check configs sanity and set when needed"""
        self.validate_paths()
        if not self.slirp_enabled:
            check_tun()
        # Check audio
        if self.audio_enabled:
            if not self.get('QB_AUDIO_DRV'):
                raise RunQemuError("QB_AUDIO_DRV is NULL, this board doesn't support audio")
            if not self.get('QB_AUDIO_OPT'):
                logger.warning('QB_AUDIO_OPT is NULL, you may need define it to make audio work')
            else:
                self.qemu_opt_script += ' %s' % self.get('QB_AUDIO_OPT')
            os.putenv('QEMU_AUDIO_DRV', self.get('QB_AUDIO_DRV'))
        else:
            os.putenv('QEMU_AUDIO_DRV', 'none')

        self.check_kvm()
        self.check_fstype()
        self.check_rootfs()
        self.check_ovmf()
        self.check_kernel()
        self.check_dtb()
        self.check_biosdir()
        self.check_mem()
        self.check_tcpserial()

    def read_qemuboot(self):
        if not self.qemuboot:
            if self.get('DEPLOY_DIR_IMAGE'):
                deploy_dir_image = self.get('DEPLOY_DIR_IMAGE')
            else:
                logger.warning("Can't find qemuboot conf file, DEPLOY_DIR_IMAGE is NULL!")
                return

            if self.rootfs and not os.path.exists(self.rootfs):
                # Lazy rootfs
                machine = self.get('MACHINE')
                if not machine:
                    machine = os.path.basename(deploy_dir_image)
                self.qemuboot = "%s/%s-%s.qemuboot.conf" % (deploy_dir_image,
                        self.rootfs, machine)
            else:
                cmd = 'ls -t %s/*.qemuboot.conf' %  deploy_dir_image
                logger.debug('Running %s...' % cmd)
                try:
                    qbs = subprocess.check_output(cmd, shell=True).decode('utf-8')
                except subprocess.CalledProcessError as err:
                    raise RunQemuError(err)
                if qbs:
                    for qb in qbs.split():
                        # Don't use initramfs when other choices unless fstype is ramfs
                        if '-initramfs-' in os.path.basename(qb) and self.fstype != 'cpio.gz':
                                continue
                        self.qemuboot = qb
                        break
                    if not self.qemuboot:
                        # Use the first one when no choice
                        self.qemuboot = qbs.split()[0]
                    self.qbconfload = True

        if not self.qemuboot:
            # If we haven't found a .qemuboot.conf at this point it probably
            # doesn't exist, continue without
            return

        if not os.path.exists(self.qemuboot):
            raise RunQemuError("Failed to find %s (wrong image name or BSP does not support running under qemu?)." % self.qemuboot)

        logger.debug('CONFFILE: %s' % self.qemuboot)

        cf = configparser.ConfigParser()
        cf.read(self.qemuboot)
        for k, v in cf.items('config_bsp'):
            k_upper = k.upper()
            if v.startswith("../"):
                v = os.path.abspath(os.path.dirname(self.qemuboot) + "/" + v)
            elif v == ".":
                v = os.path.dirname(self.qemuboot)
            self.set(k_upper, v)

    def validate_paths(self):
        """Ensure all relevant path variables are set"""
        # When we're started with a *.qemuboot.conf arg assume that image
        # artefacts are relative to that file, rather than in whatever
        # directory DEPLOY_DIR_IMAGE in the conf file points to.
        if self.qbconfload:
            imgdir = os.path.realpath(os.path.dirname(self.qemuboot))
            if imgdir != os.path.realpath(self.get('DEPLOY_DIR_IMAGE')):
                logger.info('Setting DEPLOY_DIR_IMAGE to folder containing %s (%s)' % (self.qemuboot, imgdir))
                self.set('DEPLOY_DIR_IMAGE', imgdir)

        # If the STAGING_*_NATIVE directories from the config file don't exist
        # and we're in a sourced OE build directory try to extract the paths
        # from `bitbake -e`
        havenative = os.path.exists(self.get('STAGING_DIR_NATIVE')) and \
            os.path.exists(self.get('STAGING_BINDIR_NATIVE'))

        if not havenative:
            if not self.bitbake_e:
                self.load_bitbake_env()

            if self.bitbake_e:
                native_vars = ['STAGING_DIR_NATIVE']
                for nv in native_vars:
                    s = re.search('^%s="(.*)"' % nv, self.bitbake_e, re.M)
                    if s and s.group(1) != self.get(nv):
                        logger.info('Overriding conf file setting of %s to %s from Bitbake environment' % (nv, s.group(1)))
                        self.set(nv, s.group(1))
            else:
                # when we're invoked from a running bitbake instance we won't
                # be able to call `bitbake -e`, then try:
                # - get OE_TMPDIR from environment and guess paths based on it
                # - get OECORE_NATIVE_SYSROOT from environment (for sdk)
                tmpdir = self.get('OE_TMPDIR')
                oecore_native_sysroot = self.get('OECORE_NATIVE_SYSROOT')
                if tmpdir:
                    logger.info('Setting STAGING_DIR_NATIVE and STAGING_BINDIR_NATIVE relative to OE_TMPDIR (%s)' % tmpdir)
                    hostos, _, _, _, machine = os.uname()
                    buildsys = '%s-%s' % (machine, hostos.lower())
                    staging_dir_native = '%s/sysroots/%s' % (tmpdir, buildsys)
                    self.set('STAGING_DIR_NATIVE', staging_dir_native)
                elif oecore_native_sysroot:
                    logger.info('Setting STAGING_DIR_NATIVE to OECORE_NATIVE_SYSROOT (%s)' % oecore_native_sysroot)
                    self.set('STAGING_DIR_NATIVE', oecore_native_sysroot)
                if self.get('STAGING_DIR_NATIVE'):
                    # we have to assume that STAGING_BINDIR_NATIVE is at usr/bin
                    staging_bindir_native = '%s/usr/bin' % self.get('STAGING_DIR_NATIVE')
                    logger.info('Setting STAGING_BINDIR_NATIVE to %s' % staging_bindir_native)
                    self.set('STAGING_BINDIR_NATIVE', '%s/usr/bin' % self.get('STAGING_DIR_NATIVE'))

    def print_config(self):
        logger.info('Continuing with the following parameters:\n')
        if not self.fstype in self.vmtypes:
            print('KERNEL: [%s]' % self.kernel)
            if self.dtb:
                print('DTB: [%s]' % self.dtb)
        print('MACHINE: [%s]' % self.get('MACHINE'))
        print('FSTYPE: [%s]' % self.fstype)
        if self.fstype  == 'nfs':
            print('NFS_DIR: [%s]' % self.rootfs)
        else:
            print('ROOTFS: [%s]' % self.rootfs)
        if self.ovmf_bios:
            print('OVMF: %s' % self.ovmf_bios)
        print('CONFFILE: [%s]' % self.qemuboot)
        print('')

    def setup_nfs(self):
        if not self.nfs_server:
            if self.slirp_enabled:
                self.nfs_server = '10.0.2.2'
            else:
                self.nfs_server = '192.168.7.1'

        # Figure out a new nfs_instance to allow multiple qemus running.
        # CentOS 7.1's ps doesn't print full command line without "ww"
        # when invoke by subprocess.Popen().
        cmd = "ps auxww"
        ps = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
        pattern = '/bin/unfsd .* -i .*\.pid -e .*/exports([0-9]+) '
        all_instances = re.findall(pattern, ps, re.M)
        if all_instances:
            all_instances.sort(key=int)
            self.nfs_instance = int(all_instances.pop()) + 1

        nfsd_port = 3049 + 2 * self.nfs_instance
        mountd_port = 3048 + 2 * self.nfs_instance

        # Export vars for runqemu-export-rootfs
        export_dict = {
            'NFS_INSTANCE': self.nfs_instance,
            'NFSD_PORT': nfsd_port,
            'MOUNTD_PORT': mountd_port,
        }
        for k, v in export_dict.items():
            # Use '%s' since they are integers
            os.putenv(k, '%s' % v)

        self.unfs_opts="nfsvers=3,port=%s,udp,mountport=%s" % (nfsd_port, mountd_port)

        # Extract .tar.bz2 or .tar.bz if no nfs dir
        if not (self.rootfs and os.path.isdir(self.rootfs)):
            src_prefix = '%s/%s' % (self.get('DEPLOY_DIR_IMAGE'), self.get('IMAGE_LINK_NAME'))
            dest = "%s-nfsroot" % src_prefix
            if os.path.exists('%s.pseudo_state' % dest):
                logger.info('Use %s as NFS_DIR' % dest)
                self.rootfs = dest
            else:
                src = ""
                src1 = '%s.tar.bz2' % src_prefix
                src2 = '%s.tar.gz' % src_prefix
                if os.path.exists(src1):
                    src = src1
                elif os.path.exists(src2):
                    src = src2
                if not src:
                    raise RunQemuError("No NFS_DIR is set, and can't find %s or %s to extract" % (src1, src2))
                logger.info('NFS_DIR not found, extracting %s to %s' % (src, dest))
                cmd = 'runqemu-extract-sdk %s %s' % (src, dest)
                logger.info('Running %s...' % cmd)
                if subprocess.call(cmd, shell=True) != 0:
                    raise RunQemuError('Failed to run %s' % cmd)
                self.clean_nfs_dir = True
                self.rootfs = dest

        # Start the userspace NFS server
        cmd = 'runqemu-export-rootfs start %s' % self.rootfs
        logger.info('Running %s...' % cmd)
        if subprocess.call(cmd, shell=True) != 0:
            raise RunQemuError('Failed to run %s' % cmd)

        self.nfs_running = True

    def setup_slirp(self):
        """Setup user networking"""

        if self.fstype == 'nfs':
            self.setup_nfs()
        self.kernel_cmdline_script += ' ip=dhcp'
        # Port mapping
        hostfwd = ",hostfwd=tcp::2222-:22,hostfwd=tcp::2323-:23"
        qb_slirp_opt_default = "-netdev user,id=net0%s,tftp=%s" % (hostfwd, self.get('DEPLOY_DIR_IMAGE'))
        qb_slirp_opt = self.get('QB_SLIRP_OPT') or qb_slirp_opt_default
        # Figure out the port
        ports = re.findall('hostfwd=[^-]*:([0-9]+)-[^,-]*', qb_slirp_opt)
        ports = [int(i) for i in ports]
        mac = 2
        # Find a free port to avoid conflicts
        for p in ports[:]:
            p_new = p
            while not check_free_port('localhost', p_new):
                p_new += 1
                mac += 1
                while p_new in ports:
                        p_new += 1
                        mac += 1
            if p != p_new:
                ports.append(p_new)
                qb_slirp_opt = re.sub(':%s-' % p, ':%s-' % p_new, qb_slirp_opt)
                logger.info("Port forward changed: %s -> %s" % (p, p_new))
        mac = "%s%02x" % (self.mac_slirp, mac)
        self.set('NETWORK_CMD', '%s %s' % (self.network_device.replace('@MAC@', mac), qb_slirp_opt))
        # Print out port foward
        hostfwd = re.findall('(hostfwd=[^,]*)', qb_slirp_opt)
        if hostfwd:
            logger.info('Port forward: %s' % ' '.join(hostfwd))

    def setup_tap(self):
        """Setup tap"""

        # This file is created when runqemu-gen-tapdevs creates a bank of tap
        # devices, indicating that the user should not bring up new ones using
        # sudo.
        nosudo_flag = '/etc/runqemu-nosudo'
        self.qemuifup = shutil.which('runqemu-ifup')
        self.qemuifdown = shutil.which('runqemu-ifdown')
        ip = shutil.which('ip')
        lockdir = "/tmp/qemu-tap-locks"

        if not (self.qemuifup and self.qemuifdown and ip):
            logger.error("runqemu-ifup: %s" % self.qemuifup)
            logger.error("runqemu-ifdown: %s" % self.qemuifdown)
            logger.error("ip: %s" % ip)
            raise OEPathError("runqemu-ifup, runqemu-ifdown or ip not found")

        if not os.path.exists(lockdir):
            # There might be a race issue when multi runqemu processess are
            # running at the same time.
            try:
                os.mkdir(lockdir)
                os.chmod(lockdir, 0o777)
            except FileExistsError:
                pass

        cmd = '%s link' % ip
        logger.debug('Running %s...' % cmd)
        ip_link = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
        # Matches line like: 6: tap0: <foo>
        possibles = re.findall('^[0-9]+: +(tap[0-9]+): <.*', ip_link, re.M)
        tap = ""
        for p in possibles:
            lockfile = os.path.join(lockdir, p)
            if os.path.exists('%s.skip' % lockfile):
                logger.info('Found %s.skip, skipping %s' % (lockfile, p))
                continue
            self.lock = lockfile + '.lock'
            if self.acquire_lock(error=False):
                tap = p
                logger.info("Using preconfigured tap device %s" % tap)
                logger.info("If this is not intended, touch %s.skip to make runqemu skip %s." %(lockfile, tap))
                break

        if not tap:
            if os.path.exists(nosudo_flag):
                logger.error("Error: There are no available tap devices to use for networking,")
                logger.error("and I see %s exists, so I am not going to try creating" % nosudo_flag)
                raise RunQemuError("a new one with sudo.")

            gid = os.getgid()
            uid = os.getuid()
            logger.info("Setting up tap interface under sudo")
            cmd = 'sudo %s %s %s %s' % (self.qemuifup, uid, gid, self.bindir_native)
            tap = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8').rstrip('\n')
            lockfile = os.path.join(lockdir, tap)
            self.lock = lockfile + '.lock'
            self.acquire_lock()
            self.cleantap = True
            logger.debug('Created tap: %s' % tap)

        if not tap:
            logger.error("Failed to setup tap device. Run runqemu-gen-tapdevs to manually create.")
            return 1
        self.tap = tap
        tapnum = int(tap[3:])
        gateway = tapnum * 2 + 1
        client = gateway + 1
        if self.fstype == 'nfs':
            self.setup_nfs()
        netconf = "192.168.7.%s::192.168.7.%s:255.255.255.0" % (client, gateway)
        logger.info("Network configuration: %s", netconf)
        self.kernel_cmdline_script += " ip=%s" % netconf
        mac = "%s%02x" % (self.mac_tap, client)
        qb_tap_opt = self.get('QB_TAP_OPT')
        if qb_tap_opt:
            qemu_tap_opt = qb_tap_opt.replace('@TAP@', tap)
        else:
            qemu_tap_opt = "-netdev tap,id=net0,ifname=%s,script=no,downscript=no" % (self.tap)

        if self.vhost_enabled:
            qemu_tap_opt += ',vhost=on'

        self.set('NETWORK_CMD', '%s %s' % (self.network_device.replace('@MAC@', mac), qemu_tap_opt))

    def setup_network(self):
        if self.get('QB_NET') == 'none':
            return
        if sys.stdin.isatty():
            self.saved_stty = subprocess.check_output("stty -g", shell=True).decode('utf-8')
        self.network_device = self.get('QB_NETWORK_DEVICE') or self.network_device
        if self.slirp_enabled:
            self.setup_slirp()
        else:
            self.setup_tap()

    def setup_rootfs(self):
        if self.get('QB_ROOTFS') == 'none':
            return
        if 'wic.' in self.fstype:
            self.fstype = self.fstype[4:]
        rootfs_format = self.fstype if self.fstype in ('vmdk', 'qcow2', 'vdi') else 'raw'

        qb_rootfs_opt = self.get('QB_ROOTFS_OPT')
        if qb_rootfs_opt:
            self.rootfs_options = qb_rootfs_opt.replace('@ROOTFS@', self.rootfs)
        else:
            self.rootfs_options = '-drive file=%s,if=virtio,format=%s' % (self.rootfs, rootfs_format)

        if self.fstype in ('cpio.gz', 'cpio'):
            self.kernel_cmdline = 'root=/dev/ram0 rw debugshell'
            self.rootfs_options = '-initrd %s' % self.rootfs
        else:
            vm_drive = ''
            if self.fstype in self.vmtypes:
                if self.fstype == 'iso':
                    vm_drive = '-drive file=%s,if=virtio,media=cdrom' % self.rootfs
                elif self.get('QB_DRIVE_TYPE'):
                    drive_type = self.get('QB_DRIVE_TYPE')
                    if drive_type.startswith("/dev/sd"):
                        logger.info('Using scsi drive')
                        vm_drive = '-drive if=none,id=hd,file=%s,format=%s -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=hd' \
                                       % (self.rootfs, rootfs_format)
                    elif drive_type.startswith("/dev/hd"):
                        logger.info('Using ide drive')
                        vm_drive = "-drive file=%s,format=%s" % (self.rootfs, rootfs_format)
                    else:
                        # virtio might have been selected explicitly (just use it), or
                        # is used as fallback (then warn about that).
                        if not drive_type.startswith("/dev/vd"):
                            logger.warning("Unknown QB_DRIVE_TYPE: %s" % drive_type)
                            logger.warning("Failed to figure out drive type, consider define or fix QB_DRIVE_TYPE")
                            logger.warning('Trying to use virtio block drive')
                        vm_drive = '-drive if=virtio,file=%s,format=%s' % (self.rootfs, rootfs_format)

                # All branches above set vm_drive.
                self.rootfs_options = '%s -no-reboot' % vm_drive
            self.kernel_cmdline = 'root=%s rw highres=off' % (self.get('QB_KERNEL_ROOT'))

        if self.fstype == 'nfs':
            self.rootfs_options = ''
            k_root = '/dev/nfs nfsroot=%s:%s,%s' % (self.nfs_server, os.path.abspath(self.rootfs), self.unfs_opts)
            self.kernel_cmdline = 'root=%s rw highres=off' % k_root

        if self.fstype == 'none':
            self.rootfs_options = ''

        self.set('ROOTFS_OPTIONS', self.rootfs_options)

    def guess_qb_system(self):
        """attempt to determine the appropriate qemu-system binary"""
        mach = self.get('MACHINE')
        if not mach:
            search = '.*(qemux86-64|qemux86|qemuarm64|qemuarm|qemumips64|qemumips64el|qemumipsel|qemumips|qemuppc).*'
            if self.rootfs:
                match = re.match(search, self.rootfs)
                if match:
                    mach = match.group(1)
            elif self.kernel:
                match = re.match(search, self.kernel)
                if match:
                    mach = match.group(1)

        if not mach:
            return None

        if mach == 'qemuarm':
            qbsys = 'arm'
        elif mach == 'qemuarm64':
            qbsys = 'aarch64'
        elif mach == 'qemux86':
            qbsys = 'i386'
        elif mach == 'qemux86-64':
            qbsys = 'x86_64'
        elif mach == 'qemuppc':
            qbsys = 'ppc'
        elif mach == 'qemumips':
            qbsys = 'mips'
        elif mach == 'qemumips64':
            qbsys = 'mips64'
        elif mach == 'qemumipsel':
            qbsys = 'mipsel'
        elif mach == 'qemumips64el':
            qbsys = 'mips64el'
        elif mach == 'qemuriscv64':
            qbsys = 'riscv64'
        elif mach == 'qemuriscv32':
            qbsys = 'riscv32'
        else:
            logger.error("Unable to determine QEMU PC System emulator for %s machine." % mach)
            logger.error("As %s is not among valid QEMU machines such as," % mach)
            logger.error("qemux86-64, qemux86, qemuarm64, qemuarm, qemumips64, qemumips64el, qemumipsel, qemumips, qemuppc")
            raise RunQemuError("Set qb_system_name with suitable QEMU PC System emulator in .*qemuboot.conf.")

        return 'qemu-system-%s' % qbsys

    def setup_final(self):
        qemu_system = self.get('QB_SYSTEM_NAME')
        if not qemu_system:
            qemu_system = self.guess_qb_system()
        if not qemu_system:
            raise RunQemuError("Failed to boot, QB_SYSTEM_NAME is NULL!")

        qemu_bin = '%s/%s' % (self.bindir_native, qemu_system)

        # It is possible to have qemu-native in ASSUME_PROVIDED, and it won't
        # find QEMU in sysroot, it needs to use host's qemu.
        if not os.path.exists(qemu_bin):
            logger.info("QEMU binary not found in %s, trying host's QEMU" % qemu_bin)
            for path in (os.environ['PATH'] or '').split(':'):
                qemu_bin_tmp = os.path.join(path, qemu_system)
                logger.info("Trying: %s" % qemu_bin_tmp)
                if os.path.exists(qemu_bin_tmp):
                    qemu_bin = qemu_bin_tmp
                    if not os.path.isabs(qemu_bin):
                        qemu_bin = os.path.abspath(qemu_bin)
                    logger.info("Using host's QEMU: %s" % qemu_bin)
                    break

        if not os.access(qemu_bin, os.X_OK):
            raise OEPathError("No QEMU binary '%s' could be found" % qemu_bin)

        check_libgl(qemu_bin)

        self.qemu_opt = "%s %s %s %s" % (qemu_bin, self.get('NETWORK_CMD'), self.get('ROOTFS_OPTIONS'), self.get('QB_OPT_APPEND'))

        for ovmf in self.ovmf_bios:
            format = ovmf.rsplit('.', 1)[-1]
            self.qemu_opt += ' -drive if=pflash,format=%s,file=%s' % (format, ovmf)
        if self.ovmf_bios:
            # OVMF only supports normal VGA, i.e. we need to override a -vga vmware
            # that gets added for example for normal qemux86.
            self.qemu_opt += ' -vga std'

        self.qemu_opt += ' ' + self.qemu_opt_script

        if self.snapshot:
            self.qemu_opt += " -snapshot"

        if self.serialstdio:
            if sys.stdin.isatty():
                subprocess.check_call("stty intr ^]", shell=True)
                logger.info("Interrupt character is '^]'")

            first_serial = ""
            if not re.search("-nographic", self.qemu_opt):
                first_serial = "-serial mon:vc"
            # We always want a ttyS1. Since qemu by default adds a serial
            # port when nodefaults is not specified, it seems that all that
            # would be needed is to make sure a "-serial" is there. However,
            # it appears that when "-serial" is specified, it ignores the
            # default serial port that is normally added.  So here we make
            # sure to add two -serial if there are none. And only one if
            # there is one -serial already.
            serial_num = len(re.findall("-serial", self.qemu_opt))
            if serial_num == 0:
                self.qemu_opt += " %s %s" % (first_serial, self.get("QB_SERIAL_OPT"))
            elif serial_num == 1:
                self.qemu_opt += " %s" % self.get("QB_SERIAL_OPT")

        # We always wants ttyS0 and ttyS1 in qemu machines (see SERIAL_CONSOLES),
        # if not serial or serialtcp options was specified only ttyS0 is created
        # and sysvinit shows an error trying to enable ttyS1:
        #     INIT: Id "S1" respawning too fast: disabled for 5 minutes
        serial_num = len(re.findall("-serial", self.qemu_opt))
        if serial_num == 0:
            if re.search("-nographic", self.qemu_opt):
                self.qemu_opt += " -serial mon:stdio -serial null"
            else:
                self.qemu_opt += " -serial mon:vc -serial null"

    def start_qemu(self):
        import shlex
        if self.kernel:
            kernel_opts = "-kernel %s -append '%s %s %s %s'" % (self.kernel, self.kernel_cmdline,
                                                                self.kernel_cmdline_script, self.get('QB_KERNEL_CMDLINE_APPEND'),
                                                                self.bootparams)
            if self.dtb:
                kernel_opts += " -dtb %s" % self.dtb
        else:
            kernel_opts = ""
        cmd = "%s %s" % (self.qemu_opt, kernel_opts)
        cmds = shlex.split(cmd)
        logger.info('Running %s\n' % cmd)
        pass_fds = []
        if self.lock_descriptor:
            pass_fds = [self.lock_descriptor.fileno()]
        process = subprocess.Popen(cmds, stderr=subprocess.PIPE, pass_fds=pass_fds)
        self.qemupid = process.pid
        retcode = process.wait()
        if retcode:
            if retcode == -signal.SIGTERM:
                logger.info("Qemu terminated by SIGTERM")
            else:
                logger.error("Failed to run qemu: %s", process.stderr.read().decode())

    def cleanup(self):
        if self.cleaned:
            return

        # avoid dealing with SIGTERM when cleanup function is running
        signal.signal(signal.SIGTERM, signal.SIG_IGN)

        logger.info("Cleaning up")
        if self.cleantap:
            cmd = 'sudo %s %s %s' % (self.qemuifdown, self.tap, self.bindir_native)
            logger.debug('Running %s' % cmd)
            subprocess.check_call(cmd, shell=True)
        self.release_lock()

        if self.nfs_running:
            logger.info("Shutting down the userspace NFS server...")
            cmd = "runqemu-export-rootfs stop %s" % self.rootfs
            logger.debug('Running %s' % cmd)
            subprocess.check_call(cmd, shell=True)

        if self.saved_stty:
            cmd = "stty %s" % self.saved_stty
            subprocess.check_call(cmd, shell=True)

        if self.clean_nfs_dir:
            logger.info('Removing %s' % self.rootfs)
            shutil.rmtree(self.rootfs)
            shutil.rmtree('%s.pseudo_state' % self.rootfs)

        self.cleaned = True

    def load_bitbake_env(self, mach=None):
        if self.bitbake_e:
            return

        bitbake = shutil.which('bitbake')
        if not bitbake:
            return

        if not mach:
            mach = self.get('MACHINE')

        if mach:
            cmd = 'MACHINE=%s bitbake -e' % mach
        else:
            cmd = 'bitbake -e'

        logger.info('Running %s...' % cmd)
        try:
            self.bitbake_e = subprocess.check_output(cmd, shell=True).decode('utf-8')
        except subprocess.CalledProcessError as err:
            self.bitbake_e = ''
            logger.warning("Couldn't run 'bitbake -e' to gather environment information:\n%s" % err.output.decode('utf-8'))

    def validate_combos(self):
        if (self.fstype in self.vmtypes) and self.kernel:
            raise RunQemuError("%s doesn't need kernel %s!" % (self.fstype, self.kernel))

    @property
    def bindir_native(self):
        result = self.get('STAGING_BINDIR_NATIVE')
        if result and os.path.exists(result):
            return result

        cmd = 'bitbake qemu-helper-native -e'
        logger.info('Running %s...' % cmd)
        out = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        out = out.stdout.read().decode('utf-8')

        match = re.search('^STAGING_BINDIR_NATIVE="(.*)"', out, re.M)
        if match:
            result = match.group(1)
            if os.path.exists(result):
                self.set('STAGING_BINDIR_NATIVE', result)
                return result
            raise RunQemuError("Native sysroot directory %s doesn't exist" % result)
        else:
            raise RunQemuError("Can't find STAGING_BINDIR_NATIVE in '%s' output" % cmd)


def main():
    if "help" in sys.argv or '-h' in sys.argv or '--help' in sys.argv:
        print_usage()
        return 0
    try:
        config = BaseConfig()

        def sigterm_handler(signum, frame):
            logger.info("SIGTERM received")
            os.kill(config.qemupid, signal.SIGTERM)
            config.cleanup()
            subprocess.check_call(["tput", "smam"])
        signal.signal(signal.SIGTERM, sigterm_handler)

        config.check_args()
        config.read_qemuboot()
        config.check_and_set()
        # Check whether the combos is valid or not
        config.validate_combos()
        config.print_config()
        config.setup_network()
        config.setup_rootfs()
        config.setup_final()
        config.start_qemu()
    except RunQemuError as err:
        logger.error(err)
        return 1
    except Exception as err:
        import traceback
        traceback.print_exc()
        return 1
    finally:
        config.cleanup()
        subprocess.check_call(["tput", "smam"])

if __name__ == "__main__":
    sys.exit(main())
