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

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