From 1148dbc48e6703e757d7286f39ee28da7e5f1584 Mon Sep 17 00:00:00 2001 From: grossmj Date: Fri, 30 Dec 2022 20:54:37 +0800 Subject: [PATCH] Fix issue when calling reset_console with running VPCS and Qemu nodes. Ref #1619 --- gns3server/compute/base_node.py | 14 +++++--------- gns3server/compute/dynamips/nodes/router.py | 8 +++++++- gns3server/compute/qemu/qemu_vm.py | 9 +++++++++ gns3server/compute/vpcs/vpcs_vm.py | 9 +++++++++ gns3server/utils/asyncio/telnet_server.py | 4 ++++ 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index a7b244cd..cf171a32 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -386,7 +386,11 @@ class BaseNode: await AsyncioTelnetServer.write_client_intro(writer, echo=True) server = AsyncioTelnetServer(reader=reader, writer=writer, binary=True, echo=True) # warning: this will raise OSError exception if there is a problem... - self._wrapper_telnet_server = await asyncio.start_server(server.run, self._manager.port_manager.console_host, self.console) + self._wrapper_telnet_server = await asyncio.start_server( + server.run, + self._manager.port_manager.console_host, + self.console + ) async def stop_wrap_console(self): """ @@ -397,14 +401,6 @@ class BaseNode: self._wrapper_telnet_server.close() await self._wrapper_telnet_server.wait_closed() - async def reset_console(self): - """ - Reset console - """ - - await self.stop_wrap_console() - await self.start_wrap_console() - async def start_websocket_console(self, request): """ Connect to console using Websocket. diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index 23fc7b59..e9fe08ef 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -977,7 +977,6 @@ class Router(BaseNode): raise DynamipsError('"{name}" must be stopped to change the console type to {console_type}'.format(name=self._name, console_type=console_type)) - self.console_type = console_type if self._console and console_type == "telnet": @@ -993,6 +992,13 @@ class Router(BaseNode): self.aux = aux await self._hypervisor.send('vm set_aux_tcp_port "{name}" {aux}'.format(name=self._name, aux=aux)) + async def reset_console(self): + """ + Reset console + """ + + pass # reset console is not supported with Dynamips + async def get_cpu_usage(self, cpu_id=0): """ Shows cpu usage in seconds, "cpu_id" is ignored. diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 662f07b7..22c75159 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -1567,6 +1567,15 @@ class QemuVM(BaseNode): self._process = None return False + async def reset_console(self): + """ + Reset console + """ + + await self.stop_wrap_console() + if self.is_running(): + await self.start_wrap_console() + def command(self): """ Returns the QEMU command line. diff --git a/gns3server/compute/vpcs/vpcs_vm.py b/gns3server/compute/vpcs/vpcs_vm.py index ec7a47f3..9b88f94f 100644 --- a/gns3server/compute/vpcs/vpcs_vm.py +++ b/gns3server/compute/vpcs/vpcs_vm.py @@ -344,6 +344,15 @@ class VPCSVM(BaseNode): return True return False + async def reset_console(self): + """ + Reset console + """ + + await self.stop_wrap_console() + if self.is_running(): + await self.start_wrap_console() + @BaseNode.console_type.setter def console_type(self, new_console_type): """ diff --git a/gns3server/utils/asyncio/telnet_server.py b/gns3server/utils/asyncio/telnet_server.py index 9580d899..373d324f 100644 --- a/gns3server/utils/asyncio/telnet_server.py +++ b/gns3server/utils/asyncio/telnet_server.py @@ -189,6 +189,7 @@ class AsyncioTelnetServer: sock = network_writer.get_extra_info("socket") sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #log.debug("New connection from {}".format(sock.getpeername())) # Keep track of connected clients @@ -202,6 +203,7 @@ class AsyncioTelnetServer: except ConnectionError: async with self._lock: network_writer.close() + await network_writer.wait_closed() if self._reader_process == network_reader: self._reader_process = None # Cancel current read from this reader @@ -216,6 +218,8 @@ class AsyncioTelnetServer: try: writer.write_eof() await writer.drain() + writer.close() + await writer.wait_closed() except (AttributeError, ConnectionError): continue