From nobody Thu May 15 10:08:40 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 151066713451910.579520521735276; Tue, 14 Nov 2017 05:45:34 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 46AEE10F28; Tue, 14 Nov 2017 13:45:32 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 21A568A9E8; Tue, 14 Nov 2017 13:45:32 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id DB9293FCFC; Tue, 14 Nov 2017 13:45:31 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id vAEDjR8v001625 for ; Tue, 14 Nov 2017 08:45:27 -0500 Received: by smtp.corp.redhat.com (Postfix) id 35C568B559; Tue, 14 Nov 2017 13:45:27 +0000 (UTC) Received: from antique-work.brq.redhat.com (unknown [10.43.2.152]) by smtp.corp.redhat.com (Postfix) with ESMTP id B07FAD768B for ; Tue, 14 Nov 2017 13:45:26 +0000 (UTC) From: Pavel Hrdina To: libvir-list@redhat.com Date: Tue, 14 Nov 2017 14:45:10 +0100 Message-Id: <7766efd1277955de3102fd91937016f4adf0beec.1510667009.git.phrdina@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 5/6] qemu: implement element for devices X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 14 Nov 2017 13:45:32 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" So far we were configuring the sound output based on what graphic device was configured in domain XML. This had a several disadvantages, it's not transparent, in case of multiple graphic devices it was overwritten by the last one and there was no simple way how to configure this per domain. The new element for devices allows you to configure which output will be used for each domain, however QEMU has a limitation that all sound devices will always use the same output because it is configured by environment variable QEMU_AUDIO_DRV per domain. For backward compatibility we need to preserve the defaults if no output is specified: - for vnc graphic it's by default NONE unless "vnc_allow_host_audio" was enabled, in that case we use DEFAULT which means it will pass the environment variable visible by libvirtd - for sdl graphic by default we pass the environment variable - for spice graphic we configure the SPICE output - if no graphic is configured we use by default NONE unless "nogfx_allow_host_audio" was enabled, in that case we pass the environment variable Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=3D1375433 Signed-off-by: Pavel Hrdina --- docs/formatdomain.html.in | 4 ++- src/qemu/qemu_command.c | 84 +++++++++++++++++++++----------------------= ---- src/qemu/qemu_domain.c | 54 ++++++++++++++++++++++++++++++ src/qemu/qemu_process.c | 41 +++++++++++++++++++++++ 4 files changed, 135 insertions(+), 48 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 3b7c367fc7..ae0d8b86be 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -7064,7 +7064,9 @@ qemu-kvm -net nic,model=3D? /dev/null the audio output is connected within host. There is mandatory type attribute where valid values are 'none' to disable the audio output, 'spice', 'pa', 'sdl', 'alsa', 'oss'. - This might not be supported by all hypervisors. + This might not be supported by all hypervisors. QEMU driver + has a limitation that all sound devices have to use the same + output.

=20

Watchdog device

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index c5c7bd7e54..5cbd1d0d46 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4442,67 +4442,57 @@ qemuBuildSoundCodecStr(virDomainSoundDefPtr sound, } =20 =20 -static void +static int qemuBuildSoundAudioEnv(virCommandPtr cmd, - const virDomainDef *def, - virQEMUDriverConfigPtr cfg) + const virDomainDef *def) { + char *envStr =3D NULL; + if (def->nsounds =3D=3D 0) { virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=3Dnone"); - return; + return 0; } =20 - if (def->ngraphics =3D=3D 0) { - if (cfg->nogfxAllowHostAudio) - virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL); - else - virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=3Dnone"); - } else { - switch (def->graphics[def->ngraphics - 1]->type) { - case VIR_DOMAIN_GRAPHICS_TYPE_SDL: - /* If using SDL for video, then we should just let it - * use QEMU's host audio drivers, possibly SDL too - * User can set these two before starting libvirtd - */ - virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL); + /* QEMU doesn't allow setting different audio output per sound device + * so it will always be the same for all devices. */ + switch (def->sounds[0]->output) { + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_DEFAULT: + /* The default output is used only as backward compatible way to + * pass-through environment variables configured before starting + * libvirtd. */ + virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL); + if (def->ngraphics > 0 && + def->graphics[def->ngraphics - 1]->type =3D=3D VIR_DOMAIN_GRAP= HICS_TYPE_SDL) { virCommandAddEnvPassBlockSUID(cmd, "SDL_AUDIODRIVER", NULL); + } + break; =20 - break; - - case VIR_DOMAIN_GRAPHICS_TYPE_VNC: - /* Unless user requested it, set the audio backend to none, to - * prevent it opening the host OS audio devices, since that ca= uses - * security issues and might not work when using VNC. - */ - if (cfg->vncAllowHostAudio) - virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL); - else - virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=3Dnone"); - - break; - - case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: - /* SPICE includes native support for tunnelling audio, so we - * set the audio backend to point at SPICE's own driver - */ - virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=3Dspice"); - - break; - - case VIR_DOMAIN_GRAPHICS_TYPE_RDP: - case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: - case VIR_DOMAIN_GRAPHICS_TYPE_LAST: - break; + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_NONE: + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_SPICE: + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_PA: + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_SDL: + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_ALSA: + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_OSS: + if (virAsprintf(&envStr, "QEMU_AUDIO_DRV=3D%s", + virDomainSoundOutputTypeToString(def->sounds[0]->o= utput)) < 0) { + return -1; } + virCommandAddEnvString(cmd, envStr); + VIR_FREE(envStr); + break; + + case VIR_DOMAIN_SOUND_OUTPUT_TYPE_LAST: + break; } + + return 0; } =20 =20 static int qemuBuildSoundCommandLine(virCommandPtr cmd, const virDomainDef *def, - virQEMUCapsPtr qemuCaps, - virQEMUDriverConfigPtr cfg) + virQEMUCapsPtr qemuCaps) { size_t i, j; =20 @@ -4556,7 +4546,7 @@ qemuBuildSoundCommandLine(virCommandPtr cmd, } } =20 - qemuBuildSoundAudioEnv(cmd, def, cfg); + qemuBuildSoundAudioEnv(cmd, def); =20 return 0; } @@ -10118,7 +10108,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildVideoCommandLine(cmd, def, qemuCaps) < 0) goto error; =20 - if (qemuBuildSoundCommandLine(cmd, def, qemuCaps, cfg) < 0) + if (qemuBuildSoundCommandLine(cmd, def, qemuCaps) < 0) goto error; =20 if (qemuBuildWatchdogCommandLine(cmd, def, qemuCaps) < 0) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a36e157529..3b8fa2d79c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3148,6 +3148,31 @@ qemuDomainDefVerifyFeatures(const virDomainDef *def) } =20 =20 +static void +qemuDomainDefSoundPostParse(virDomainDefPtr def) +{ + size_t i; + virDomainSoundOutputType output =3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_DEFAU= LT; + + for (i =3D 0; i < def->nsounds; i++) { + if (output !=3D def->sounds[i]->output) { + output =3D def->sounds[i]->output; + break; + } + } + + /* For convenience we will copy the first configured sound output to a= ll + * sound devices that doesn't have any output configured because QEMU + * will use only one output for all sound devices. */ + if (output !=3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_DEFAULT) { + for (i =3D 0; i < def->nsounds; i++) { + if (def->sounds[i]->output =3D=3D VIR_DOMAIN_SOUND_OUTPUT_TYPE= _DEFAULT) + def->sounds[i]->output =3D output; + } + } +} + + static int qemuDomainDefPostParseBasic(virDomainDefPtr def, virCapsPtr caps, @@ -3221,6 +3246,8 @@ qemuDomainDefPostParse(virDomainDefPtr def, if (qemuDomainDefCPUPostParse(def) < 0) goto cleanup; =20 + qemuDomainDefSoundPostParse(def); + ret =3D 0; cleanup: virObjectUnref(cfg); @@ -3301,6 +3328,30 @@ qemuDomainDefValidateVideo(const virDomainDef *def) } =20 =20 +static int +qemuDomainDefValidateSound(const virDomainDef *def) +{ + size_t i; + virDomainSoundOutputType output =3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_DEFAU= LT; + + for (i =3D 0; i < def->nsounds; i++) { + if (output =3D=3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_DEFAULT) { + output =3D def->sounds[i]->output; + continue; + } + + if (output !=3D def->sounds[i]->output) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("all sound devices must be configured to use " + "the same output")); + return -1; + } + } + + return 0; +} + + #define QEMU_MAX_VCPUS_WITHOUT_EIM 255 =20 =20 @@ -3403,6 +3454,9 @@ qemuDomainDefValidate(const virDomainDef *def, if (qemuDomainDefValidateVideo(def) < 0) goto cleanup; =20 + if (qemuDomainDefValidateSound(def) < 0) + goto cleanup; + ret =3D 0; =20 cleanup: diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6d242b1b51..2957c4a074 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5393,6 +5393,45 @@ qemuProcessPrepareAllowReboot(virDomainObjPtr vm) } =20 =20 +static void +qemuProcessPrepareSound(virDomainDefPtr def, + virQEMUDriverConfigPtr cfg) +{ + virDomainSoundOutputType output =3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_DEFAU= LT; + size_t i; + + if (def->nsounds =3D=3D 0) + return; + + if (def->ngraphics =3D=3D 0) { + if (!cfg->nogfxAllowHostAudio) + output =3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_NONE; + } else { + switch (def->graphics[def->ngraphics - 1]->type) { + case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + output =3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_SPICE; + break; + + case VIR_DOMAIN_GRAPHICS_TYPE_VNC: + if (!cfg->vncAllowHostAudio) + output =3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_NONE; + break; + + case VIR_DOMAIN_GRAPHICS_TYPE_SDL: + case VIR_DOMAIN_GRAPHICS_TYPE_RDP: + case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: + case VIR_DOMAIN_GRAPHICS_TYPE_LAST: + break; + } + } + + for (i =3D 0; i < def->nsounds; i++) { + if (def->sounds[i]->output =3D=3D VIR_DOMAIN_SOUND_OUTPUT_TYPE_DEF= AULT) + def->sounds[i]->output =3D output; + } +} + + /** * qemuProcessPrepareDomain: * @conn: connection object (for looking up storage volumes) @@ -5513,6 +5552,8 @@ qemuProcessPrepareDomain(virConnectPtr conn, goto cleanup; } =20 + qemuProcessPrepareSound(vm->def, cfg); + ret =3D 0; cleanup: virObjectUnref(caps); --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list