[PATCH 02/12] hyperv: add support for creating serial devices

Matt Coleman mcoleman at datto.com
Fri Jan 22 20:18:33 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 | 92 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 9bbbcfc88c..9394794c8f 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -899,6 +899,85 @@ hypervDomainAttachStorage(virDomainPtr domain, virDomainDefPtr def, const char *
 }
 
 
+static int
+hypervDomainAttachSerial(virDomainPtr domain, virDomainChrDefPtr serial)
+{
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    g_autofree char *com_string = g_strdup_printf("COM %d", serial->target.port);
+    g_autoptr(Msvm_VirtualSystemSettingData) vssd = NULL;
+    g_autoptr(Msvm_ResourceAllocationSettingData) rasd = NULL;
+    g_autoptr(Msvm_SerialPortSettingData) spsd = NULL;
+    hypervWmiClassInfoPtr classInfo = NULL;
+    Msvm_ResourceAllocationSettingData *current = NULL;
+    Msvm_ResourceAllocationSettingData *entry = NULL;
+    g_autoptr(GHashTable) serialResource = NULL;
+    const char *connectionValue = NULL;
+    g_autofree const char *resourceType = NULL;
+
+    virUUIDFormat(domain->uuid, uuid_string);
+
+    if (hypervGetMsvmVirtualSystemSettingDataFromUUID(priv, uuid_string, &vssd) < 0)
+        return -1;
+
+    if (g_str_has_prefix(priv->version, "6.")) {
+        if (hypervGetResourceAllocationSD(priv, vssd->data->InstanceID, &rasd) < 0)
+            return -1;
+
+        current = rasd;
+        classInfo = Msvm_ResourceAllocationSettingData_WmiInfo;
+    } else {
+        if (hypervGetSerialPortSD(priv, vssd->data->InstanceID, &spsd) < 0)
+            return -1;
+
+        current = (Msvm_ResourceAllocationSettingData *)spsd;
+        classInfo = Msvm_SerialPortSettingData_WmiInfo;
+    }
+
+    while (current) {
+        if (current->data->ResourceType == MSVM_RASD_RESOURCETYPE_SERIAL_PORT &&
+            STREQ(current->data->ElementName, com_string)) {
+            /* found our com port */
+            entry = current;
+            break;
+        }
+        current = current->next;
+    }
+
+    if (!entry)
+        return -1;
+
+    if (STRNEQ(serial->source->data.file.path, "-1"))
+        connectionValue = serial->source->data.file.path;
+    else
+        connectionValue = "";
+
+    resourceType = g_strdup_printf("%d", entry->data->ResourceType);
+
+    serialResource = hypervCreateEmbeddedParam(classInfo);
+    if (!serialResource)
+        return -1;
+
+    if (hypervSetEmbeddedProperty(serialResource, "Connection", connectionValue) < 0)
+        return -1;
+
+    if (hypervSetEmbeddedProperty(serialResource, "InstanceID", entry->data->InstanceID) < 0)
+        return -1;
+
+    if (hypervSetEmbeddedProperty(serialResource, "ResourceType", resourceType) < 0)
+        return -1;
+
+    if (hypervSetEmbeddedProperty(serialResource, "ResourceSubType",
+                                  entry->data->ResourceSubType) < 0)
+        return -1;
+
+    if (hypervMsvmVSMSModifyResourceSettings(priv, &serialResource, classInfo) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 /*
  * Functions for deserializing device entries
  */
@@ -2425,6 +2504,7 @@ hypervDomainDefineXML(virConnectPtr conn, const char *xml)
     virDomainPtr domain = NULL;
     g_autoptr(hypervInvokeParamsList) params = NULL;
     g_autoptr(GHashTable) defineSystemParam = NULL;
+    size_t i = 0;
 
     /* parse xml */
     def = virDomainDefParseString(xml, priv->xmlopt, NULL,
@@ -2484,6 +2564,14 @@ hypervDomainDefineXML(virConnectPtr conn, const char *xml)
     if (hypervDomainAttachStorage(domain, def, hostname) < 0)
         goto error;
 
+    /* Attach serials */
+    for (i = 0; i < def->nserials; i++) {
+        if (hypervDomainAttachSerial(domain, def->serials[i]) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach serial port %lu"), i);
+            goto error;
+        }
+    }
+
     return domain;
 
  error:
@@ -2583,6 +2671,10 @@ hypervDomainAttachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int
         if (hypervDomainAttachStorageVolume(domain, dev->data.disk, controller, hostname) < 0)
             return -1;
         break;
+    case VIR_DOMAIN_DEVICE_CHR:
+        if (hypervDomainAttachSerial(domain, dev->data.chr) < 0)
+            return -1;
+        break;
     default:
         /* unsupported device type */
         virReportError(VIR_ERR_INTERNAL_ERROR,
-- 
2.30.0





More information about the libvir-list mailing list