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(a)gmail.com>
---
docs/schemas/domaincommon.rng | 36 +++++++
src/conf/domain_capabilities.c | 4 +
src/conf/domain_conf.c | 176 ++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 28 ++++++
src/conf/virconftypes.h | 3 +
src/libvirt_private.syms | 2 +
src/qemu/qemu_command.c | 1 +
src/qemu/qemu_domain.c | 1 +
src/qemu/qemu_domain_address.c | 2 +
src/qemu/qemu_driver.c | 5 +
src/qemu/qemu_hotplug.c | 3 +
src/qemu/qemu_validate.c | 1 +
12 files changed, 260 insertions(+), 2 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index fb9638f3f6..c933c71035 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4372,12 +4372,47 @@
<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">
@@ -5303,6 +5338,7 @@
<ref name="interface"/>
<ref name="input"/>
<ref name="sound"/>
+ <ref name="audio"/>
<ref name="hostdev"/>
<ref name="graphic"/>
<ref name="video"/>
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index d61108e125..59ad8937a4 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -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:
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f9cdc4efa9..165d5d5f7a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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",
@@ -2872,6 +2878,24 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
VIR_FREE(def);
}
+void virDomainAudioDefFree(virDomainAudioDefPtr def)
+{
+ if (!def)
+ return;
+
+ switch (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)
{
@@ -3225,6 +3249,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;
@@ -3485,6 +3512,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);
@@ -4073,6 +4104,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;
@@ -4167,6 +4199,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;
@@ -4433,6 +4468,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
@@ -5425,6 +5461,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;
@@ -6814,6 +6851,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:
@@ -15016,10 +15055,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");
@@ -15056,6 +15095,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;
@@ -15107,6 +15158,58 @@ 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;
+ }
+
+ if (def->type == 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");
+ }
+
+ return def;
+
+ error:
+ virDomainAudioDefFree(def);
+ return NULL;
+}
static virDomainWatchdogDefPtr
virDomainWatchdogDefParseXML(virDomainXMLOptionPtr xmlopt,
xmlNodePtr node,
@@ -17063,6 +17166,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)))
@@ -21971,6 +22078,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;
@@ -22485,7 +22608,6 @@ virDomainDefParse(const char *xmlStr,
virDomainDefPtr def = NULL;
int keepBlanksDefault = xmlKeepBlanksDefault(0);
xmlNodePtr root;
-
if (!(xml = virXMLParse(filename, xmlStr, _("(domain_definition)"))))
goto cleanup;
@@ -24586,6 +24708,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
@@ -27352,6 +27475,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;
@@ -27368,6 +27494,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,
@@ -30047,6 +30211,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;
@@ -31219,6 +31388,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:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 411b9b99e4..fdf706a7e0 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -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);
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index 1c62cde251..9042a2b34f 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -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;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 01c2e710cd..35bf9f08ef 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -224,6 +224,8 @@ virDiskNameToBusDeviceIndex;
virDiskNameToIndex;
virDomainActualNetDefFree;
virDomainActualNetDefValidate;
+virDomainAudioTypeTypeFromString;
+virDomainAudioTypeTypeToString;
virDomainBlockedReasonTypeFromString;
virDomainBlockedReasonTypeToString;
virDomainBlockIoTuneInfoCopy;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ec3d4c8d99..40408fdd70 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -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;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c440c79e1d..9c735e4776 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5265,6 +5265,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;
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index d25fb653d3..cbf8ffddd7 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -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;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0f98243fe4..43d6f6eb5b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7960,6 +7960,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"),
@@ -8094,6 +8095,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"),
@@ -8313,6 +8315,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"),
@@ -8515,6 +8518,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"),
@@ -8622,6 +8626,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"),
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 2c6c30ce03..3a780d00af 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4944,6 +4944,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;
@@ -5042,6 +5043,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"),
@@ -5813,6 +5815,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"),
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 4cd377c8bc..fe8a64b933 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -4145,6 +4145,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;
--
2.27.0