summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2021-03-31 22:41:52 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-04-06 09:30:10 +0100
commit232cb7b0553f844be695d26f55aaf531029a6a9a (patch)
tree5fa23ee5245cfc0ecec91d1ff8c1969165a6580c
parent82d7dc9709bb2cc85a42b168bdd25ab70e763bee (diff)
downloadpoky-232cb7b0553f844be695d26f55aaf531029a6a9a.tar.gz
oeqa/runqemu: Support RUNQEMU_TMPFS_DIR as a location to copy snapshot images to
We have a working theory that IO queues on the autobuilder are impacting runtime testing under qemu, particularly async writes which inice does not influence. We already pass the snapshot option to qemu which copies the image and runs out of the copy. Add in the ability to copy the image to a specificed location which can be a tmpfs. This means that writes to the image would no longer be blocked by other writes to disk in the system. Preliminary tests show that this does improve the qemu errors at the expense of sometimes showing qemu startup timeouts as on a loaded system with a large test image, it can take longer than 120s to copy the image to tmpfs. Having a most consistent failure mode for loaded tests is probably desireable though. (From OE-Core rev: fd1c26ab426c3699ffd8082b83d65a84c8eb8bff) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/classes/testimage.bbclass1
-rw-r--r--meta/lib/oeqa/core/target/qemu.py4
-rw-r--r--meta/lib/oeqa/targetcontrol.py2
-rw-r--r--meta/lib/oeqa/utils/qemurunner.py6
-rw-r--r--meta/lib/oeqa/utils/qemutinyrunner.py6
-rwxr-xr-xscripts/runqemu9
6 files changed, 24 insertions, 4 deletions
diff --git a/meta/classes/testimage.bbclass b/meta/classes/testimage.bbclass
index 78da4b09bd..e613759503 100644
--- a/meta/classes/testimage.bbclass
+++ b/meta/classes/testimage.bbclass
@@ -305,6 +305,7 @@ def testimage_main(d):
305 'dump_dir' : d.getVar("TESTIMAGE_DUMP_DIR"), 305 'dump_dir' : d.getVar("TESTIMAGE_DUMP_DIR"),
306 'serial_ports': len(d.getVar("SERIAL_CONSOLES").split()), 306 'serial_ports': len(d.getVar("SERIAL_CONSOLES").split()),
307 'ovmf' : ovmf, 307 'ovmf' : ovmf,
308 'tmpfsdir' : d.getVar("RUNQEMU_TMPFS_DIR"),
308 } 309 }
309 310
310 if d.getVar("TESTIMAGE_BOOT_PATTERNS"): 311 if d.getVar("TESTIMAGE_BOOT_PATTERNS"):
diff --git a/meta/lib/oeqa/core/target/qemu.py b/meta/lib/oeqa/core/target/qemu.py
index 0f29414df5..792efca1f8 100644
--- a/meta/lib/oeqa/core/target/qemu.py
+++ b/meta/lib/oeqa/core/target/qemu.py
@@ -21,7 +21,7 @@ class OEQemuTarget(OESSHTarget):
21 port=None, machine='', rootfs='', kernel='', kvm=False, slirp=False, 21 port=None, machine='', rootfs='', kernel='', kvm=False, slirp=False,
22 dump_dir='', dump_host_cmds='', display='', bootlog='', 22 dump_dir='', dump_host_cmds='', display='', bootlog='',
23 tmpdir='', dir_image='', boottime=60, serial_ports=2, 23 tmpdir='', dir_image='', boottime=60, serial_ports=2,
24 boot_patterns = defaultdict(str), ovmf=False, **kwargs): 24 boot_patterns = defaultdict(str), ovmf=False, tmpfsdir=None, **kwargs):
25 25
26 super(OEQemuTarget, self).__init__(logger, None, server_ip, timeout, 26 super(OEQemuTarget, self).__init__(logger, None, server_ip, timeout,
27 user, port) 27 user, port)
@@ -42,7 +42,7 @@ class OEQemuTarget(OESSHTarget):
42 use_kvm=kvm, use_slirp=slirp, dump_dir=dump_dir, 42 use_kvm=kvm, use_slirp=slirp, dump_dir=dump_dir,
43 dump_host_cmds=dump_host_cmds, logger=logger, 43 dump_host_cmds=dump_host_cmds, logger=logger,
44 serial_ports=serial_ports, boot_patterns = boot_patterns, 44 serial_ports=serial_ports, boot_patterns = boot_patterns,
45 use_ovmf=ovmf) 45 use_ovmf=ovmf, tmpfsdir=tmpfsdir)
46 dump_target_cmds = kwargs.get("testimage_dump_target") 46 dump_target_cmds = kwargs.get("testimage_dump_target")
47 self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner) 47 self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner)
48 self.target_dumper.create_dir("qemu") 48 self.target_dumper.create_dir("qemu")
diff --git a/meta/lib/oeqa/targetcontrol.py b/meta/lib/oeqa/targetcontrol.py
index 19f5a4ea7e..12057f855a 100644
--- a/meta/lib/oeqa/targetcontrol.py
+++ b/meta/lib/oeqa/targetcontrol.py
@@ -131,6 +131,7 @@ class QemuTarget(BaseTarget):
131 logfile = self.qemulog, 131 logfile = self.qemulog,
132 kernel = self.kernel, 132 kernel = self.kernel,
133 boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT")), 133 boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT")),
134 tmpfsdir = d.getVar("RUNQEMU_TMPFS_DIR"),
134 logger = logger) 135 logger = logger)
135 else: 136 else:
136 self.runner = QemuRunner(machine=d.getVar("MACHINE"), 137 self.runner = QemuRunner(machine=d.getVar("MACHINE"),
@@ -144,6 +145,7 @@ class QemuTarget(BaseTarget):
144 dump_dir = dump_dir, 145 dump_dir = dump_dir,
145 dump_host_cmds = d.getVar("testimage_dump_host"), 146 dump_host_cmds = d.getVar("testimage_dump_host"),
146 logger = logger, 147 logger = logger,
148 tmpfsdir = d.getVar("RUNQEMU_TMPFS_DIR"),
147 serial_ports = len(d.getVar("SERIAL_CONSOLES").split())) 149 serial_ports = len(d.getVar("SERIAL_CONSOLES").split()))
148 150
149 self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner) 151 self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner)
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py
index eb23dbceb8..278904ba0b 100644
--- a/meta/lib/oeqa/utils/qemurunner.py
+++ b/meta/lib/oeqa/utils/qemurunner.py
@@ -32,7 +32,7 @@ re_control_char = re.compile('[%s]' % re.escape("".join(control_chars)))
32class QemuRunner: 32class QemuRunner:
33 33
34 def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, boottime, dump_dir, dump_host_cmds, 34 def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, boottime, dump_dir, dump_host_cmds,
35 use_kvm, logger, use_slirp=False, serial_ports=2, boot_patterns = defaultdict(str), use_ovmf=False, workdir=None): 35 use_kvm, logger, use_slirp=False, serial_ports=2, boot_patterns = defaultdict(str), use_ovmf=False, workdir=None, tmpfsdir=None):
36 36
37 # Popen object for runqemu 37 # Popen object for runqemu
38 self.runqemu = None 38 self.runqemu = None
@@ -61,6 +61,7 @@ class QemuRunner:
61 self.serial_ports = serial_ports 61 self.serial_ports = serial_ports
62 self.msg = '' 62 self.msg = ''
63 self.boot_patterns = boot_patterns 63 self.boot_patterns = boot_patterns
64 self.tmpfsdir = tmpfsdir
64 65
65 self.runqemutime = 120 66 self.runqemutime = 120
66 if not workdir: 67 if not workdir:
@@ -150,6 +151,9 @@ class QemuRunner:
150 else: 151 else:
151 env["DEPLOY_DIR_IMAGE"] = self.deploy_dir_image 152 env["DEPLOY_DIR_IMAGE"] = self.deploy_dir_image
152 153
154 if self.tmpfsdir:
155 env["RUNQEMU_TMPFS_DIR"] = self.tmpfsdir
156
153 if not launch_cmd: 157 if not launch_cmd:
154 launch_cmd = 'runqemu %s' % ('snapshot' if discard_writes else '') 158 launch_cmd = 'runqemu %s' % ('snapshot' if discard_writes else '')
155 if self.use_kvm: 159 if self.use_kvm:
diff --git a/meta/lib/oeqa/utils/qemutinyrunner.py b/meta/lib/oeqa/utils/qemutinyrunner.py
index 5c92941c0a..20009401ca 100644
--- a/meta/lib/oeqa/utils/qemutinyrunner.py
+++ b/meta/lib/oeqa/utils/qemutinyrunner.py
@@ -19,7 +19,7 @@ from .qemurunner import QemuRunner
19 19
20class QemuTinyRunner(QemuRunner): 20class QemuTinyRunner(QemuRunner):
21 21
22 def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, kernel, boottime, logger): 22 def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, kernel, boottime, logger, tmpfsdir=None):
23 23
24 # Popen object for runqemu 24 # Popen object for runqemu
25 self.runqemu = None 25 self.runqemu = None
@@ -37,6 +37,7 @@ class QemuTinyRunner(QemuRunner):
37 self.deploy_dir_image = deploy_dir_image 37 self.deploy_dir_image = deploy_dir_image
38 self.logfile = logfile 38 self.logfile = logfile
39 self.boottime = boottime 39 self.boottime = boottime
40 self.tmpfsdir = tmpfsdir
40 41
41 self.runqemutime = 60 42 self.runqemutime = 60
42 self.socketfile = "console.sock" 43 self.socketfile = "console.sock"
@@ -83,6 +84,9 @@ class QemuTinyRunner(QemuRunner):
83 return False 84 return False
84 else: 85 else:
85 os.environ["DEPLOY_DIR_IMAGE"] = self.deploy_dir_image 86 os.environ["DEPLOY_DIR_IMAGE"] = self.deploy_dir_image
87 if self.tmpfsdir:
88 env["RUNQEMU_TMPFS_DIR"] = self.tmpfsdir
89
86 90
87 # Set this flag so that Qemu doesn't do any grabs as SDL grabs interact 91 # Set this flag so that Qemu doesn't do any grabs as SDL grabs interact
88 # badly with screensavers. 92 # badly with screensavers.
diff --git a/scripts/runqemu b/scripts/runqemu
index 35053de368..ba0b701aff 100755
--- a/scripts/runqemu
+++ b/scripts/runqemu
@@ -1196,6 +1196,15 @@ class BaseConfig(object):
1196 self.fstype = self.fstype[4:] 1196 self.fstype = self.fstype[4:]
1197 rootfs_format = self.fstype if self.fstype in ('vmdk', 'vhd', 'vhdx', 'qcow2', 'vdi') else 'raw' 1197 rootfs_format = self.fstype if self.fstype in ('vmdk', 'vhd', 'vhdx', 'qcow2', 'vdi') else 'raw'
1198 1198
1199 tmpfsdir = os.environ.get("RUNQEMU_TMPFS_DIR", None)
1200 if self.snapshot and tmpfsdir:
1201 newrootfs = os.path.join(tmpfsdir, os.path.basename(self.rootfs)) + "." + str(os.getpid())
1202 shutil.copyfile(self.rootfs, newrootfs)
1203 #print("Copying rootfs to tmpfs: %s" % newrootfs)
1204 self.rootfs = newrootfs
1205 # Don't need a second copy now!
1206 self.snapshot = False
1207
1199 qb_rootfs_opt = self.get('QB_ROOTFS_OPT') 1208 qb_rootfs_opt = self.get('QB_ROOTFS_OPT')
1200 if qb_rootfs_opt: 1209 if qb_rootfs_opt:
1201 self.rootfs_options = qb_rootfs_opt.replace('@ROOTFS@', self.rootfs) 1210 self.rootfs_options = qb_rootfs_opt.replace('@ROOTFS@', self.rootfs)