xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oeqa/core/target/qemu.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1#
2# Copyright (C) 2016 Intel Corporation
3#
4# SPDX-License-Identifier: MIT
5#
6
7import os
8import sys
9import signal
10import time
11import glob
12import subprocess
13from collections import defaultdict
14
15from .ssh import OESSHTarget
16from oeqa.utils.qemurunner import QemuRunner
17from oeqa.utils.dump import MonitorDumper
18from oeqa.utils.dump import TargetDumper
19
20supported_fstypes = ['ext3', 'ext4', 'cpio.gz', 'wic']
21
22class OEQemuTarget(OESSHTarget):
23    def __init__(self, logger, server_ip, timeout=300, user='root',
24            port=None, machine='', rootfs='', kernel='', kvm=False, slirp=False,
25            dump_dir='', dump_host_cmds='', display='', bootlog='',
26            tmpdir='', dir_image='', boottime=60, serial_ports=2,
27            boot_patterns = defaultdict(str), ovmf=False, tmpfsdir=None, **kwargs):
28
29        super(OEQemuTarget, self).__init__(logger, None, server_ip, timeout,
30                user, port)
31
32        self.server_ip = server_ip
33        self.server_port = 0
34        self.machine = machine
35        self.rootfs = rootfs
36        self.kernel = kernel
37        self.kvm = kvm
38        self.ovmf = ovmf
39        self.use_slirp = slirp
40        self.boot_patterns = boot_patterns
41        self.dump_dir = dump_dir
42        self.bootlog = bootlog
43
44        self.runner = QemuRunner(machine=machine, rootfs=rootfs, tmpdir=tmpdir,
45                                 deploy_dir_image=dir_image, display=display,
46                                 logfile=bootlog, boottime=boottime,
47                                 use_kvm=kvm, use_slirp=slirp, dump_dir=dump_dir,
48                                 dump_host_cmds=dump_host_cmds, logger=logger,
49                                 serial_ports=serial_ports, boot_patterns = boot_patterns,
50                                 use_ovmf=ovmf, tmpfsdir=tmpfsdir)
51        dump_monitor_cmds = kwargs.get("testimage_dump_monitor")
52        self.monitor_dumper = MonitorDumper(dump_monitor_cmds, dump_dir, self.runner)
53        if self.monitor_dumper:
54            self.monitor_dumper.create_dir("qmp")
55
56        dump_target_cmds = kwargs.get("testimage_dump_target")
57        self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner)
58        self.target_dumper.create_dir("qemu")
59
60    def start(self, params=None, extra_bootparams=None, runqemuparams=''):
61        if self.use_slirp and not self.server_ip:
62            self.logger.error("Could not start qemu with slirp without server ip - provide 'TEST_SERVER_IP'")
63            raise RuntimeError("FAILED to start qemu - check the task log and the boot log")
64        if self.runner.start(params, extra_bootparams=extra_bootparams, runqemuparams=runqemuparams):
65            self.ip = self.runner.ip
66            if self.use_slirp:
67                target_ip_port = self.runner.ip.split(':')
68                if len(target_ip_port) == 2:
69                    target_ip = target_ip_port[0]
70                    port = target_ip_port[1]
71                    self.ip = target_ip
72                    self.ssh = self.ssh + ['-p', port]
73                    self.scp = self.scp + ['-P', port]
74                else:
75                    self.logger.error("Could not get host machine port to connect qemu with slirp, ssh will not be "
76                                      "able to connect to qemu with slirp")
77            if self.runner.server_ip:
78                self.server_ip = self.runner.server_ip
79        else:
80            self.stop()
81            # Display the first 20 lines of top and
82            # last 20 lines of the bootlog when the
83            # target is not being booted up.
84            topfile = glob.glob(self.dump_dir + "/*_qemu/host_*_top")
85            msg = "\n\n===== start: snippet =====\n\n"
86            for f in topfile:
87                msg += "file: %s\n\n" % f
88                with open(f) as tf:
89                    for x in range(20):
90                        msg += next(tf)
91            msg += "\n\n===== end: snippet =====\n\n"
92            blcmd = ["tail", "-20", self.bootlog]
93            msg += "===== start: snippet =====\n\n"
94            try:
95                out = subprocess.check_output(blcmd, stderr=subprocess.STDOUT, timeout=1).decode('utf-8')
96                msg += "file: %s\n\n" % self.bootlog
97                msg += out
98            except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError) as err:
99                msg += "Error running command: %s\n%s\n" % (blcmd, err)
100            msg += "\n\n===== end: snippet =====\n"
101
102            raise RuntimeError("FAILED to start qemu - check the task log and the boot log %s" % (msg))
103
104    def stop(self):
105        self.runner.stop()
106