Skip to contentSkip to conversation

fixes for runqemu

PATCH Superseded Robert Yang 2 participants 9 messages Apr 6, 2017 – Apr 7, 2017

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

cover fixes for runqemu

The following changes since commit 3a1cce659156ef2654a55a6e3c6922fa2dc780e4:

glibc: fix nativesdk ldd RTLDLIST (2017-04-05 23:22:06 +0100)

are available in the git repository at:

git://git.openembedded.org/openembedded-core-contrib rbt/qemu
http://cgit.openembedded.org/openembedded-core-contrib/log/?h=rbt/qemu

Robert Yang (6):
runqemu: fix 2 typos
runqemu: support env vars explicitly
runqemu: use self.rootfs to replace self.nfs_dir
runqemu: run without arguments
runqemu: use realpath for imgdir
runqemu: do not rely on grepping images

 meta/classes/qemuboot.bbclass |   3 +
 scripts/runqemu               | 130 +++++++++++++++++++++++-------------------
 2 files changed, 75 insertions(+), 58 deletions(-)
Signature · 1 line
2.11.0.rc2.dirty
#1 lore raw

PATCH 1/6 runqemu: fix 2 typos

* "is it" -> "it is"
* Remove "<image>.qemuboot.conf =" in the error message which looked strange.

---
 scripts/runqemu | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/runqemu +2 -2
index 23c9efbae2..251f5f7e94 100755
@@ -421,7 +421,7 @@ class BaseConfig(object):
             elif arg.startswith('ovmf'):
                 self.ovmf_bios.append(arg)
             else:
-                # At last, assume is it the MACHINE
+                # At last, assume it is the MACHINE
                 if (not unknown_arg) or unknown_arg == arg:
                     unknown_arg = arg
                 else:
@@ -677,7 +677,7 @@ class BaseConfig(object):
             return
 
         if not os.path.exists(self.qemuboot):
-            raise Exception("Failed to find <image>.qemuboot.conf = %s (wrong image name or BSP does not support running under qemu?)." % self.qemuboot)
+            raise Exception("Failed to find %s (wrong image name or BSP does not support running under qemu?)." % self.qemuboot)
 
         logger.info('CONFFILE: %s' % self.qemuboot)
 
Signature · 1 line
2.11.0.rc2.dirty
#2 lore raw

PATCH 2/6 runqemu: support env vars explicitly

In reply to Robert Yang

Use self.env_vars to support get vars from environment explicity. The MACHINE, ROOTFS and KERNEL was supported by shell based runqemu, and the help text says support them from env vars, so add them back.

[YOCTO #11141]

---
 scripts/runqemu | 71 ++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 29 deletions(-)
scripts/runqemu +42 -29
index 251f5f7e94..71e3cdbe80 100755
@@ -163,12 +163,18 @@ def check_free_port(host, port):
 
 class BaseConfig(object):
     def __init__(self):
-        # Vars can be merged with .qemuboot.conf, use a dict to manage them.
-        self.d = {
-            'MACHINE': '',
-            'DEPLOY_DIR_IMAGE': '',
-            'QB_KERNEL_ROOT': '/dev/vda',
-        }
+        # 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',
+                        'DEPLOY_DIR_IMAGE',
+                        'OE_TMPDIR',
+                        'OECORE_NATIVE_SYSROOT',
+                        )
 
         self.qemu_opt = ''
         self.qemu_opt_script = ''
@@ -238,6 +244,8 @@ class BaseConfig(object):
     def get(self, key):
         if key in self.d:
             return self.d.get(key)
+        elif os.getenv(key):
+            return os.getenv(key)
         else:
             return ''
 
@@ -338,10 +346,13 @@ class BaseConfig(object):
 
     def check_arg_machine(self, arg):
         """Check whether it is a machine"""
-        if self.get('MACHINE') and self.get('MACHINE') != arg or re.search('/', arg):
-            raise Exception("Unknown arg: %s" % arg)
-        elif self.get('MACHINE') == arg:
+        if self.get('MACHINE') == arg:
             return
+        elif self.get('MACHINE') and self.get('MACHINE') != arg:
+            raise Exception("Maybe conflicted MACHINE: %s vs %s" % (self.get('MACHINE'), arg))
+        elif re.search('/', arg):
+            raise Exception("Unknown arg: %s" % arg)
+
         logger.info('Assuming MACHINE = %s' % arg)
 
         # if we're running under testimage, or similarly as a child
@@ -350,14 +361,14 @@ class BaseConfig(object):
         # FIXME: testimage.bbclass exports these two variables into env,
         # are there other scenarios in which we need to support being
         # invoked by bitbake?
-        deploy = os.environ.get('DEPLOY_DIR_IMAGE')
-        bbchild = deploy and os.environ.get('OE_TMPDIR')
+        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 os.environ.get('OECORE_NATIVE_SYSROOT'):
+        if self.get('OECORE_NATIVE_SYSROOT'):
             self.set("MACHINE", arg)
             return
 
@@ -430,20 +441,15 @@ class BaseConfig(object):
         if unknown_arg:
             if self.get('MACHINE') == unknown_arg:
                 return
-            if not self.get('DEPLOY_DIR_IMAGE'):
-                # Trying to get DEPLOY_DIR_IMAGE from env.
-                p = os.getenv('DEPLOY_DIR_IMAGE')
-                if p and self.is_deploy_dir_image(p):
-                    machine = os.path.basename(p)
-                    if unknown_arg == machine:
-                        self.set_machine_deploy_dir(machine, p)
-                        return
-                    else:
-                        logger.info('DEPLOY_DIR_IMAGE: %s' % p)
-                        self.set("DEPLOY_DIR_IMAGE", p)
+            if self.get('DEPLOY_DIR_IMAGE'):
+                machine = os.path.basename(self.get('DEPLOY_DIR_IMAGE'))
+                if unknown_arg == machine:
+                    self.set_machine_deploy_dir(machine, p)
+                    return
+
             self.check_arg_machine(unknown_arg)
 
-        if not (self.get('MACHINE') or self.get('DEPLOY_DIR_IMAGE')):
+        if not self.get('DEPLOY_DIR_IMAGE'):
             self.load_bitbake_env()
             s = re.search('^DEPLOY_DIR_IMAGE="(.*)"', self.bitbake_e, re.M)
             if s:
@@ -505,7 +511,16 @@ class BaseConfig(object):
     def check_rootfs(self):
         """Check and set rootfs"""
 
-        if self.fstype == 'nfs' or self.fstype == "none":
+        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 Exception("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):
@@ -642,8 +657,6 @@ class BaseConfig(object):
         if not self.qemuboot:
             if self.get('DEPLOY_DIR_IMAGE'):
                 deploy_dir_image = self.get('DEPLOY_DIR_IMAGE')
-            elif os.getenv('DEPLOY_DIR_IMAGE'):
-                deploy_dir_image = os.getenv('DEPLOY_DIR_IMAGE')
             else:
                 logger.info("Can't find qemuboot conf file, DEPLOY_DIR_IMAGE is NULL!")
                 return
@@ -720,8 +733,8 @@ class BaseConfig(object):
                 # 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 = os.environ.get('OE_TMPDIR', None)
-                oecore_native_sysroot = os.environ.get('OECORE_NATIVE_SYSROOT', None)
+                tmpdir = self.get('OE_TMPDIR', None)
+                oecore_native_sysroot = self.get('OECORE_NATIVE_SYSROOT', None)
                 if tmpdir:
                     logger.info('Setting STAGING_DIR_NATIVE and STAGING_BINDIR_NATIVE relative to OE_TMPDIR (%s)' % tmpdir)
                     hostos, _, _, _, machine = os.uname()
Signature · 1 line
2.11.0.rc2.dirty
#3 lore raw

PATCH 3/6 runqemu: use self.rootfs to replace self.nfs_dir

In reply to Robert Yang

We can use self.rootfs as self.nfs_dir when self.fstype is nfs, this can reduce the code's complexity and we can re-use the code of checking ROOTFS conflictions.

---
 scripts/runqemu | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)
scripts/runqemu +13 -15
index 71e3cdbe80..23a344da35 100755
@@ -178,7 +178,6 @@ class BaseConfig(object):
 
         self.qemu_opt = ''
         self.qemu_opt_script = ''
-        self.nfs_dir = ''
         self.clean_nfs_dir = False
         self.nfs_server = ''
         self.rootfs = ''
@@ -284,12 +283,11 @@ class BaseConfig(object):
 
     def check_arg_nfs(self, p):
         if os.path.isdir(p):
-            self.nfs_dir = p
+            self.rootfs = p
         else:
             m = re.match('(.*):(.*)', p)
             self.nfs_server = m.group(1)
-            self.nfs_dir = m.group(2)
-        self.rootfs = ""
+            self.rootfs = m.group(2)
         self.check_arg_fstype('nfs')
 
     def check_arg_path(self, p):
@@ -759,7 +757,7 @@ class BaseConfig(object):
         print('MACHINE: [%s]' % self.get('MACHINE'))
         print('FSTYPE: [%s]' % self.fstype)
         if self.fstype  == 'nfs':
-            print('NFS_DIR: [%s]' % self.nfs_dir)
+            print('NFS_DIR: [%s]' % self.rootfs)
         else:
             print('ROOTFS: [%s]' % self.rootfs)
         if self.ovmf_bios:
@@ -804,13 +802,13 @@ class BaseConfig(object):
 
         self.unfs_opts="nfsvers=3,port=%s,mountprog=%s,nfsprog=%s,udp,mountport=%s" % (nfsd_port, mountd_rpcport, nfsd_rpcport, mountd_port)
 
-        # Extract .tar.bz2 or .tar.bz if no self.nfs_dir
-        if not self.nfs_dir:
+        # 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.nfs_dir = dest
+                self.rootfs = dest
             else:
                 src = ""
                 src1 = '%s.tar.bz2' % src_prefix
@@ -827,10 +825,10 @@ class BaseConfig(object):
                 if subprocess.call(cmd, shell=True) != 0:
                     raise Exception('Failed to run %s' % cmd)
                 self.clean_nfs_dir = True
-                self.nfs_dir = dest
+                self.rootfs = dest
 
         # Start the userspace NFS server
-        cmd = 'runqemu-export-rootfs start %s' % self.nfs_dir
+        cmd = 'runqemu-export-rootfs start %s' % self.rootfs
         logger.info('Running %s...' % cmd)
         if subprocess.call(cmd, shell=True) != 0:
             raise Exception('Failed to run %s' % cmd)
@@ -1001,7 +999,7 @@ class BaseConfig(object):
 
         if self.fstype == 'nfs':
             self.rootfs_options = ''
-            k_root = '/dev/nfs nfsroot=%s:%s,%s' % (self.nfs_server, self.nfs_dir, self.unfs_opts)
+            k_root = '/dev/nfs nfsroot=%s:%s,%s' % (self.nfs_server, self.rootfs, self.unfs_opts)
             self.kernel_cmdline = 'root=%s rw highres=off' % k_root
 
         if self.fstype == 'none':
@@ -1147,7 +1145,7 @@ class BaseConfig(object):
 
         if self.nfs_running:
             logger.info("Shutting down the userspace NFS server...")
-            cmd = "runqemu-export-rootfs stop %s" % self.nfs_dir
+            cmd = "runqemu-export-rootfs stop %s" % self.rootfs
             logger.info('Running %s' % cmd)
             subprocess.call(cmd, shell=True)
 
@@ -1156,9 +1154,9 @@ class BaseConfig(object):
             subprocess.call(cmd, shell=True)
 
         if self.clean_nfs_dir:
-            logger.info('Removing %s' % self.nfs_dir)
-            shutil.rmtree(self.nfs_dir)
-            shutil.rmtree('%s.pseudo_state' % self.nfs_dir)
+            logger.info('Removing %s' % self.rootfs)
+            shutil.rmtree(self.rootfs)
+            shutil.rmtree('%s.pseudo_state' % self.rootfs)
 
     def load_bitbake_env(self, mach=None):
         if self.bitbake_e:
Signature · 1 line
2.11.0.rc2.dirty
#4 lore raw

PATCH 4/6 runqemu: run without arguments

In reply to Robert Yang

Since we can get MACHINE and others from env vars and "bitbake -e", "runqemu" can work without any arguments.

---
 scripts/runqemu | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/runqemu +2 -2
index 23a344da35..1b330b7cfd 100755
@@ -83,6 +83,7 @@ of the following environment variables (in any order):
   help, -h, --help: print this text
 
 Examples:
+  runqemu
   runqemu qemuarm
   runqemu tmp/deploy/images/qemuarm
   runqemu tmp/deploy/images/qemux86/<qemuboot.conf>
@@ -1182,8 +1183,7 @@ class BaseConfig(object):
             logger.warn("Couldn't run 'bitbake -e' to gather environment information:\n%s" % err.output.decode('utf-8'))
 
 def main():
-    if len(sys.argv) == 1 or "help" in sys.argv or \
-            '-h' in sys.argv or '--help' in sys.argv:
+    if "help" in sys.argv or '-h' in sys.argv or '--help' in sys.argv:
         print_usage()
         return 0
     config = BaseConfig()
Signature · 1 line
2.11.0.rc2.dirty
#5 lore raw

PATCH 5/6 runqemu: use realpath for imgdir

In reply to Robert Yang

The DEPLOY_DIR_IMAGE maybe relative or absolute path since it can be read from env vars, so use realpath for both imgdir and DEPLOY_DIR_IMAGE when compare.

---
 scripts/runqemu | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/runqemu +2 -2
index 1b330b7cfd..b9646223c4 100755
@@ -705,8 +705,8 @@ class BaseConfig(object):
         # 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.dirname(self.qemuboot)
-            if imgdir != self.get('DEPLOY_DIR_IMAGE'):
+            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)
 
Signature · 1 line
2.11.0.rc2.dirty
#6 lore raw

PATCH 6/6 runqemu: do not rely on grepping images

In reply to Robert Yang

Fixed when the image is large and not enough memory:
grep: memory exhausted
Aborted

[YOCTO #11073]

---
 meta/classes/qemuboot.bbclass |  3 +++
 scripts/runqemu               | 19 +++++++++++--------
 2 files changed, 14 insertions(+), 8 deletions(-)
meta/classes/qemuboot.bbclass +3 -0
index 3ca97cad4c..2870388dfb 100644
@@ -64,6 +64,9 @@ QB_DEFAULT_FSTYPE ?= "ext4"
 QB_OPT_APPEND ?= "-show-cursor"
 QB_NETWORK_DEVICE ?= "-device virtio-net-pci,netdev=net0,mac=@MAC@"
 
+# This should be kept align with ROOT_VM
+QB_DRIVE_TYPE ?= "/dev/sd"
+
 # Create qemuboot.conf
 addtask do_write_qemuboot_conf after do_rootfs before do_image
 IMGDEPLOYDIR ?= "${WORKDIR}/deploy-${PN}-image-complete"
scripts/runqemu +11 -8
index b9646223c4..b5fc22af18 100755
@@ -978,23 +978,26 @@ class BaseConfig(object):
             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 = '-cdrom %s' % self.rootfs
-                else:
-                    cmd1 = "grep -q 'root=/dev/sd' %s" % self.rootfs
-                    cmd2 = "grep -q 'root=/dev/hd' %s" % self.rootfs
-                    if subprocess.call(cmd1, shell=True) == 0:
+                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 subprocess.call(cmd2, shell=True) == 0:
+                    elif drive_type.startswith("/dev/hd"):
                         logger.info('Using ide drive')
                         vm_drive = "%s,format=%s" % (self.rootfs, rootfs_format)
                     else:
-                        logger.warn("Can't detect drive type %s" % self.rootfs)
-                        logger.warn('Trying to use virtio block drive')
-                        vm_drive = '-drive if=virtio,file=%s,format=%s' % (self.rootfs, rootfs_format)
+                        logger.warn("Unknown QB_DRIVE_TYPE: %s" % drive_type)
+
+                if not vm_drive:
+                    logger.warn("Failed to figure out drive type, consider define or fix QB_DRIVE_TYPE")
+                    logger.warn('Trying to use virtio block drive')
+                    vm_drive = '-drive if=virtio,file=%s,format=%s' % (self.rootfs, rootfs_format)
                 self.rootfs_options = '%s -no-reboot' % vm_drive
             self.kernel_cmdline = 'root=%s rw highres=off' % (self.get('QB_KERNEL_ROOT'))
 
Signature · 1 line
2.11.0.rc2.dirty
#7 lore raw
In reply to Robert Yang
Quoted 11 lines · Robert Yang

The following changes since commit
3a1cce659156ef2654a55a6e3c6922fa2dc780e4:

  glibc: fix nativesdk ldd RTLDLIST (2017-04-05 23:22:06 +0100)

are available in the git repository at:

  git://git.openembedded.org/openembedded-core-contrib rbt/qemu
  http://cgit.openembedded.org/openembedded-core-contrib/log/?h=rbt/q
emu

Quoted 7 lines

Robert Yang (6):
  runqemu: fix 2 typos
  runqemu: support env vars explicitly
  runqemu: use self.rootfs to replace self.nfs_dir
  runqemu: run without arguments
  runqemu: use realpath for imgdir
  runqemu: do not rely on grepping images

Something in here breaks the use of "bitbake xxx-image -c testimage":

https://autobuilder.yocto.io/builders/nightly-arm/builds/280

[basically all sanity tests failed in that build]

Cheers,

Richard

#8 lore raw
Quoted 20 lines · Richard Purdie
Quoted 11 lines · Robert Yang

The following changes since commit
3a1cce659156ef2654a55a6e3c6922fa2dc780e4:

glibc: fix nativesdk ldd RTLDLIST (2017-04-05 23:22:06 +0100)

are available in the git repository at:

git://git.openembedded.org/openembedded-core-contrib rbt/qemu
http://cgit.openembedded.org/openembedded-core-contrib/log/?h=rbt/q
emu

Quoted 7 lines

Robert Yang (6):
runqemu: fix 2 typos
runqemu: support env vars explicitly
runqemu: use self.rootfs to replace self.nfs_dir
runqemu: run without arguments
runqemu: use realpath for imgdir
runqemu: do not rely on grepping images

Quoted 5 lines

Something in here breaks the use of "bitbake xxx-image -c testimage":

https://autobuilder.yocto.io/builders/nightly-arm/builds/280

[basically all sanity tests failed in that build]

I'm really very sorry for the stupid errors, I had seen it, and I thought that I had fixed it, but didn't. I will send a V2 and include Qi's patch since there are conflicts, I will resolve the conflicts.

// Robert

Quoted 5 lines

Cheers,

Richard