Blame SOURCES/kvm-scripts-qemu.py-introduce-set_console-method.patch

1bdc94
From 7d56e73ebc9b816b987f26ec66101562bdd941b8 Mon Sep 17 00:00:00 2001
1bdc94
From: Yash Mankad <ymankad@redhat.com>
1bdc94
Date: Tue, 17 Jul 2018 23:38:07 +0200
1bdc94
Subject: [PATCH 50/89] scripts/qemu.py: introduce set_console() method
1bdc94
MIME-Version: 1.0
1bdc94
Content-Type: text/plain; charset=UTF-8
1bdc94
Content-Transfer-Encoding: 8bit
1bdc94
1bdc94
RH-Author: Yash Mankad <ymankad@redhat.com>
1bdc94
Message-id: <3daef391b07eb8b66afabe66bee05749ab1a5e9a.1531870629.git.ymankad@redhat.com>
1bdc94
Patchwork-id: 81381
1bdc94
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 4/5] scripts/qemu.py: introduce set_console() method
1bdc94
Bugzilla:
1bdc94
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
1bdc94
RH-Acked-by: John Snow <jsnow@redhat.com>
1bdc94
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
1bdc94
1bdc94
From: Cleber Rosa <crosa@redhat.com>
1bdc94
1bdc94
The set_console() method is intended to ease higher level use cases
1bdc94
that require a console device.
1bdc94
1bdc94
The amount of intelligence is limited on purpose, requiring either the
1bdc94
device type explicitly, or the existence of a machine (pattern)
1bdc94
definition.
1bdc94
1bdc94
Because of the console device type selection criteria (by machine
1bdc94
type), users should also be able to define that.  It'll then be used
1bdc94
for both '-machine' and for the console device type selection.
1bdc94
1bdc94
Users of the set_console() method will certainly be interested in
1bdc94
accessing the console device, and for that a console_socket property
1bdc94
has been added.
1bdc94
1bdc94
Signed-off-by: Cleber Rosa <crosa@redhat.com>
1bdc94
Message-Id: <20180530184156.15634-5-crosa@redhat.com>
1bdc94
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
1bdc94
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
1bdc94
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
1bdc94
(cherry picked from commit 22dea9db2baf72a79782c748c57e2d87b06234d5)
1bdc94
Signed-off-by: Yash Mankad <ymankad@redhat.com>
1bdc94
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
1bdc94
---
1bdc94
 scripts/qemu.py | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1bdc94
 1 file changed, 96 insertions(+), 1 deletion(-)
1bdc94
1bdc94
diff --git a/scripts/qemu.py b/scripts/qemu.py
1bdc94
index 7cd8193..f099ce7 100644
1bdc94
--- a/scripts/qemu.py
1bdc94
+++ b/scripts/qemu.py
1bdc94
@@ -17,19 +17,41 @@ import logging
1bdc94
 import os
1bdc94
 import subprocess
1bdc94
 import qmp.qmp
1bdc94
+import re
1bdc94
 import shutil
1bdc94
+import socket
1bdc94
 import tempfile
1bdc94
 
1bdc94
 
1bdc94
 LOG = logging.getLogger(__name__)
1bdc94
 
1bdc94
 
1bdc94
+#: Maps machine types to the preferred console device types
1bdc94
+CONSOLE_DEV_TYPES = {
1bdc94
+    r'^clipper$': 'isa-serial',
1bdc94
+    r'^malta': 'isa-serial',
1bdc94
+    r'^(pc.*|q35.*|isapc)$': 'isa-serial',
1bdc94
+    r'^(40p|powernv|prep)$': 'isa-serial',
1bdc94
+    r'^pseries.*': 'spapr-vty',
1bdc94
+    r'^s390-ccw-virtio.*': 'sclpconsole',
1bdc94
+    }
1bdc94
+
1bdc94
+
1bdc94
 class QEMUMachineError(Exception):
1bdc94
     """
1bdc94
     Exception called when an error in QEMUMachine happens.
1bdc94
     """
1bdc94
 
1bdc94
 
1bdc94
+class QEMUMachineAddDeviceError(QEMUMachineError):
1bdc94
+    """
1bdc94
+    Exception raised when a request to add a device can not be fulfilled
1bdc94
+
1bdc94
+    The failures are caused by limitations, lack of information or conflicting
1bdc94
+    requests on the QEMUMachine methods.  This exception does not represent
1bdc94
+    failures reported by the QEMU binary itself.
1bdc94
+    """
1bdc94
+
1bdc94
 class MonitorResponseError(qmp.qmp.QMPError):
1bdc94
     '''
1bdc94
     Represents erroneous QMP monitor reply
1bdc94
@@ -91,6 +113,10 @@ class QEMUMachine(object):
1bdc94
         self._test_dir = test_dir
1bdc94
         self._temp_dir = None
1bdc94
         self._launched = False
1bdc94
+        self._machine = None
1bdc94
+        self._console_device_type = None
1bdc94
+        self._console_address = None
1bdc94
+        self._console_socket = None
1bdc94
 
1bdc94
         # just in case logging wasn't configured by the main script:
1bdc94
         logging.basicConfig()
1bdc94
@@ -175,9 +201,19 @@ class QEMUMachine(object):
1bdc94
                 self._monitor_address[1])
1bdc94
         else:
1bdc94
             moncdev = 'socket,id=mon,path=%s' % self._vm_monitor
1bdc94
-        return ['-chardev', moncdev,
1bdc94
+        args = ['-chardev', moncdev,
1bdc94
                 '-mon', 'chardev=mon,mode=control',
1bdc94
                 '-display', 'none', '-vga', 'none']
1bdc94
+        if self._machine is not None:
1bdc94
+            args.extend(['-machine', self._machine])
1bdc94
+        if self._console_device_type is not None:
1bdc94
+            self._console_address = os.path.join(self._temp_dir,
1bdc94
+                                                 self._name + "-console.sock")
1bdc94
+            chardev = ('socket,id=console,path=%s,server,nowait' %
1bdc94
+                       self._console_address)
1bdc94
+            device = '%s,chardev=console' % self._console_device_type
1bdc94
+            args.extend(['-chardev', chardev, '-device', device])
1bdc94
+        return args
1bdc94
 
1bdc94
     def _pre_launch(self):
1bdc94
         self._temp_dir = tempfile.mkdtemp(dir=self._test_dir)
1bdc94
@@ -202,6 +238,10 @@ class QEMUMachine(object):
1bdc94
 
1bdc94
         self._qemu_log_path = None
1bdc94
 
1bdc94
+        if self._console_socket is not None:
1bdc94
+            self._console_socket.close()
1bdc94
+            self._console_socket = None
1bdc94
+
1bdc94
         if self._temp_dir is not None:
1bdc94
             shutil.rmtree(self._temp_dir)
1bdc94
             self._temp_dir = None
1bdc94
@@ -365,3 +405,58 @@ class QEMUMachine(object):
1bdc94
         Adds to the list of extra arguments to be given to the QEMU binary
1bdc94
         '''
1bdc94
         self._args.extend(args)
1bdc94
+
1bdc94
+    def set_machine(self, machine_type):
1bdc94
+        '''
1bdc94
+        Sets the machine type
1bdc94
+
1bdc94
+        If set, the machine type will be added to the base arguments
1bdc94
+        of the resulting QEMU command line.
1bdc94
+        '''
1bdc94
+        self._machine = machine_type
1bdc94
+
1bdc94
+    def set_console(self, device_type=None):
1bdc94
+        '''
1bdc94
+        Sets the device type for a console device
1bdc94
+
1bdc94
+        If set, the console device and a backing character device will
1bdc94
+        be added to the base arguments of the resulting QEMU command
1bdc94
+        line.
1bdc94
+
1bdc94
+        This is a convenience method that will either use the provided
1bdc94
+        device type, of if not given, it will used the device type set
1bdc94
+        on CONSOLE_DEV_TYPES.
1bdc94
+
1bdc94
+        The actual setting of command line arguments will be be done at
1bdc94
+        machine launch time, as it depends on the temporary directory
1bdc94
+        to be created.
1bdc94
+
1bdc94
+        @param device_type: the device type, such as "isa-serial"
1bdc94
+        @raises: QEMUMachineAddDeviceError if the device type is not given
1bdc94
+                 and can not be determined.
1bdc94
+        '''
1bdc94
+        if device_type is None:
1bdc94
+            if self._machine is None:
1bdc94
+                raise QEMUMachineAddDeviceError("Can not add a console device:"
1bdc94
+                                                " QEMU instance without a "
1bdc94
+                                                "defined machine type")
1bdc94
+            for regex, device in CONSOLE_DEV_TYPES.items():
1bdc94
+                if re.match(regex, self._machine):
1bdc94
+                    device_type = device
1bdc94
+                    break
1bdc94
+            if device_type is None:
1bdc94
+                raise QEMUMachineAddDeviceError("Can not add a console device:"
1bdc94
+                                                " no matching console device "
1bdc94
+                                                "type definition")
1bdc94
+        self._console_device_type = device_type
1bdc94
+
1bdc94
+    @property
1bdc94
+    def console_socket(self):
1bdc94
+        """
1bdc94
+        Returns a socket connected to the console
1bdc94
+        """
1bdc94
+        if self._console_socket is None:
1bdc94
+            self._console_socket = socket.socket(socket.AF_UNIX,
1bdc94
+                                                 socket.SOCK_STREAM)
1bdc94
+            self._console_socket.connect(self._console_address)
1bdc94
+        return self._console_socket
1bdc94
-- 
1bdc94
1.8.3.1
1bdc94