summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/utils
diff options
context:
space:
mode:
authorMariano Lopez <mariano.lopez@linux.intel.com>2015-09-01 07:36:29 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-09-03 12:43:16 +0100
commit53ab41a5f6d20e911362a9261ae528452bb71bbd (patch)
tree0962c78c4f378c3de0fc25810778a49f0a35d168 /meta/lib/oeqa/utils
parent170b89d9863a1b8560f397d3bb7a1eafd7c61e1e (diff)
downloadpoky-53ab41a5f6d20e911362a9261ae528452bb71bbd.tar.gz
qemurunner: Added host dumps when there are errors
This adds an instance of HostDumper to qemurunner, with this instance now is possible to get dumps from the host when there is an error. This adds dump points in the next cases: - runqemu exits before seeing qemu pid - Fail to get qemu process arguments - Not reach login banner before timeout - qemu pid never appears This also modifies the constructors of BaseDumper, HostDumper and TargetDumper, they don't require the datastore anymore, but the feature to replace datastore variables has been lost (never used) [YOCTO #8118] (From OE-Core rev: b0af40fb76cd5035696e9d8a44f815f64214d23a) Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oeqa/utils')
-rw-r--r--meta/lib/oeqa/utils/dump.py28
-rw-r--r--meta/lib/oeqa/utils/qemurunner.py15
2 files changed, 23 insertions, 20 deletions
diff --git a/meta/lib/oeqa/utils/dump.py b/meta/lib/oeqa/utils/dump.py
index e71e1cd341..6067438e35 100644
--- a/meta/lib/oeqa/utils/dump.py
+++ b/meta/lib/oeqa/utils/dump.py
@@ -6,30 +6,22 @@ import itertools
6from commands import runCmd 6from commands import runCmd
7 7
8def get_host_dumper(d): 8def get_host_dumper(d):
9 return HostDumper(d) 9 cmds = d.getVar("testimage_dump_host", True)
10 parent_dir = d.getVar("TESTIMAGE_DUMP_DIR", True)
11 return HostDumper(cmds, parent_dir)
10 12
11 13
12class BaseDumper(object): 14class BaseDumper(object):
13 15
14 def __init__(self, d, cmds): 16 def __init__(self, cmds, parent_dir):
15 self.cmds = [] 17 self.cmds = []
16 self.parent_dir = d.getVar("TESTIMAGE_DUMP_DIR", True) 18 self.parent_dir = parent_dir
17 if not cmds: 19 if not cmds:
18 return 20 return
19 for cmd in cmds.split('\n'): 21 for cmd in cmds.split('\n'):
20 cmd = cmd.lstrip() 22 cmd = cmd.lstrip()
21 if not cmd or cmd[0] == '#': 23 if not cmd or cmd[0] == '#':
22 continue 24 continue
23 # Replae variables from the datastore
24 while True:
25 index_start = cmd.find("${")
26 if index_start == -1:
27 break
28 index_start += 2
29 index_end = cmd.find("}", index_start)
30 var = cmd[index_start:index_end]
31 value = d.getVar(var, True)
32 cmd = cmd.replace("${%s}" % var, value)
33 self.cmds.append(cmd) 25 self.cmds.append(cmd)
34 26
35 def create_dir(self, dir_suffix): 27 def create_dir(self, dir_suffix):
@@ -62,9 +54,8 @@ class BaseDumper(object):
62 54
63class HostDumper(BaseDumper): 55class HostDumper(BaseDumper):
64 56
65 def __init__(self, d): 57 def __init__(self, cmds, parent_dir):
66 host_cmds = d.getVar("testimage_dump_host", True) 58 super(HostDumper, self).__init__(cmds, parent_dir)
67 super(HostDumper, self).__init__(d, host_cmds)
68 59
69 def dump_host(self, dump_dir=""): 60 def dump_host(self, dump_dir=""):
70 if dump_dir: 61 if dump_dir:
@@ -76,9 +67,8 @@ class HostDumper(BaseDumper):
76 67
77class TargetDumper(BaseDumper): 68class TargetDumper(BaseDumper):
78 69
79 def __init__(self, d, qemurunner): 70 def __init__(self, cmds, parent_dir, qemurunner):
80 target_cmds = d.getVar("testimage_dump_target", True) 71 super(TargetDumper, self).__init__(cmds, parent_dir)
81 super(TargetDumper, self).__init__(d, target_cmds)
82 self.runner = qemurunner 72 self.runner = qemurunner
83 73
84 def dump_target(self, dump_dir=""): 74 def dump_target(self, dump_dir=""):
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py
index bcdb69b38c..4ce5d9c685 100644
--- a/meta/lib/oeqa/utils/qemurunner.py
+++ b/meta/lib/oeqa/utils/qemurunner.py
@@ -14,13 +14,14 @@ import socket
14import select 14import select
15import errno 15import errno
16import threading 16import threading
17from oeqa.utils.dump import HostDumper
17 18
18import logging 19import logging
19logger = logging.getLogger("BitBake.QemuRunner") 20logger = logging.getLogger("BitBake.QemuRunner")
20 21
21class QemuRunner: 22class QemuRunner:
22 23
23 def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, boottime): 24 def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, boottime, dump_dir, dump_host_cmds):
24 25
25 # Popen object for runqemu 26 # Popen object for runqemu
26 self.runqemu = None 27 self.runqemu = None
@@ -42,6 +43,7 @@ class QemuRunner:
42 self.thread = None 43 self.thread = None
43 44
44 self.runqemutime = 60 45 self.runqemutime = 60
46 self.host_dumper = HostDumper(dump_host_cmds, dump_dir)
45 47
46 def create_socket(self): 48 def create_socket(self):
47 try: 49 try:
@@ -118,6 +120,7 @@ class QemuRunner:
118 if self.runqemu.returncode: 120 if self.runqemu.returncode:
119 # No point waiting any longer 121 # No point waiting any longer
120 logger.info('runqemu exited with code %d' % self.runqemu.returncode) 122 logger.info('runqemu exited with code %d' % self.runqemu.returncode)
123 self._dump_host()
121 self.stop() 124 self.stop()
122 logger.info("Output from runqemu:\n%s" % getOutput(output)) 125 logger.info("Output from runqemu:\n%s" % getOutput(output))
123 return False 126 return False
@@ -137,6 +140,7 @@ class QemuRunner:
137 self.server_ip = ips[1] 140 self.server_ip = ips[1]
138 except IndexError, ValueError: 141 except IndexError, ValueError:
139 logger.info("Couldn't get ip from qemu process arguments! Here is the qemu command line used:\n%s\nand output from runqemu:\n%s" % (cmdline, getOutput(output))) 142 logger.info("Couldn't get ip from qemu process arguments! Here is the qemu command line used:\n%s\nand output from runqemu:\n%s" % (cmdline, getOutput(output)))
143 self._dump_host()
140 self.stop() 144 self.stop()
141 return False 145 return False
142 logger.info("qemu cmdline used:\n{}".format(cmdline)) 146 logger.info("qemu cmdline used:\n{}".format(cmdline))
@@ -189,6 +193,7 @@ class QemuRunner:
189 lines = "\n".join(bootlog.splitlines()[-25:]) 193 lines = "\n".join(bootlog.splitlines()[-25:])
190 logger.info("Last 25 lines of text:\n%s" % lines) 194 logger.info("Last 25 lines of text:\n%s" % lines)
191 logger.info("Check full boot log: %s" % self.logfile) 195 logger.info("Check full boot log: %s" % self.logfile)
196 self._dump_host()
192 self.stop() 197 self.stop()
193 return False 198 return False
194 199
@@ -202,6 +207,7 @@ class QemuRunner:
202 207
203 else: 208 else:
204 logger.info("Qemu pid didn't appeared in %s seconds" % self.runqemutime) 209 logger.info("Qemu pid didn't appeared in %s seconds" % self.runqemutime)
210 self._dump_host()
205 self.stop() 211 self.stop()
206 logger.info("Output from runqemu:\n%s" % getOutput(output)) 212 logger.info("Output from runqemu:\n%s" % getOutput(output))
207 return False 213 return False
@@ -334,6 +340,13 @@ class QemuRunner:
334 status = 1 340 status = 1
335 return (status, str(data)) 341 return (status, str(data))
336 342
343
344 def _dump_host(self):
345 self.host_dumper.create_dir("qemu")
346 logger.error("Qemu ended unexpectedly, dump data from host"
347 " is in %s" % self.host_dumper.dump_dir)
348 self.host_dumper.dump_host()
349
337# This class is for reading data from a socket and passing it to logfunc 350# This class is for reading data from a socket and passing it to logfunc
338# to be processed. It's completely event driven and has a straightforward 351# to be processed. It's completely event driven and has a straightforward
339# event loop. The mechanism for stopping the thread is a simple pipe which 352# event loop. The mechanism for stopping the thread is a simple pipe which