aboutsummaryrefslogtreecommitdiffstats
path: root/lib/oeqa/utils/qemuzephyrrunner.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/oeqa/utils/qemuzephyrrunner.py')
-rw-r--r--lib/oeqa/utils/qemuzephyrrunner.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/oeqa/utils/qemuzephyrrunner.py b/lib/oeqa/utils/qemuzephyrrunner.py
new file mode 100644
index 0000000..8021a22
--- /dev/null
+++ b/lib/oeqa/utils/qemuzephyrrunner.py
@@ -0,0 +1,131 @@
+# Copyright (C) 2015 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+# This module provides a class for starting qemu images of poky tiny.
+# It's used by testimage.bbclass.
+
+import subprocess
+import os
+import time
+import signal
+import socket
+import select
+import bb
+import tempfile
+from qemurunner import QemuRunner
+
+class QemuZephyrRunner(QemuRunner):
+
+ def __init__(self, machine, rootfs, display, tmpdir, deploy_dir_image, logfile, kernel, boottime):
+ QemuRunner.__init__(self, machine, rootfs, display, tmpdir,
+ deploy_dir_image, logfile, boottime, None,
+ None)
+
+ # Popen object for runqemu
+ self.socketfile = tempfile.NamedTemporaryFile()
+ self.socketname = self.socketfile.name
+ self.server_socket = None
+ self.kernel = kernel
+
+ def create_socket(self):
+ tries = 3
+ while tries > 0:
+ try:
+ self.server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.server_socket.connect(self.socketname)
+ bb.note("Created listening socket for qemu serial console.")
+ tries = 0
+ except socket.error, msg:
+ self.server_socket.close()
+ bb.error("Failed to create listening socket %s: %s" % (self.socketname, msg))
+ tries -= 1
+
+ def start(self, qemuparams = None):
+
+ if not os.path.exists(self.tmpdir):
+ bb.error("Invalid TMPDIR path %s" % self.tmpdir)
+ return False
+ else:
+ os.environ["OE_TMPDIR"] = self.tmpdir
+ if not os.path.exists(self.deploy_dir_image):
+ bb.error("Invalid DEPLOY_DIR_IMAGE path %s" % self.deploy_dir_image)
+ return False
+ else:
+ os.environ["DEPLOY_DIR_IMAGE"] = self.deploy_dir_image
+
+ if not os.path.exists(self.kernel):
+ bb.error("Invalid kernel path: %s" % self.deploy_dir_image)
+ return False
+
+ self.qemuparams = '-nographic -serial unix:%s,server' % (self.socketname)
+ qemu_binary = ""
+ if 'arm' in self.machine:
+ qemu_binary = 'qemu-system-arm'
+ qemu_machine_args = '-machine lm3s6965evb'
+ elif 'x86' in self.machine:
+ qemu_binary = 'qemu-system-i386'
+ qemu_machine_args = '-machine type=pc-0.14'
+
+ self.origchldhandler = signal.getsignal(signal.SIGCHLD)
+ signal.signal(signal.SIGCHLD, self.handleSIGCHLD)
+
+ launch_cmd = '%s -kernel %s %s %s' % (qemu_binary, self.kernel, self.qemuparams, qemu_machine_args)
+ bb.note(launch_cmd)
+ self.runqemu = subprocess.Popen(launch_cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,preexec_fn=os.setpgrp)
+
+ #
+ # We need the preexec_fn above so that all runqemu processes can easily be killed
+ # (by killing their process group). This presents a problem if this controlling
+ # process itself is killed however since those processes don't notice the death
+ # of the parent and merrily continue on.
+ #
+ # Rather than hack runqemu to deal with this, we add something here instead.
+ # Basically we fork off another process which holds an open pipe to the parent
+ # and also is setpgrp. If/when the pipe sees EOF from the parent dieing, it kills
+ # the process group. This is like pctrl's PDEATHSIG but for a process group
+ # rather than a single process.
+ #
+ r, w = os.pipe()
+ self.monitorpid = os.fork()
+ if self.monitorpid:
+ os.close(r)
+ self.monitorpipe = os.fdopen(w, "w")
+ else:
+ # child process
+ os.setpgrp()
+ os.close(w)
+ r = os.fdopen(r)
+ x = r.read()
+ os.killpg(os.getpgid(self.runqemu.pid), signal.SIGTERM)
+ sys.exit(0)
+
+ bb.note("qemu started, pid is %s" % self.runqemu.pid)
+ #Hack to wait for socket to show up because I'm tired
+ time.sleep(5)
+ self.create_socket()
+
+ return True
+
+ def is_alive(self):
+ if not self.runqemu:
+ return False
+ return True
+
+ def wait_for_serial(self, func_timeout, data_timeout):
+ stopread = False
+ check_endtime = False
+ self.server_socket.setblocking(0)
+ endtime = time.time() + func_timeout
+
+ while time.time() < endtime:
+ sread, _, _ = select.select([self.server_socket],[],[],data_timeout)
+ if not sread:
+ break
+ answer = self.server_socket.recv(1024)
+ if answer:
+ self.log(answer)
+ else:
+ break
+
+ return self.logfile