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 58F6D42B6F; Mon, 22 May 2023 10:31:18 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 532B6410DD; Mon, 22 May 2023 10:31:18 +0200 (CEST) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mails.dpdk.org (Postfix) with ESMTP id 588A6410D1 for ; Mon, 22 May 2023 10:31:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1684744277; x=1716280277; h=from:to:cc:subject:date:message-id; bh=wcUYohRlesmnp4e2yAq17AdRoS4imngDXLvStg/avXQ=; b=cV7TJN0SBOiFxf9WGkqblizjIRvsJ3YZ1u/639ECw+eP659EIqO3g6Mz G574alHIIRF7kytRKR8Zr5e70qhGSwytiD2tExm4LXT9D467qa3I02qZ/ JCvUDXPVD2M4xbeWo0bgUAcIsE2c7s3A7SZTSExAk8i5XrPXVlHXPshsw SdA1ew8/stDNAsglShQ20Iq/6JAblGUHH65ZVrGAiG8tjcOXlXsnR9stG RoWCGHckZrNM/sfoQMbvxxXM6x90s2zpFyxqpJe6xt7V7c6uBh3mBaQqj 7kn/+KvHg+49X2hnNA0baUecuD37uwwjO41d58Ogn1cu+0Je1W41l+JcY A==; X-IronPort-AV: E=McAfee;i="6600,9927,10717"; a="439216156" X-IronPort-AV: E=Sophos;i="6.00,183,1681196400"; d="scan'208";a="439216156" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 01:31:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10717"; a="877682387" X-IronPort-AV: E=Sophos;i="6.00,183,1681196400"; d="scan'208";a="877682387" Received: from unknown (HELO localhost.localdomain) ([10.239.252.161]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 May 2023 01:31:14 -0700 From: Daxue Gao To: dts@dpdk.org Cc: Daxue Gao Subject: [PATCH v2] framework: fix container vm port conflict Date: Mon, 22 May 2023 16:31:17 +0800 Message-Id: <20230522083117.8835-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 | 12 ++++++++++++ framework/qemu_kvm.py | 25 ++++++++++++++++++++----- framework/virt_base.py | 7 +++---- framework/virt_resource.py | 12 ++++++------ 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/framework/exception.py b/framework/exception.py index fb0fa72e..e8659bd1 100644 --- a/framework/exception.py +++ b/framework/exception.py @@ -146,3 +146,15 @@ 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