[libvirt PATCH 08/18] conf: add support for audio backend for the VNC server

Daniel P. Berrangé berrange at redhat.com
Wed Mar 3 18:18:24 UTC 2021


When there are multiple <audio> backends specified, it is possible to
assign a specific one to the VNC server using

  <graphics type='vnc'...>
    <audio id='1'/>
  </graphics>

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 docs/formatdomain.rst         | 22 ++++++++++++++++++----
 docs/schemas/domaincommon.rng | 11 ++++++++++-
 src/conf/domain_conf.c        | 32 ++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h        |  1 +
 4 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 0d1bdcb338..eccd89921b 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -5795,6 +5795,19 @@ interaction with the admin.
       graphics type ``egl-headless`` (see below) which will instruct QEMU to
       open and use drm nodes for OpenGL rendering.
 
+      A VNC server could be optionally mapped to the specific host audio
+      backend using the ``<audio>`` sub-element:
+
+      ::
+
+         <graphics type='vnc' ...>
+           <audio id='1'>
+         </graphics>
+
+      Where ``1`` is an id of the `audio device <#elementsAudio>`__. If no
+      ID is specified, then the default audio backend will be used.
+      :since:`Since 7.2.0, qemu`.
+
    ``spice`` :since:`Since 0.8.6`
       Starts a SPICE server. The ``port`` attribute specifies the TCP port
       number (with -1 as legacy syntax indicating that it should be
@@ -6800,8 +6813,8 @@ Valid values are:
 Each ``sound`` element has an optional sub-element ``<address>`` which can tie
 the device to a particular PCI slot, `documented above <#elementsAddress>`__.
 
-:since:`Since 6.7.0`, a sound device could be optionally mapped to the specific
-host audio backend using the ``<audio>`` sub-element:
+A sound device could be optionally mapped to the specific host audio
+backend using the ``<audio>`` sub-element:
 
 ::
 
@@ -6813,8 +6826,9 @@ host audio backend using the ``<audio>`` sub-element:
    </devices>
    ...
 
-Where ``1`` is an id of the `audio device <#elementsAudio>`__.
-This is supported for bhyve only.
+Where ``1`` is an id of the `audio device <#elementsAudio>`__. If no
+ID is specified, then the default audio backend will be used.
+:since:`Since 6.7.0, bhyve; Since 7.2.0, qemu`.
 
 :anchor:`<a id="elementsAudio"/>`
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index d27de58b42..330a600539 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3692,7 +3692,16 @@
               <value>keep</value>
             </attribute>
           </optional>
-          <ref name="listenElements"/>
+          <interleave>
+            <optional>
+              <element name="audio">
+                <attribute name="id">
+                  <ref name="uint8"/>
+                </attribute>
+              </element>
+            </optional>
+            <ref name="listenElements"/>
+          </interleave>
         </group>
         <group>
           <attribute name="type">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b2a232a8d0..c3a21b4c78 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13204,6 +13204,8 @@ virDomainGraphicsDefParseXMLVNC(virDomainGraphicsDefPtr def,
     g_autofree char *websocketGenerated = virXMLPropString(node, "websocketGenerated");
     g_autofree char *sharePolicy = virXMLPropString(node, "sharePolicy");
     g_autofree char *autoport = virXMLPropString(node, "autoport");
+    xmlNodePtr audioNode;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt)
 
     if (virDomainGraphicsListensParseXML(def, node, ctxt, flags) < 0)
         return -1;
@@ -13262,6 +13264,24 @@ virDomainGraphicsDefParseXMLVNC(virDomainGraphicsDefPtr def,
 
     def->data.vnc.keymap = virXMLPropString(node, "keymap");
 
+    ctxt->node = node;
+    audioNode = virXPathNode("./audio", ctxt);
+    if (audioNode) {
+        g_autofree char *tmp = NULL;
+        tmp = virXMLPropString(audioNode, "id");
+        if (!tmp) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("missing audio 'id' attribute"));
+            return -1;
+        }
+        if (virStrToLong_ui(tmp, NULL, 10, &def->data.vnc.audioId) < 0 ||
+            def->data.vnc.audioId == 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("Invalid audio 'id' value '%s'"), tmp);
+            return -1;
+        }
+    }
+
     if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth,
                                          def->type) < 0)
         return -1;
@@ -27529,6 +27549,18 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
         virDomainSpiceGLDefFormat(buf, def);
     }
 
+    if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
+        if (!children) {
+            virBufferAddLit(buf, ">\n");
+            virBufferAdjustIndent(buf, 2);
+            children = true;
+        }
+
+        if (def->data.vnc.audioId > 0)
+            virBufferAsprintf(buf, "<audio id='%d'/>\n",
+                              def->data.vnc.audioId);
+    }
+
     if (children) {
         virBufferAdjustIndent(buf, -2);
         virBufferAddLit(buf, "</graphics>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cebbe3de0b..a3432f7e8a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1738,6 +1738,7 @@ struct _virDomainGraphicsDef {
             char *keymap;
             virDomainGraphicsAuthDef auth;
             int sharePolicy;
+            unsigned int audioId;
         } vnc;
         struct {
             char *display;
-- 
2.29.2




More information about the libvir-list mailing list