cryptospore / rpms / qemu-kvm

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