From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 5128DC326 for ; Thu, 4 Jun 2015 08:28:57 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 03 Jun 2015 23:28:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,551,1427785200"; d="scan'208";a="705102912" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga001.jf.intel.com with ESMTP; 03 Jun 2015 23:28:56 -0700 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id t546Sr5u018340; Thu, 4 Jun 2015 14:28:53 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t546So3Y002371; Thu, 4 Jun 2015 14:28:53 +0800 Received: (from yliu84x@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t546So71002367; Thu, 4 Jun 2015 14:28:50 +0800 From: Yong Liu To: dts@dpdk.org Date: Thu, 4 Jun 2015 14:28:37 +0800 Message-Id: <1433399319-2314-4-git-send-email-yong.liu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1433399319-2314-1-git-send-email-yong.liu@intel.com> References: <1433399319-2314-1-git-send-email-yong.liu@intel.com> Subject: [dts] [PATCH 3/5] Optimize qemu kvm module functions and code style. X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Jun 2015 06:28:58 -0000 From: Marvin Liu 1)Support vhost net user net device options. 2)Support hugepage based memory options. 3)Add default options when qemu_kvm object initialized. 4)Fix bug in virtio-net-pci device add funtion. 5)Optimize virtual machine start and check function. 6)Optimize variable code name. 7)Remove debug function from qemu_kvm module. Signed-off-by: Marvin Liu diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py index 707dd7b..8e0582a 100644 --- a/framework/qemu_kvm.py +++ b/framework/qemu_kvm.py @@ -84,12 +84,22 @@ class QEMUKvm(VirtBase): QGA_CLI_PATH = '-r dep/QMP/' self.host_session.copy_file_to(QGA_CLI_PATH) + # charater and network device default index + self.char_idx = 0 + self.netdev_idx = 0 + def set_vm_default(self): self.set_vm_name(self.vm_name) self.set_vm_enable_kvm() self.set_vm_qga() self.set_vm_daemon() + # add default control interface + def_nic = {'type': 'nic', 'opt_vlan': '0'} + self.set_vm_net(**def_nic) + def_net = {'type': 'user', 'opt_vlan': '0'} + self.set_vm_net(**def_net) + def init_vm_request_resource(self): """ initialize some resource used by VM. @@ -129,12 +139,12 @@ class QEMUKvm(VirtBase): out = self.host_session.send_expect( 'ls %s' % qemu_emulator_path, '[.*') if 'No such file or directory' in out: - self.host_logger.error("No emulator [ %s ] on the DUT [ %s ]" % \ + self.host_logger.error("No emulator [ %s ] on the DUT [ %s ]" % (qemu_emulator, self.host_dut.get_ip_address())) return None out = self.host_session.send_expect("[ -x %s ];echo $?" % qemu_emulator_path, '# ') if out == '1': - self.host_logger.error("Emulator [ %s ] not executable on the DUT [ %s ]" % \ + self.host_logger.error("Emulator [ %s ] not executable on the DUT [ %s ]" % (qemu_emulator, self.host_dut.get_ip_address())) return None self.qemu_emulator = qemu_emulator @@ -250,6 +260,15 @@ class QEMUKvm(VirtBase): if 'size' in options.keys(): mem_boot_line = '-m %s' % options['size'] self.__add_boot_line(mem_boot_line) + if 'hugepage' in options.keys(): + if options['hugepage'] == 'yes': + mem_boot_huge = '-object memory-backend-file,' \ + + 'id=mem,size=%sM,mem-path=%s,share=on' \ + % (options['size'], self.host_dut.hugepage_path) + + self.__add_boot_line(mem_boot_huge) + mem_boot_huge_opt = "-numa node,memdev=mem -mem-prealloc" + self.__add_boot_line(mem_boot_huge_opt) def add_vm_disk(self, **options): """ @@ -259,6 +278,13 @@ class QEMUKvm(VirtBase): disk_boot_line = '-drive file=%s' % options['file'] self.__add_boot_line(disk_boot_line) + def set_vm_net(self, **options): + index = self.find_option_index('net') + if index: + self.params[index]['net'].append(options) + else: + self.params.append({'net': [options]}) + def add_vm_net(self, **options): """ Add VM net device. @@ -471,22 +497,22 @@ class QEMUKvm(VirtBase): self.host_session.send_expect( 'chmod +x %s' % self.QEMU_IFUP_PATH, '# ') - def set_vm_device(self, driver='pci-assign', **props): + def set_vm_device(self, driver='pci-assign', **opts): """ Set VM device with specified driver. """ - props['driver'] = driver + opts['driver'] = driver index = self.find_option_index('device') if index: - self.params[index]['device'].append(props) + self.params[index]['device'].append(opts) else: - self.params.append({'device': [props]}) + self.params.append({'device': [opts]}) def add_vm_device(self, **options): """ driver: [pci-assign | virtio-net-pci | ...] - prop_[host | addr | ...]: value - note:the sub-property will be decided according to the driver. + opt_[host | addr | ...]: value + note:the sub-opterty will be decided according to the driver. """ if 'driver' in options.keys() and \ options['driver']: @@ -494,54 +520,84 @@ class QEMUKvm(VirtBase): self.__add_vm_pci_assign(**options) elif options['driver'] == 'virtio-net-pci': self.__add_vm_virtio_net_pci(**options) + elif options['driver'] == 'vhost-user': + self.__add_vm_virtio_user_pci(**options) def __add_vm_pci_assign(self, **options): """ driver: pci-assign - prop_host: 08:00.0 - prop_addr: 00:00:00:00:01:02 + opt_host: 08:00.0 + opt_addr: 00:00:00:00:01:02 """ dev_boot_line = '-device pci-assign' separator = ',' - if 'prop_host' in options.keys() and \ - options['prop_host']: - dev_boot_line += separator + 'host=%s' % options['prop_host'] - if 'prop_addr' in options.keys() and \ - options['prop_addr']: - dev_boot_line += separator + 'addr=%s' % options['prop_addr'] - self.assigned_pcis.append(options['prop_addr']) + if 'opt_host' in options.keys() and \ + options['opt_host']: + dev_boot_line += separator + 'host=%s' % options['opt_host'] + if 'opt_addr' in options.keys() and \ + options['opt_addr']: + dev_boot_line += separator + 'addr=%s' % options['opt_addr'] + self.assigned_pcis.append(options['opt_addr']) if self.__string_has_multi_fields(dev_boot_line, separator): self.__add_boot_line(dev_boot_line) + def __add_vm_virtio_user_pci(self, **options): + """ + driver virtio-net-pci + opt_path: /tmp/vhost-net + opt_mac: 00:00:20:00:00:00 + """ + separator = ',' + # chardev parameter + if 'opt_path' in options.keys() and \ + options['opt_path']: + dev_boot_line = '-chardev socket' + char_id = 'char%d' % self.char_idx + dev_boot_line += separator + 'id=%s' % char_id + separator + 'path=%s' % options['opt_path'] + self.char_idx += 1 + self.__add_boot_line(dev_boot_line) + # netdev parameter + netdev_id = 'netdev%d' % self.netdev_idx + self.netdev_idx += 1 + dev_boot_line = '-netdev type=vhost-user,id=%s,chardev=%s,vhostforce' % (netdev_id, char_id) + self.__add_boot_line(dev_boot_line) + # device parameter + opts = {'opt_netdev': '%s' % netdev_id} + if 'opt_mac' in options.keys() and \ + options['opt_mac']: + opts['opt_mac'] = options['opt_mac'] + + self.__add_vm_virtio_net_pci(**opts) + def __add_vm_virtio_net_pci(self, **options): """ driver: virtio-net-pci - prop_netdev: mynet1 - prop_id: net1 - prop_mac: 00:00:00:00:01:03 - prop_bus: pci.0 - prop_addr: 0x3 + opt_netdev: mynet1 + opt_id: net1 + opt_mac: 00:00:00:00:01:03 + opt_bus: pci.0 + opt_addr: 0x3 """ dev_boot_line = '-device virtio-net-pci' separator = ',' - if 'prop_netdev' in options.keys() and \ - options['prop_netdev']: - dev_boot_line += separator + 'netdev=%s' % options['prop_netdev'] - if 'prop_id' in options.keys() and \ - options['prop_id']: - dev_boot_line += separator + 'id=%s' % options['prop_id'] - if 'prop_mac' in options.keys() and \ - options['prop_mac']: - dev_boot_line += separator + 'mac=%s' % options['prop_mac'] - if 'prop_bus' in options.keys() and \ - options['prop_bus']: - dev_boot_line += separator + 'bus=%s' % options['prop_bus'] - if 'prop_addr' in options.keys() and \ - options['prop_addr']: - dev_boot_line += separator + 'addr=%s' % options['prop_addr'] - - if self.__string_has_multi_fields(self, string, separator): + if 'opt_netdev' in options.keys() and \ + options['opt_netdev']: + dev_boot_line += separator + 'netdev=%s' % options['opt_netdev'] + if 'opt_id' in options.keys() and \ + options['opt_id']: + dev_boot_line += separator + 'id=%s' % options['opt_id'] + if 'opt_mac' in options.keys() and \ + options['opt_mac']: + dev_boot_line += separator + 'mac=%s' % options['opt_mac'] + if 'opt_bus' in options.keys() and \ + options['opt_bus']: + dev_boot_line += separator + 'bus=%s' % options['opt_bus'] + if 'opt_addr' in options.keys() and \ + options['opt_addr']: + dev_boot_line += separator + 'addr=%s' % options['opt_addr'] + + if self.__string_has_multi_fields(dev_boot_line, separator): self.__add_boot_line(dev_boot_line) def __string_has_multi_fields(self, string, separator, field_num=2): @@ -665,11 +721,15 @@ class QEMUKvm(VirtBase): qemu_boot_line = self.generate_qemu_boot_line() - # Start VM using the qemu command + # Start VM using the qemu command ret = self.host_session.send_expect(qemu_boot_line, '# ', verify=True) - time.sleep(30) if type(ret) is int and ret != 0: raise StartVMFailedException('Start VM failed!!!') + out = self.__control_session('ping', '120') + if "Not responded" in out: + raise StartVMFailedException('Not response in 60 seconds!!!') + + self.__wait_vmnet_ready() def generate_qemu_boot_line(self): """ @@ -690,6 +750,21 @@ class QEMUKvm(VirtBase): return qemu_boot_line + def __wait_vmnet_ready(self): + """ + wait for 120 seconds for vm net ready + 10.0.2.* is the default ip address allocated by qemu + """ + count = 20 + while count: + out = self.__control_session('ifconfig') + if "10.0.2" in out: + return True + time.sleep(6) + count -= 1 + + raise StartVMFailedException('Virtual machine control net not ready in 120 seconds!!!') + def __alloc_vcpus(self): """ Allocate virtual CPUs for VM. @@ -698,8 +773,8 @@ class QEMUKvm(VirtBase): cpus = self.virt_pool.alloc_cpu(vm=self.vm_name, corelist=req_cpus) if len(req_cpus) != len(cpus): - self.host_logger.warn("VCPUs not enough, required [ %s ], just [ %s ]" % \ - (req_cpus, cpus)) + self.host_logger.warn("VCPUs not enough, required [ %s ], just [ %s ]" % + (req_cpus, cpus)) raise Exception("No enough required vcpus!!!") vcpus_pinned_to_vm = '' @@ -853,7 +928,10 @@ class QEMUKvm(VirtBase): for arg in args: cmd = cmd_head + ' ' + str(arg) - out = self.host_session.send_expect(cmd, '# ') + if command is "ping": + out = self.host_session.send_expect(cmd, '# ', int(args[0])) + else: + out = self.host_session.send_expect(cmd, '# ') return out @@ -864,109 +942,3 @@ class QEMUKvm(VirtBase): self.__control_session('powerdown') time.sleep(5) self.virt_pool.free_all_resource(self.vm_name) - - -if __name__ == "__main__": - import subprocess - import sys - from serializer import Serializer - from crbs import crbs - from tester import Tester - from dut import Dut - import dts - from virt_proxy import VirtProxy - - command = "ifconfig br0" - subp = subprocess.Popen(command.split(), stdout=subprocess.PIPE) - subp.wait() - - intf_info = subp.stdout.readlines() - for line_info in intf_info: - regx = re.search(r'inet (\d+\.\d+\.\d+\.\d+)', line_info) - if regx: - dutIP = regx.group(1) - break - - print "DEBUG: dutIp: ", dutIP - - # look up in crbs - to find the matching IP - crbInst = None - for crb in crbs: - if crb['IP'] == dutIP: - crbInst = crb - break - - # only run on the dut in known crbs - if crbInst is None: - raise Exception("No available crb instance!!!") - - # initialize the dut and tester - serializer = Serializer() - serializer.set_serialized_filename('../.%s.cache' % crbInst['IP']) - serializer.load_from_file() - - read_cache = None - skip_setup = None - - project = "dpdk" - dts.Package = 'dep/dpdk.tar.gz' - dut = dts.get_project_obj(project, Dut, crbInst, serializer) - tester = dts.get_project_obj(project, Tester, crbInst, serializer) - dut.tester = tester - dut.base_dir = 'dpdk' - dut.set_nic_type('niantic') - tester.dut = dut - - tester.set_test_types(True, False) - dut.set_test_types(True, False) - - tester.set_speedup_options(read_cache, skip_setup) - tester.tester_prerequisites() - dut.set_speedup_options(read_cache, skip_setup) - dut.dut_prerequisites() - - # test that generating and destroying VF - port0 = dut.ports_info[0]['port'] - dut.generate_sriov_vfs_by_port(0, 4) - print "port 0 sriov vfs: ", dut.ports_info[0] - - dut.destroy_sriov_vfs_by_port(0) - - time.sleep(2) - - # test that binding and unbing the NIC - port0_pci = dut.ports_info[0]['pci'] - port0.unbind_driver() - - dut.logger.info("JUST TESTING!!!") - - # Start VM by the qemu kvm config file - vm1 = QEMUKvm(dut, 'vm1', 'pmd_sriov') - print "VM config params:" - print vm1.params - vm1_dut = vm1.start() - - try: - host_ip = vm1.session.send_expect("ifconfig", '# ') - print "Host IP:" - print host_ip - - vm1_ip = vm1.get_vm_ip() - print "VM1 IP:" - print vm1_ip - - print "VM1 PCI device:" - print vm_dut.session.send_expect('lspci -nn | grep -i eth', '# ') - except Exception as e: - print e - vm1_dut.stop() - port0.bind_driver() - # Stop VM - vm1.stop() - port0.bind_driver() - - dut.host_logger.logger_exit() - dut.logger.logger_exit() - tester.logger.logger_exit() - - print "Start and stop VM over!" -- 1.9.3