[PATCH v2 01/13] hyperv: XML parsing of serial ports

Matt Coleman mcoleman at datto.com
Tue Feb 2 00:48:36 UTC 2021


Co-authored-by: Sri Ramanujam <sramanujam at datto.com>
Signed-off-by: Matt Coleman <matt at datto.com>
---
 src/hyperv/hyperv_driver.c            | 61 +++++++++++++++++++++++++++
 src/hyperv/hyperv_wmi.c               | 10 +++++
 src/hyperv/hyperv_wmi.h               |  4 ++
 src/hyperv/hyperv_wmi_classes.h       |  1 +
 src/hyperv/hyperv_wmi_generator.input |  5 +++
 5 files changed, 81 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index bdc084790a..9902fa75b8 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1253,6 +1253,54 @@ hypervDomainDefParseStorage(hypervPrivate *priv,
 }
 
 
+static int
+hypervDomainDefParseSerial(virDomainDefPtr def, Msvm_ResourceAllocationSettingData *rasd)
+{
+    while (rasd) {
+        if (rasd->data->ResourceType == MSVM_RASD_RESOURCETYPE_SERIAL_PORT) {
+            int port_num = 0;
+            char **conn = NULL;
+            const char *srcPath = NULL;
+            virDomainChrDefPtr serial = NULL;
+
+            /* get port number */
+            port_num = rasd->data->ElementName[4] - '0';
+            if (port_num < 1) {
+                rasd = rasd->next;
+                continue;
+            }
+
+            serial = virDomainChrDefNew(NULL);
+
+            serial->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
+            serial->source->type = VIR_DOMAIN_CHR_TYPE_PIPE;
+            serial->target.port = port_num;
+
+            /* set up source */
+            if (rasd->data->Connection.count < 1) {
+                srcPath = "-1";
+            } else {
+                conn = rasd->data->Connection.data;
+                if (!*conn)
+                    srcPath = "-1";
+                else
+                    srcPath = *conn;
+            }
+
+            serial->source->data.file.path = g_strdup(srcPath);
+
+            if (VIR_APPEND_ELEMENT(def->serials, def->nserials, serial) < 0) {
+                virDomainChrDefFree(serial);
+                return -1;
+            }
+        }
+
+        rasd = rasd->next;
+    }
+
+    return 0;
+}
+
 
 /*
  * Driver functions
@@ -2113,6 +2161,8 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
     g_autoptr(Msvm_MemorySettingData) memorySettingData = NULL;
     g_autoptr(Msvm_ResourceAllocationSettingData) rasd = NULL;
     g_autoptr(Msvm_StorageAllocationSettingData) sasd = NULL;
+    g_autoptr(Msvm_SerialPortSettingData) spsd = NULL;
+    Msvm_ResourceAllocationSettingData *serialDevices = NULL;
 
     virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL);
 
@@ -2151,6 +2201,9 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
         return NULL;
     }
 
+    if (hypervGetSerialPortSD(priv, virtualSystemSettingData->data->InstanceID, &spsd) < 0)
+        return NULL;
+
     /* Fill struct */
     def->virtType = VIR_DOMAIN_VIRT_HYPERV;
 
@@ -2215,6 +2268,14 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
     if (hypervDomainDefParseStorage(priv, def, rasd, sasd) < 0)
         return NULL;
 
+    if (g_str_has_prefix(priv->version, "6."))
+        serialDevices = rasd;
+    else
+        serialDevices = (Msvm_ResourceAllocationSettingData *)spsd;
+
+    if (hypervDomainDefParseSerial(def, serialDevices) < 0)
+        return NULL;
+
     /* XXX xmlopts must be non-NULL */
     return virDomainDefFormat(def, NULL, virDomainDefFormatConvertXMLFlags(flags));
 }
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index a28bb0e815..f5f0797605 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -1488,6 +1488,16 @@ hypervGetStorageAllocationSD(hypervPrivate *priv,
 }
 
 
+int
+hypervGetSerialPortSD(hypervPrivate *priv,
+                      const char *id,
+                      Msvm_SerialPortSettingData **data)
+{
+    hypervGetSettingData(Msvm_SerialPortSettingData, id, data);
+    return 0;
+}
+
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * Msvm_VirtualSystemManagementService
  */
diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
index f09948895e..2b0d0e4a3f 100644
--- a/src/hyperv/hyperv_wmi.h
+++ b/src/hyperv/hyperv_wmi.h
@@ -254,6 +254,10 @@ int hypervGetStorageAllocationSD(hypervPrivate *priv,
                                  const char *id,
                                  Msvm_StorageAllocationSettingData **data);
 
+int hypervGetSerialPortSD(hypervPrivate *priv,
+                          const char *id,
+                          Msvm_SerialPortSettingData **data);
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * Msvm_VirtualSystemManagementService
  */
diff --git a/src/hyperv/hyperv_wmi_classes.h b/src/hyperv/hyperv_wmi_classes.h
index 2c03ca3745..2f813bedb3 100644
--- a/src/hyperv/hyperv_wmi_classes.h
+++ b/src/hyperv/hyperv_wmi_classes.h
@@ -113,6 +113,7 @@ enum _Msvm_ResourceAllocationSettingData_ResourceType {
     MSVM_RASD_RESOURCETYPE_DVD_DRIVE = 16,
     MSVM_RASD_RESOURCETYPE_DISK_DRIVE = 17,
     MSVM_RASD_RESOURCETYPE_STORAGE_EXTENT = 19,
+    MSVM_RASD_RESOURCETYPE_SERIAL_PORT = 21,
     MSVM_RASD_RESOURCETYPE_LOGICAL_DISK = 31,
 };
 
diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input
index e1b4fd3f9f..765ffba169 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -629,6 +629,11 @@ class Msvm_ResourceAllocationSettingData
 end
 
 
+class Msvm_SerialPortSettingData : Msvm_ResourceAllocationSettingData
+    boolean  DebuggerMode
+end
+
+
 class Msvm_Keyboard
     string   InstanceID
     string   Caption
-- 
2.30.0





More information about the libvir-list mailing list