c1c534
From f39b12fb966c2dfe7841a299f00ff5c6fa68095e Mon Sep 17 00:00:00 2001
c1c534
Message-Id: <f39b12fb966c2dfe7841a299f00ff5c6fa68095e@dist-git>
c1c534
From: Andrea Bolognani <abologna@redhat.com>
c1c534
Date: Wed, 29 Nov 2017 16:23:07 +0100
c1c534
Subject: [PATCH] conf: Parse and format virDomainChrSerialTargetModel
c1c534
c1c534
This information will be used to select, and store in the guest
c1c534
configuration in order to guarantee ABI stability, the concrete
c1c534
(hypervisor-specific) model for serial devices.
c1c534
c1c534
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
c1c534
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
c1c534
(cherry picked from commit 5ad9d9afd4738ea716a6f820bbb53eecf5604a2f)
c1c534
c1c534
https://bugzilla.redhat.com/show_bug.cgi?id=1449265
c1c534
https://bugzilla.redhat.com/show_bug.cgi?id=1511421
c1c534
https://bugzilla.redhat.com/show_bug.cgi?id=1512929
c1c534
https://bugzilla.redhat.com/show_bug.cgi?id=1512934
c1c534
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c1c534
---
c1c534
 docs/formatdomain.html.in     | 16 ++++++++--
c1c534
 docs/schemas/domaincommon.rng | 15 +++++++++
c1c534
 src/conf/domain_conf.c        | 72 ++++++++++++++++++++++++++++++++++++++++++-
c1c534
 src/conf/domain_conf.h        | 12 ++++++++
c1c534
 4 files changed, 112 insertions(+), 3 deletions(-)
c1c534
c1c534
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
c1c534
index f57a124056..cf1167b9c6 100644
c1c534
--- a/docs/formatdomain.html.in
c1c534
+++ b/docs/formatdomain.html.in
c1c534
@@ -6447,7 +6447,9 @@ qemu-kvm -net nic,model=? /dev/null
c1c534
 <devices>
c1c534
   <!-- USB serial port -->
c1c534
   <serial type='pty'>
c1c534
-    <target type='usb-serial' port='0'/>
c1c534
+    <target type='usb-serial' port='0'>
c1c534
+      <model name='usb-serial'/>
c1c534
+    </target>
c1c534
     <address type='usb' bus='0' port='1'/>
c1c534
   </serial>
c1c534
 </devices>
c1c534
@@ -6463,6 +6465,16 @@ qemu-kvm -net nic,model=? /dev/null
c1c534
       is available).
c1c534
     

c1c534
 
c1c534
+    

c1c534
+      Since 3.10.0, the target
c1c534
+      element can have an optional model subelement;
c1c534
+      valid values for its name attribute are:
c1c534
+      isa-serial (usable with the isa-serial target
c1c534
+      type); usb-serial (usable with the usb-serial
c1c534
+      target type); pci-serial
c1c534
+      (usable with the pci-serial target type).
c1c534
+    

c1c534
+
c1c534
     

c1c534
       If any of the attributes is not specified by the user, libvirt will
c1c534
       choose a value suitable for most users.
c1c534
@@ -6489,7 +6501,7 @@ qemu-kvm -net nic,model=? /dev/null
c1c534
   <!-- Serial console -->
c1c534
   <console type='pty'>
c1c534
     <source path='/dev/pts/2'/>
c1c534
-    <target type='serial' port='0'/>
c1c534
+   <target type='serial' port='0'/>
c1c534
   </console>
c1c534
 </devices>
c1c534
 ...
c1c534
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
c1c534
index 367861c1ea..3630e539e6 100644
c1c534
--- a/docs/schemas/domaincommon.rng
c1c534
+++ b/docs/schemas/domaincommon.rng
c1c534
@@ -3575,6 +3575,18 @@
c1c534
     </attribute>
c1c534
   </define>
c1c534
 
c1c534
+  <define name='qemucdevSerialTgtModel'>
c1c534
+    <element name='model'>
c1c534
+      <attribute name='name'>
c1c534
+        <choice>
c1c534
+          <value>isa-serial</value>
c1c534
+          <value>usb-serial</value>
c1c534
+          <value>pci-serial</value>
c1c534
+        </choice>
c1c534
+      </attribute>
c1c534
+    </element>
c1c534
+  </define>
c1c534
+
c1c534
   <define  name="qemucdevTgtDef">
c1c534
     <element name="target">
c1c534
       <interleave>
c1c534
@@ -3589,6 +3601,9 @@
c1c534
         <optional>
c1c534
           <attribute name="port"/>
c1c534
         </optional>
c1c534
+        <optional>
c1c534
+          <ref name="qemucdevSerialTgtModel"/>
c1c534
+        </optional>
c1c534
       </interleave>
c1c534
     </element>
c1c534
   </define>
c1c534
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
c1c534
index 44d9bbe01d..692b9d9414 100644
c1c534
--- a/src/conf/domain_conf.c
c1c534
+++ b/src/conf/domain_conf.c
c1c534
@@ -465,6 +465,14 @@ VIR_ENUM_IMPL(virDomainChrConsoleTarget,
c1c534
               "sclp",
c1c534
               "sclplm")
c1c534
 
c1c534
+VIR_ENUM_IMPL(virDomainChrSerialTargetModel,
c1c534
+              VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST,
c1c534
+              "none",
c1c534
+              "isa-serial",
c1c534
+              "usb-serial",
c1c534
+              "pci-serial",
c1c534
+);
c1c534
+
c1c534
 VIR_ENUM_IMPL(virDomainChrDevice, VIR_DOMAIN_CHR_DEVICE_TYPE_LAST,
c1c534
               "parallel",
c1c534
               "serial",
c1c534
@@ -11530,14 +11538,42 @@ virDomainChrTargetTypeFromString(int devtype,
c1c534
     return ret;
c1c534
 }
c1c534
 
c1c534
+static int
c1c534
+virDomainChrTargetModelFromString(int devtype,
c1c534
+                                  const char *targetModel)
c1c534
+{
c1c534
+    int ret = -1;
c1c534
+
c1c534
+    if (!targetModel)
c1c534
+        return 0;
c1c534
+
c1c534
+    switch ((virDomainChrDeviceType) devtype) {
c1c534
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
c1c534
+        ret = virDomainChrSerialTargetModelTypeFromString(targetModel);
c1c534
+        break;
c1c534
+
c1c534
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
c1c534
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
c1c534
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
c1c534
+    case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
c1c534
+        /* Target model not supported yet */
c1c534
+        ret = 0;
c1c534
+        break;
c1c534
+    }
c1c534
+
c1c534
+    return ret;
c1c534
+}
c1c534
+
c1c534
 static int
c1c534
 virDomainChrDefParseTargetXML(virDomainChrDefPtr def,
c1c534
                               xmlNodePtr cur,
c1c534
                               unsigned int flags)
c1c534
 {
c1c534
     int ret = -1;
c1c534
+    xmlNodePtr child;
c1c534
     unsigned int port;
c1c534
     char *targetType = virXMLPropString(cur, "type");
c1c534
+    char *targetModel = NULL;
c1c534
     char *addrStr = NULL;
c1c534
     char *portStr = NULL;
c1c534
     char *stateStr = NULL;
c1c534
@@ -11551,6 +11587,24 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def,
c1c534
         goto error;
c1c534
     }
c1c534
 
c1c534
+    child = cur->children;
c1c534
+    while (child != NULL) {
c1c534
+        if (child->type == XML_ELEMENT_NODE &&
c1c534
+            virXMLNodeNameEqual(child, "model")) {
c1c534
+            targetModel = virXMLPropString(child, "name");
c1c534
+        }
c1c534
+        child = child->next;
c1c534
+    }
c1c534
+
c1c534
+    if ((def->targetModel =
c1c534
+         virDomainChrTargetModelFromString(def->deviceType,
c1c534
+                                           targetModel)) < 0) {
c1c534
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
c1c534
+                       _("unknown target model '%s' specified for character device"),
c1c534
+                       targetModel);
c1c534
+        goto error;
c1c534
+    }
c1c534
+
c1c534
     switch (def->deviceType) {
c1c534
     case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
c1c534
         switch (def->targetType) {
c1c534
@@ -11639,6 +11693,7 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def,
c1c534
     ret = 0;
c1c534
  error:
c1c534
     VIR_FREE(targetType);
c1c534
+    VIR_FREE(targetModel);
c1c534
     VIR_FREE(addrStr);
c1c534
     VIR_FREE(portStr);
c1c534
     VIR_FREE(stateStr);
c1c534
@@ -24019,8 +24074,23 @@ virDomainChrTargetDefFormat(virBufferPtr buf,
c1c534
         }
c1c534
 
c1c534
         virBufferAsprintf(buf,
c1c534
-                          "port='%d'/>\n",
c1c534
+                          "port='%d'",
c1c534
                           def->target.port);
c1c534
+
c1c534
+        if (def->targetModel != VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE) {
c1c534
+            virBufferAddLit(buf, ">\n");
c1c534
+
c1c534
+            virBufferAdjustIndent(buf, 2);
c1c534
+            virBufferAsprintf(buf,
c1c534
+                              "<model name='%s'/>\n",
c1c534
+                              virDomainChrSerialTargetModelTypeToString(def->targetModel));
c1c534
+            virBufferAdjustIndent(buf, -2);
c1c534
+
c1c534
+            virBufferAddLit(buf, "</target>\n");
c1c534
+        } else {
c1c534
+            virBufferAddLit(buf, "/>\n");
c1c534
+        }
c1c534
+
c1c534
         break;
c1c534
 
c1c534
     case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
c1c534
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
c1c534
index bbb056cf21..9dfe9388cd 100644
c1c534
--- a/src/conf/domain_conf.h
c1c534
+++ b/src/conf/domain_conf.h
c1c534
@@ -1104,6 +1104,17 @@ typedef enum {
c1c534
     VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST
c1c534
 } virDomainChrConsoleTargetType;
c1c534
 
c1c534
+typedef enum {
c1c534
+    VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE = 0,
c1c534
+    VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_ISA_SERIAL,
c1c534
+    VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_USB_SERIAL,
c1c534
+    VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PCI_SERIAL,
c1c534
+
c1c534
+    VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST
c1c534
+} virDomainChrSerialTargetModel;
c1c534
+
c1c534
+VIR_ENUM_DECL(virDomainChrSerialTargetModel);
c1c534
+
c1c534
 typedef enum {
c1c534
     VIR_DOMAIN_CHR_TYPE_NULL,
c1c534
     VIR_DOMAIN_CHR_TYPE_VC,
c1c534
@@ -1202,6 +1213,7 @@ struct _virDomainChrDef {
c1c534
     int targetType; /* enum virDomainChrConsoleTargetType ||
c1c534
                        enum virDomainChrChannelTargetType ||
c1c534
                        enum virDomainChrSerialTargetType according to deviceType */
c1c534
+    int targetModel; /* enum virDomainChrSerialTargetModel */
c1c534
 
c1c534
     union {
c1c534
         int port; /* parallel, serial, console */
c1c534
-- 
c1c534
2.15.1
c1c534