Extend <sound> device element to accept "soundDevice" sub-element which allows to map guest sound device to host sound device. Example <sound model='ich6'> <soundDevice playback='/dev/dsp0' recording='/dev/dsp0'/> </sound> The "playback" attribute points to the playback device, and "recording" attribute points to the recording device. Signed-off-by: Roman Bogorodskiy <bogorodskiy@xxxxxxxxx> --- docs/schemas/domaincommon.rng | 15 +++++++++++++++ src/conf/domain_conf.c | 24 ++++++++++++++++++++++++ src/conf/domain_conf.h | 3 +++ 3 files changed, 42 insertions(+) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index a810f569c6..b11b3f2af6 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4346,6 +4346,18 @@ </attribute> </element> </define> + <define name="soundDevice"> + <element name="soundDevice"> + <attribute name="playback"> + <text/> + </attribute> + <optional> + <attribute name="recording"> + <text/> + </attribute> + </optional> + </element> + </define> <define name="sound"> <element name="sound"> <attribute name="model"> @@ -4366,6 +4378,9 @@ <optional> <ref name="address"/> </optional> + <optional> + <ref name="soundDevice"/> + </optional> <zeroOrMore> <ref name="codec"/> </zeroOrMore> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7ecd2818b9..b678a2319d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2850,6 +2850,9 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def) virDomainSoundCodecDefFree(def->codecs[i]); VIR_FREE(def->codecs); + VIR_FREE(def->playback); + VIR_FREE(def->recording); + VIR_FREE(def); } @@ -14984,6 +14987,8 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt, virDomainSoundDefPtr def; VIR_XPATH_NODE_AUTORESTORE(ctxt); g_autofree char *model = NULL; + char *recording = NULL; + xmlNodePtr soundDeviceNode; if (VIR_ALLOC(def) < 0) return NULL; @@ -15024,6 +15029,14 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt, } } + soundDeviceNode = virXPathNode("./soundDevice", ctxt); + if (soundDeviceNode) { + def->playback = virXMLPropString(soundDeviceNode, "playback"); + recording = virXMLPropString(soundDeviceNode, "recording"); + if (recording) + def->recording = recording; + } + if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0) goto error; @@ -15056,6 +15069,9 @@ virDomainSoundDefEquals(const virDomainSoundDef *a, !virDomainDeviceInfoAddressIsEqual(&a->info, &b->info)) return false; + if ((a->playback != b->playback) || (a->recording != b->recording)) + return false; + return true; } @@ -27284,6 +27300,14 @@ virDomainSoundDefFormat(virBufferPtr buf, for (i = 0; i < def->ncodecs; i++) virDomainSoundCodecDefFormat(&childBuf, def->codecs[i]); + if (def->playback) { + virBufferAsprintf(&childBuf, "<soundDevice playback='%s'", def->playback); + if (def->recording) + virBufferAsprintf(&childBuf, " recording='%s'/>\n", def->recording); + else + virBufferAddLit(&childBuf, "/>\n"); + } + if (virDomainDeviceInfoFormat(&childBuf, &def->info, flags) < 0) return -1; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 241149af24..b501f48442 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1415,6 +1415,9 @@ struct _virDomainSoundDef { size_t ncodecs; virDomainSoundCodecDefPtr *codecs; + + char *playback; + char *recording; }; typedef enum { -- 2.27.0