test suite reviews and discussions
 help / color / mirror / Atom feed
* [PATCH v2] framework: fix container vm port conflict
@ 2023-05-22  8:31 Daxue Gao
  2023-05-25  2:32 ` lijuan.tu
  0 siblings, 1 reply; 2+ messages in thread
From: Daxue Gao @ 2023-05-22  8:31 UTC (permalink / raw)
  To: dts; +Cc: Daxue Gao

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 <daxuex.gao@intel.com>
---
 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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-05-25  2:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-22  8:31 [PATCH v2] framework: fix container vm port conflict Daxue Gao
2023-05-25  2:32 ` lijuan.tu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).