]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: allow to map sound device to host device
authorRoman Bogorodskiy <bogorodskiy@gmail.com>
Sat, 18 Jul 2020 06:23:57 +0000 (10:23 +0400)
committerRoman Bogorodskiy <bogorodskiy@gmail.com>
Tue, 25 Aug 2020 04:42:16 +0000 (08:42 +0400)
Introduce a new device element "<audio>" which allows
to map guest sound device specified using the "<sound>"
element to specific audio backend.

Example:

  <sound model='ich7'>
     <audio id='1'/>
  </sound>
  <audio id='1' type='oss'>
     <input dev='/dev/dsp0'/>
     <output dev='/dev/dsp0'/>
  </audio>

This block maps to OSS audio backend on the host using
/dev/dsp0 device for both input (recording)
and output (playback).

OSS is the only backend supported so far.

Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
12 files changed:
docs/schemas/domaincommon.rng
src/conf/domain_capabilities.c
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/virconftypes.h
src/libvirt_private.syms
src/qemu/qemu_command.c
src/qemu/qemu_domain.c
src/qemu/qemu_domain_address.c
src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_validate.c

index fb9638f3f6ce8025df993a79458bb45e31c667e8..c933c71035d09313d8c71adae2067e1a0f7b3872 100644 (file)
         <optional>
           <ref name="address"/>
         </optional>
+        <optional>
+          <element name="audio">
+            <attribute name="id">
+              <ref name="uint8"/>
+            </attribute>
+          </element>
+        </optional>
         <zeroOrMore>
           <ref name="codec"/>
         </zeroOrMore>
       </interleave>
     </element>
   </define>
+  <define name="audio">
+    <element name="audio">
+      <attribute name="id">
+        <ref name="uint8"/>
+      </attribute>
+      <attribute name="type">
+        <choice>
+          <value>oss</value>
+        </choice>
+      </attribute>
+      <interleave>
+        <optional>
+          <element name="input">
+            <attribute name="dev">
+              <ref name="deviceName"/>
+            </attribute>
+          </element>
+        </optional>
+        <optional>
+          <element name="output">
+            <attribute name="dev">
+              <ref name="deviceName"/>
+            </attribute>
+          </element>
+        </optional>
+      </interleave>
+    </element>
+  </define>
   <define name="watchdog">
     <element name="watchdog">
       <attribute name="model">
             <ref name="interface"/>
             <ref name="input"/>
             <ref name="sound"/>
+            <ref name="audio"/>
             <ref name="hostdev"/>
             <ref name="graphic"/>
             <ref name="video"/>
index d61108e125c483d55320831c8b8e0d2b33c8c654..59ad8937a48bc72de992d6076e91697b2f86747d 100644 (file)
@@ -688,6 +688,10 @@ virDomainCapsDeviceDefValidate(const virDomainCaps *caps,
         ret = virDomainCapsDeviceVideoDefValidate(caps, dev->data.video);
         break;
 
+    case VIR_DOMAIN_DEVICE_AUDIO:
+        /* TODO: add validation */
+        break;
+
     case VIR_DOMAIN_DEVICE_DISK:
     case VIR_DOMAIN_DEVICE_REDIRDEV:
     case VIR_DOMAIN_DEVICE_NET:
index cfdea84c88fc7b7ee8695ff8a4c0d121e59d8174..4f3a83435dd9e1f51a7772292a2f6d75715ac589 100644 (file)
@@ -323,6 +323,7 @@ VIR_ENUM_IMPL(virDomainDevice,
               "memory",
               "iommu",
               "vsock",
+              "audio",
 );
 
 VIR_ENUM_IMPL(virDomainDiskDevice,
@@ -729,6 +730,11 @@ VIR_ENUM_IMPL(virDomainSoundModel,
               "ich7",
 );
 
+VIR_ENUM_IMPL(virDomainAudioType,
+              VIR_DOMAIN_AUDIO_TYPE_LAST,
+              "oss",
+);
+
 VIR_ENUM_IMPL(virDomainKeyWrapCipherName,
               VIR_DOMAIN_KEY_WRAP_CIPHER_NAME_LAST,
               "aes",
@@ -2864,6 +2870,24 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
     VIR_FREE(def);
 }
 
+void virDomainAudioDefFree(virDomainAudioDefPtr def)
+{
+    if (!def)
+        return;
+
+    switch ((virDomainAudioType) def->type) {
+    case VIR_DOMAIN_AUDIO_TYPE_OSS:
+        VIR_FREE(def->backend.oss.inputDev);
+        VIR_FREE(def->backend.oss.outputDev);
+        break;
+
+    case VIR_DOMAIN_AUDIO_TYPE_LAST:
+        break;
+    }
+
+    VIR_FREE(def);
+}
+
 virDomainSoundDefPtr
 virDomainSoundDefRemove(virDomainDefPtr def, size_t idx)
 {
@@ -3217,6 +3241,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
     case VIR_DOMAIN_DEVICE_VSOCK:
         virDomainVsockDefFree(def->data.vsock);
         break;
+    case VIR_DOMAIN_DEVICE_AUDIO:
+        virDomainAudioDefFree(def->data.audio);
+        break;
     case VIR_DOMAIN_DEVICE_LAST:
     case VIR_DOMAIN_DEVICE_NONE:
         break;
@@ -3477,6 +3504,10 @@ void virDomainDefFree(virDomainDefPtr def)
         virDomainSoundDefFree(def->sounds[i]);
     VIR_FREE(def->sounds);
 
+    for (i = 0; i < def->naudios; i++)
+        virDomainAudioDefFree(def->audios[i]);
+    VIR_FREE(def->audios);
+
     for (i = 0; i < def->nvideos; i++)
         virDomainVideoDefFree(def->videos[i]);
     VIR_FREE(def->videos);
@@ -4065,6 +4096,7 @@ virDomainDeviceGetInfo(virDomainDeviceDefPtr device)
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_GRAPHICS:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
     case VIR_DOMAIN_DEVICE_NONE:
         break;
@@ -4159,6 +4191,9 @@ virDomainDeviceSetData(virDomainDeviceDefPtr device,
     case VIR_DOMAIN_DEVICE_LEASE:
         device->data.lease = devicedata;
         break;
+    case VIR_DOMAIN_DEVICE_AUDIO:
+        device->data.audio = devicedata;
+        break;
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LAST:
         break;
@@ -4425,6 +4460,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
     case VIR_DOMAIN_DEVICE_MEMORY:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
+    case VIR_DOMAIN_DEVICE_AUDIO:
         break;
     }
 #endif
@@ -5417,6 +5453,7 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_MEMORY:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
         ret = 0;
         break;
 
@@ -6806,6 +6843,8 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_SHMEM:
         return virDomainShmemDefValidate(dev->data.shmem);
 
+    case VIR_DOMAIN_DEVICE_AUDIO:
+        /* TODO: validate? */
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_FS:
     case VIR_DOMAIN_DEVICE_SOUND:
@@ -15002,10 +15041,10 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt,
     virDomainSoundDefPtr def;
     VIR_XPATH_NODE_AUTORESTORE(ctxt);
     g_autofree char *model = NULL;
+    xmlNodePtr audioNode;
 
     if (VIR_ALLOC(def) < 0)
         return NULL;
-
     ctxt->node = node;
 
     model = virXMLPropString(node, "model");
@@ -15042,6 +15081,18 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt,
         }
     }
 
+    audioNode = virXPathNode("./audio", ctxt);
+    if (audioNode) {
+        g_autofree char *tmp = NULL;
+        tmp = virXMLPropString(audioNode, "id");
+        if (virStrToLong_ui(tmp, NULL, 10, &def->audioId) < 0 ||
+            def->audioId == 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("Invalid audio 'id' value '%s'"), tmp);
+            goto error;
+        }
+    }
+
     if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0)
         goto error;
 
@@ -15093,6 +15144,64 @@ virDomainSoundDefFind(const virDomainDef *def,
 }
 
 
+static virDomainAudioDefPtr
+virDomainAudioDefParseXML(virDomainXMLOptionPtr xmlopt G_GNUC_UNUSED,
+                          xmlNodePtr node G_GNUC_UNUSED,
+                          xmlXPathContextPtr ctxt G_GNUC_UNUSED)
+{
+    virDomainAudioDefPtr def;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt);
+    g_autofree char *tmp = NULL;
+    g_autofree char *type = NULL;
+
+    if (VIR_ALLOC(def) < 0)
+        return NULL;
+    ctxt->node = node;
+
+    type = virXMLPropString(node, "type");
+    if ((def->type = virDomainAudioTypeTypeFromString(type)) < 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown audio type '%s'"), type);
+        goto error;
+    }
+
+    tmp = virXMLPropString(node, "id");
+    if (virStrToLong_ui(tmp, NULL, 10, &def->id) < 0 ||
+        def->id == 0) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("invalid audio 'id' value '%s'"), tmp);
+        goto error;
+    }
+
+    switch ((virDomainAudioType) def->type) {
+    case VIR_DOMAIN_AUDIO_TYPE_OSS: {
+        xmlNodePtr inputDevNode, outputDevNode;
+
+        inputDevNode = virXPathNode("./input", ctxt);
+        outputDevNode = virXPathNode("./output", ctxt);
+
+        if (!inputDevNode || !outputDevNode) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Audio type OSS requires to have <input> "
+                             "and <output> specified"));
+            goto error;
+        }
+
+        def->backend.oss.inputDev = virXMLPropString(inputDevNode, "dev");
+        def->backend.oss.outputDev = virXMLPropString(outputDevNode, "dev");
+        break;
+    }
+
+    case VIR_DOMAIN_AUDIO_TYPE_LAST:
+        break;
+    }
+
+    return def;
+
+ error:
+    virDomainAudioDefFree(def);
+    return NULL;
+}
 static virDomainWatchdogDefPtr
 virDomainWatchdogDefParseXML(virDomainXMLOptionPtr xmlopt,
                              xmlNodePtr node,
@@ -17049,6 +17158,10 @@ virDomainDeviceDefParse(const char *xmlStr,
                                                           ctxt, flags)))
             return NULL;
         break;
+    case VIR_DOMAIN_DEVICE_AUDIO:
+        if (!(dev->data.audio = virDomainAudioDefParseXML(xmlopt, node, ctxt)))
+            return NULL;
+        break;
     case VIR_DOMAIN_DEVICE_WATCHDOG:
         if (!(dev->data.watchdog = virDomainWatchdogDefParseXML(xmlopt,
                                                                 node, flags)))
@@ -21957,6 +22070,22 @@ virDomainDefParseXML(xmlDocPtr xml,
     }
     VIR_FREE(nodes);
 
+    /* analysis of the audio devices */
+    if ((n = virXPathNodeSet("./devices/audio", ctxt, &nodes)) < 0)
+        goto error;
+    if (n && VIR_ALLOC_N(def->audios, n) < 0)
+        goto error;
+    for (i = 0; i < n; i++) {
+        virDomainAudioDefPtr audio = virDomainAudioDefParseXML(xmlopt,
+                                                               nodes[i],
+                                                               ctxt);
+        if (!audio)
+            goto error;
+
+        def->audios[def->naudios++] = audio;
+    }
+    VIR_FREE(nodes);
+
     /* analysis of the video devices */
     if ((n = virXPathNodeSet("./devices/video", ctxt, &nodes)) < 0)
         goto error;
@@ -22471,7 +22600,6 @@ virDomainDefParse(const char *xmlStr,
     virDomainDefPtr def = NULL;
     int keepBlanksDefault = xmlKeepBlanksDefault(0);
     xmlNodePtr root;
-
     if (!(xml = virXMLParse(filename, xmlStr, _("(domain_definition)"))))
         goto cleanup;
 
@@ -24572,6 +24700,7 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
     case VIR_DOMAIN_DEVICE_MEMORY:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
+    case VIR_DOMAIN_DEVICE_AUDIO:
         break;
     }
 #endif
@@ -27340,6 +27469,9 @@ virDomainSoundDefFormat(virBufferPtr buf,
     for (i = 0; i < def->ncodecs; i++)
         virDomainSoundCodecDefFormat(&childBuf, def->codecs[i]);
 
+    if (def->audioId > 0)
+        virBufferAsprintf(&childBuf, "<audio id='%d'/>\n", def->audioId);
+
     if (virDomainDeviceInfoFormat(&childBuf, &def->info, flags) < 0)
         return -1;
 
@@ -27356,6 +27488,44 @@ virDomainSoundDefFormat(virBufferPtr buf,
 }
 
 
+static int
+virDomainAudioDefFormat(virBufferPtr buf,
+                        virDomainAudioDefPtr def)
+{
+    g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
+    const char *type = virDomainAudioTypeTypeToString(def->type);
+
+    if (!type) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unexpected audio type %d"), def->type);
+        return -1;
+    }
+
+    virBufferAsprintf(buf, "<audio id='%d' type='%s'", def->id, type);
+
+    switch (def->type) {
+    case VIR_DOMAIN_AUDIO_TYPE_OSS:
+        if (def->backend.oss.inputDev)
+            virBufferAsprintf(&childBuf, "<input dev='%s'/>\n",
+                              def->backend.oss.inputDev);
+        if (def->backend.oss.outputDev)
+            virBufferAsprintf(&childBuf, "<output dev='%s'/>\n",
+                              def->backend.oss.outputDev);
+        break;
+    }
+
+    if (virBufferUse(&childBuf)) {
+        virBufferAddLit(buf, ">\n");
+        virBufferAddBuffer(buf, &childBuf);
+        virBufferAddLit(buf, "</audio>\n");
+    } else {
+        virBufferAddLit(buf, "/>\n");
+    }
+
+    return 0;
+}
+
+
 static int
 virDomainMemballoonDefFormat(virBufferPtr buf,
                              virDomainMemballoonDefPtr def,
@@ -30035,6 +30205,11 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def,
             return -1;
     }
 
+    for (n = 0; n < def->naudios; n++) {
+        if (virDomainAudioDefFormat(buf, def->audios[n]) < 0)
+            return -1;
+    }
+
     for (n = 0; n < def->nvideos; n++) {
         if (virDomainVideoDefFormat(buf, def->videos[n], flags) < 0)
             return -1;
@@ -31207,6 +31382,9 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
     case VIR_DOMAIN_DEVICE_VSOCK:
         rc = virDomainVsockDefFormat(&buf, src->data.vsock);
         break;
+    case VIR_DOMAIN_DEVICE_AUDIO:
+        rc = virDomainAudioDefFormat(&buf, src->data.audio);
+        break;
 
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_SMARTCARD:
index 7b60c28c6df2e786c3dbc1c5565210e1788cb741..e0827fee7454fef80be6c79a16feb16e7aee19ae 100644 (file)
@@ -85,6 +85,7 @@ typedef enum {
     VIR_DOMAIN_DEVICE_MEMORY,
     VIR_DOMAIN_DEVICE_IOMMU,
     VIR_DOMAIN_DEVICE_VSOCK,
+    VIR_DOMAIN_DEVICE_AUDIO,
 
     VIR_DOMAIN_DEVICE_LAST
 } virDomainDeviceType;
@@ -116,6 +117,7 @@ struct _virDomainDeviceDef {
         virDomainMemoryDefPtr memory;
         virDomainIOMMUDefPtr iommu;
         virDomainVsockDefPtr vsock;
+        virDomainAudioDefPtr audio;
     } data;
 };
 
@@ -1417,6 +1419,27 @@ struct _virDomainSoundDef {
 
     size_t ncodecs;
     virDomainSoundCodecDefPtr *codecs;
+
+    unsigned int audioId;
+};
+
+typedef enum {
+    VIR_DOMAIN_AUDIO_TYPE_OSS,
+
+    VIR_DOMAIN_AUDIO_TYPE_LAST
+} virDomainAudioType;
+
+struct _virDomainAudioDef {
+    int type;
+
+    unsigned int id;
+
+    union {
+        struct {
+            char *inputDev;
+            char *outputDev;
+        } oss;
+    } backend;
 };
 
 typedef enum {
@@ -2602,6 +2625,9 @@ struct _virDomainDef {
     size_t nsounds;
     virDomainSoundDefPtr *sounds;
 
+    size_t naudios;
+    virDomainAudioDefPtr *audios;
+
     size_t nvideos;
     virDomainVideoDefPtr *videos;
 
@@ -3032,6 +3058,7 @@ ssize_t virDomainSoundDefFind(const virDomainDef *def,
                               const virDomainSoundDef *sound);
 void virDomainSoundDefFree(virDomainSoundDefPtr def);
 virDomainSoundDefPtr virDomainSoundDefRemove(virDomainDefPtr def, size_t idx);
+void virDomainAudioDefFree(virDomainAudioDefPtr def);
 void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def);
 void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def);
 void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def);
@@ -3591,6 +3618,7 @@ VIR_ENUM_DECL(virDomainChrTcpProtocol);
 VIR_ENUM_DECL(virDomainChrSpicevmc);
 VIR_ENUM_DECL(virDomainSoundCodec);
 VIR_ENUM_DECL(virDomainSoundModel);
+VIR_ENUM_DECL(virDomainAudioType);
 VIR_ENUM_DECL(virDomainKeyWrapCipherName);
 VIR_ENUM_DECL(virDomainMemballoonModel);
 VIR_ENUM_DECL(virDomainSmbiosMode);
index 1c62cde251abde8bb171b620f0a7247f34105d53..9042a2b34fb169267413b46ecd0775f99d714505 100644 (file)
@@ -309,6 +309,9 @@ typedef virDomainSoundCodecDef *virDomainSoundCodecDefPtr;
 typedef struct _virDomainSoundDef virDomainSoundDef;
 typedef virDomainSoundDef *virDomainSoundDefPtr;
 
+typedef struct _virDomainAudioDef virDomainAudioDef;
+typedef virDomainAudioDef *virDomainAudioDefPtr;
+
 typedef struct _virDomainTPMDef virDomainTPMDef;
 typedef virDomainTPMDef *virDomainTPMDefPtr;
 
index 01c2e710cdead908649203049b5365e51f978c97..35bf9f08ef0e683979a57d7ff592b200736956f2 100644 (file)
@@ -224,6 +224,8 @@ virDiskNameToBusDeviceIndex;
 virDiskNameToIndex;
 virDomainActualNetDefFree;
 virDomainActualNetDefValidate;
+virDomainAudioTypeTypeFromString;
+virDomainAudioTypeTypeToString;
 virDomainBlockedReasonTypeFromString;
 virDomainBlockedReasonTypeToString;
 virDomainBlockIoTuneInfoCopy;
index ec3d4c8d998507b4be9f9a2f515464e84fff0e00..40408fdd708bb9ae0a4f9ea16937278836e1c43d 100644 (file)
@@ -523,6 +523,7 @@ qemuBuildVirtioDevStr(virBufferPtr buf,
         case VIR_DOMAIN_DEVICE_PANIC:
         case VIR_DOMAIN_DEVICE_MEMORY:
         case VIR_DOMAIN_DEVICE_IOMMU:
+        case VIR_DOMAIN_DEVICE_AUDIO:
         case VIR_DOMAIN_DEVICE_LAST:
         default:
             return 0;
index b24176e4a9d88bbdc01b09f0b53432850cbecc29..59c6e318023efec2131ef8f2f79d20fe341d78f9 100644 (file)
@@ -5412,6 +5412,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
     case VIR_DOMAIN_DEVICE_RNG:
     case VIR_DOMAIN_DEVICE_MEMORY:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
         ret = 0;
         break;
 
index d25fb653d32d4f7805170e5c44a9c15c5cb66aeb..cbf8ffddd7a09ee9e480f4353fc1a47603e4d03a 100644 (file)
@@ -531,6 +531,7 @@ qemuDomainDeviceSupportZPCI(virDomainDeviceDefPtr device)
     case VIR_DOMAIN_DEVICE_MEMORY:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
+    case VIR_DOMAIN_DEVICE_AUDIO:
         break;
 
     case VIR_DOMAIN_DEVICE_NONE:
@@ -1047,6 +1048,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_GRAPHICS:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
     case VIR_DOMAIN_DEVICE_NONE:
         return 0;
index 8a42883316a01ce2ce8b8851c838b0b375fb89ff..3636716ceea1b72d8143dfe3f315ab292c9330e9 100644 (file)
@@ -6979,6 +6979,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live attach of device '%s' is not supported"),
@@ -7113,6 +7114,7 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("live update of device '%s' is not supported"),
@@ -7332,6 +7334,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
          virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                         _("persistent attach of device '%s' is not supported"),
@@ -7534,6 +7537,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("persistent detach of device '%s' is not supported"),
@@ -7641,6 +7645,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
     case VIR_DOMAIN_DEVICE_VSOCK:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("persistent update of device '%s' is not supported"),
index df45e1e8320ba057578bc998ee6ae8e234967715..e2c6e14c2e11ec62c65d61704b0ab5122a8a13c5 100644 (file)
@@ -4943,6 +4943,7 @@ qemuDomainRemoveAuditDevice(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
         /* libvirt doesn't yet support detaching these devices */
         break;
@@ -5041,6 +5042,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("don't know how to remove a %s device"),
@@ -5811,6 +5813,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
     case VIR_DOMAIN_DEVICE_TPM:
     case VIR_DOMAIN_DEVICE_PANIC:
     case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live detach of device '%s' is not supported"),
index 9b5df859ff565bc156fed581d6d342ad9fde4f2e..c4b86326ad73cd6e17c6510a93d7fefc04e15427 100644 (file)
@@ -4175,6 +4175,7 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev,
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_SHMEM:
     case VIR_DOMAIN_DEVICE_PANIC:
+    case VIR_DOMAIN_DEVICE_AUDIO:
     case VIR_DOMAIN_DEVICE_NONE:
     case VIR_DOMAIN_DEVICE_LAST:
         break;