From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4318D42B6F; Mon, 22 May 2023 10:10:21 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 18E7E410DD; Mon, 22 May 2023 10:10:21 +0200 (CEST) Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by mails.dpdk.org (Postfix) with ESMTP id C3ADE410D1 for ; Mon, 22 May 2023 10:10:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1684743018; x=1716279018; h=from:to:cc:subject:date:message-id; bh=bwtiADQ0W90M23n2WIniVdvFQRbXZX6LuHcb0t5Q89o=; b=Y5sjYQJfB3RsmbFMRNC7W8QlN5Hmjdscn0ELZj46wKAGnWHUe7wLVyVC KAqu99cQjKnvX8akKVa9IM2YAfKgoF6uGyOxn0rzlCKJJ74DYCQdhnSLK 9EFSC5aCXWKf3SfOjmZgOz7zIugZTxPvvBSV3FknzgaKNVWfk7wGYtCUs bwq1/DWSN9JKObOksFXIpX3ZRLhYsmO40lLXnyi7UqLgNdFsTzfaIluzI x5E5eEGxL/N1uV6UQOjjb4pLOTP71K1sy1J6BRI0KqdGxNDwR5Bp0Undy mb2x4XzkL4MJ1PwptifB94+uYD1CQZ1zwVj23GSa65vO7a0GEdeguJHJ4 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10717"; a="416321750" X-IronPort-AV: E=Sophos;i="6.00,183,1681196400"; d="scan'208";a="416321750" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 01:10:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10717"; a="1033524865" X-IronPort-AV: E=Sophos;i="6.00,183,1681196400"; d="scan'208";a="1033524865" Received: from unknown (HELO localhost.localdomain) ([10.239.252.161]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 01:10:16 -0700 From: Daxue Gao To: dts@dpdk.org Cc: Daxue Gao Subject: [PATCH v1] framework: fix container vm port conflict Date: Mon, 22 May 2023 16:10:16 +0800 Message-Id: <20230522081016.6430-1-daxuex.gao@intel.com> X-Mailer: git-send-email 2.17.1 X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dts-bounces@dpdk.org Fix the problem that the container vm port conflict causes the vm to fail to start. Capture the port conflict by exception, and assign a new port number to start the vm. The port conflict includes tcp forward/vnc/telnet/migrate port. Signed-off-by: Daxue Gao --- framework/exception.py | 11 +++++++++++ framework/qemu_kvm.py | 25 ++++++++++++++++++++----- framework/virt_base.py | 7 +++---- framework/virt_resource.py | 12 ++++++------ 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/framework/exception.py b/framework/exception.py index fb0fa72e..09012d43 100644 --- a/framework/exception.py +++ b/framework/exception.py @@ -146,3 +146,14 @@ class VirtVmOperationException(Exception): class VirtHostPrepareException(Exception): pass + + +class VmPortConflictException(Exception): + """ + Start VM vnc port or vm port conflict failed. + """ + def __init__(self, error): + self.error = error + + def __str__(self): + pass diff --git a/framework/qemu_kvm.py b/framework/qemu_kvm.py index 0131abcc..b656675c 100644 --- a/framework/qemu_kvm.py +++ b/framework/qemu_kvm.py @@ -6,7 +6,7 @@ import os import re import time -from .exception import StartVMFailedException +from .exception import StartVMFailedException, VmPortConflictException from .settings import DTS_PARALLEL_SETTING, get_host_ip, load_global_setting from .utils import RED, parallel_lock from .virt_base import ST_NOTSTART, ST_PAUSE, ST_RUNNING, ST_UNKNOWN, VirtBase @@ -1404,16 +1404,20 @@ class QEMUKvm(VirtBase): @parallel_lock(num=4) def __send_qemu_cmd(self, qemu_boot_line, dut_id): # add more time for qemu start will be slow when system is busy - ret = self.host_session.send_expect( - qemu_boot_line, "# ", verify=True, timeout=30 - ) + ret = self.host_session.send_expect(qemu_boot_line, "# ", timeout=30) + ret_status = int(self.host_session.send_expect("echo $?", "#", timeout=30)) # record start time self.start_time = time.time() # wait for qemu process ready time.sleep(2) - if type(ret) is int and ret != 0: + if type(ret_status) is int and ret_status != 0: + if self.vm_port_conflict(ret): + self.qemu_boot_line = "" + self.pt_idx = 0 + delattr(self, "hostfwd_addr") + raise VmPortConflictException(self) raise StartVMFailedException("Start VM failed!!!") def _quick_start_vm(self): @@ -2043,3 +2047,14 @@ class QEMUKvm(VirtBase): map = list(zip(threads, lcores)) for thread, lcore in map: self.host_session.send_expect("taskset -pc %s %s" % (lcore, thread), "#") + + def vm_port_conflict(self, ret): + """ + check for vm port conflict + """ + status = None + if "Could not set up host forwarding rule" in ret: + status = True + elif "Failed to find an available port: Address already in use" in ret: + status = True + return status diff --git a/framework/virt_base.py b/framework/virt_base.py index 24f50d0f..e8c34b09 100644 --- a/framework/virt_base.py +++ b/framework/virt_base.py @@ -279,6 +279,7 @@ class VirtBase(object): """ Start VM and instantiate the VM with VirtDut. """ + vm_dut = None try: if load_config is True: self.load_config() @@ -293,9 +294,8 @@ class VirtBase(object): vm_dut = self.instantiate_vm_dut( set_target, cpu_topo, bind_dev=bind_dev, autodetect_topo=True ) - else: - vm_dut = None - + except exception.VmPortConflictException: + vm_dut = self.start() except Exception as vm_except: if self.handle_exception(vm_except): print(utils.RED("Handled exception " + str(type(vm_except)))) @@ -305,7 +305,6 @@ class VirtBase(object): if callable(self.callback): self.callback() - return None return vm_dut def quick_start(self, load_config=True, set_target=True, cpu_topo=""): diff --git a/framework/virt_resource.py b/framework/virt_resource.py index 3bc4b87b..231cdebc 100644 --- a/framework/virt_resource.py +++ b/framework/virt_resource.py @@ -2,7 +2,7 @@ # Copyright(c) 2010-2015 Intel Corporation # -from random import randint +from random import randint, randrange from .utils import RED, get_obj_funcs, parallel_lock @@ -344,15 +344,15 @@ class VirtResource(object): if vm == "": print("Alloc host port request vitual machine name!!!") return None - + offset = randrange(0, 1000, 200) if port_type == "connect": - port = INIT_FREE_PORT + port = INIT_FREE_PORT + offset elif port_type == "serial": - port = INIT_SERIAL_PORT + port = INIT_SERIAL_PORT + offset elif port_type == "migrate": - port = INIT_MIGRATE_PORT + port = INIT_MIGRATE_PORT + offset elif port_type == "display": - port = INIT_DISPLAY_PORT + 5900 + port = INIT_DISPLAY_PORT + 5900 + offset while True: if ( -- 2.17.1