[PATCH 0/5] qemu: Clean up testing of sound devices and implement 'multichannel' support for 'usb-audio'

Peter Krempa (5): docs: formatdomain: Use code blocks to emphasize various sound device options qemuxml2(argv|xml)test: Remove 'sound' case qemuxml2(argv|xml)test: Modernize 'sound-device' case conf: Register autoptr cleanup for 'virDomainSoundDef' and refactor virDomainSoundDefParseXML conf: qemu: Add support for multi-channel mode for 'usb' sound cards docs/formatdomain.rst | 55 ++++++++++--------- src/conf/domain_conf.c | 42 ++++++++++---- src/conf/domain_conf.h | 5 ++ src/conf/schemas/domaincommon.rng | 5 ++ src/qemu/qemu_command.c | 3 + ...ce.args => sound-device.x86_64-4.2.0.args} | 13 ++--- .../sound-device.x86_64-latest.args | 50 +++++++++++++++++ tests/qemuxml2argvdata/sound-device.xml | 12 +--- tests/qemuxml2argvdata/sound.args | 37 ------------- tests/qemuxml2argvdata/sound.xml | 34 ------------ tests/qemuxml2argvtest.c | 8 +-- ...ice.xml => sound-device.x86_64-latest.xml} | 17 +++--- tests/qemuxml2xmloutdata/sound.xml | 43 --------------- tests/qemuxml2xmltest.c | 8 +-- 14 files changed, 142 insertions(+), 190 deletions(-) rename tests/qemuxml2argvdata/{sound-device.args => sound-device.x86_64-4.2.0.args} (80%) create mode 100644 tests/qemuxml2argvdata/sound-device.x86_64-latest.args delete mode 100644 tests/qemuxml2argvdata/sound.args delete mode 100644 tests/qemuxml2argvdata/sound.xml rename tests/qemuxml2xmloutdata/{sound-device.xml => sound-device.x86_64-latest.xml} (82%) delete mode 100644 tests/qemuxml2xmloutdata/sound.xml -- 2.40.0

Emphasize the various sound card models and other config options by using ``...``. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/formatdomain.rst | 50 +++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 99e0a4241c..d62bda9adb 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7209,9 +7209,9 @@ A virtual sound card can be attached to the host via the ``sound`` element. ``sound`` The ``sound`` element has one mandatory attribute, ``model``, which specifies what real sound device is emulated. Valid values are specific to the - underlying hypervisor, though typical choices are 'sb16', 'es1370', 'pcspk', - 'ac97' (:since:`Since 0.6.0`), 'ich6' (:since:`Since 0.8.8`), 'ich9' - (:since:`Since 1.1.3`), 'usb' (:since:`Since 1.2.8`) and 'ich7' + underlying hypervisor, though typical choices are ``sb16``, ``es1370``, + ``pcspk``, ``ac97`` (:since:`Since 0.6.0`), ``ich6`` (:since:`Since 0.8.8`), + ``ich9`` (:since:`Since 1.1.3`), ``usb`` (:since:`Since 1.2.8`) and ``ich7`` (:since:`Since 6.7.0`, bhyve only). :since:`Since 0.9.13` , a sound element with ``ich6`` or ``ich9`` models can have @@ -7221,9 +7221,9 @@ and recording. Valid values are: -- 'duplex' - advertise a line-in and a line-out -- 'micro' - advertise a speaker and a microphone -- 'output' - advertise a line-out :since:`Since 4.4.0` +- ``duplex`` - advertise a line-in and a line-out +- ``micro`` - advertise a speaker and a microphone +- ``output`` - advertise a line-out :since:`Since 4.4.0` :: @@ -7264,8 +7264,8 @@ to the guest sound device. ``type`` The required ``type`` attribute specifies audio backend type. - Currently, the supported values are 'none', 'alsa', 'coreaudio', - 'dbus', jack', 'oss', 'pulseaudio', 'sdl', 'spice', 'file'. + Currently, the supported values are ``none``, ``alsa``, ``coreaudio``, + ``dbus``, ``jack``, ``oss``, ``pulseaudio``, ``sdl``, ``spice``, ``file``. ``id`` Integer id of the audio device. Must be greater than 0. @@ -7339,22 +7339,22 @@ is permitted with the following attributes. Note: If no ``<audio/>`` element is defined, and the ``graphics`` element is set to -either 'vnc' or 'sdl', the libvirtd or virtqemud process will honor the following -environment variables: +either ``vnc`` or ``sdl``, the libvirtd or virtqemud process will honor the +following environment variables: * ``SDL_AUDIODRIVER`` - Valid values are 'pulseaudio', 'esd', 'alsa' or 'arts'. + Valid values are ``pulseaudio``, ``esd``, ``alsa`` or ``arts``. * ``QEMU_AUDIO_DRV`` - Valid values are 'pa', 'none', 'alsa', 'coreaudio', 'jack', 'oss', - 'sdl', 'spice' or 'wav'. + Valid values are ``pa``, ``none``, ``alsa``, ``coreaudio``, ``jack``, ``oss``, + ``sdl``, ``spice`` or ``wav``. None audio backend ^^^^^^^^^^^^^^^^^^ -The 'none' audio backend is a dummy backend that does not connect to +The ``none`` audio backend is a dummy backend that does not connect to any host audio framework. It still allows a remote desktop server like VNC to send and receive audio though. This is the default backend when VNC graphics are enabled in QEMU. @@ -7364,7 +7364,7 @@ when VNC graphics are enabled in QEMU. ALSA audio backend ^^^^^^^^^^^^^^^^^^ -The 'alsa' audio type uses the ALSA host audio device framework. +The ``alsa`` audio type uses the ALSA host audio device framework. The following additional attributes are permitted on the ``<input>`` and ``<output>`` elements @@ -7386,7 +7386,7 @@ and ``<output>`` elements Coreaudio audio backend ^^^^^^^^^^^^^^^^^^^^^^^ -The 'coreaudio' audio backend delegates to a CoreAudio host audio framework +The ``coreaudio`` audio backend delegates to a CoreAudio host audio framework for input and output on macOS. The following additional attributes are permitted on the ``<input>`` @@ -7409,7 +7409,7 @@ and ``<output>`` elements D-Bus audio backend ^^^^^^^^^^^^^^^^^^^ -The 'dbus' audio backend does not connect to any host audio framework. It +The ``dbus`` audio backend does not connect to any host audio framework. It exports a D-Bus interface when associated with a D-Bus display. :since:`Since 8.4.0, qemu` @@ -7417,7 +7417,7 @@ exports a D-Bus interface when associated with a D-Bus display. Jack audio backend ^^^^^^^^^^^^^^^^^^ -The 'jack' audio backend delegates to a Jack daemon for audio input +The ``jack`` audio backend delegates to a Jack daemon for audio input and output. The following additional attributes are permitted on the ``<input>`` @@ -7453,7 +7453,7 @@ and ``<output>`` elements OSS audio backend ^^^^^^^^^^^^^^^^^ -The 'oss' audio type uses the OSS host audio device framework. +The ``oss`` audio type uses the OSS host audio device framework. The following additional attributes are permitted on the ``<audio>`` element @@ -7501,7 +7501,7 @@ and ``<output>`` elements PulseAudio audio backend ^^^^^^^^^^^^^^^^^^^^^^^^ -The 'pulseaudio' audio backend delegates to a PulseAudio daemon audio input +The ``pulseaudio`` audio backend delegates to a PulseAudio daemon audio input and output. The following additional attributes are permitted on the ``<audio>`` @@ -7538,7 +7538,7 @@ and ``<output>`` elements SDL audio backend ^^^^^^^^^^^^^^^^^ -The 'sdl' audio backend delegates to the SDL library for audio input +The ``sdl`` audio backend delegates to the SDL library for audio input and output. The following additional attributes are permitted on the ``<audio>`` @@ -7547,7 +7547,7 @@ element * ``driver`` SDL audio driver. The ``name`` attribute specifies SDL driver name, - one of 'esd', 'alsa', 'arts', 'pulseaudio'. + one of ``esd``, ``alsa``, ``arts``, ``pulseaudio``. The following additional attributes are permitted on the ``<input>`` and ``<output>`` elements @@ -7569,7 +7569,7 @@ and ``<output>`` elements Spice audio backend ^^^^^^^^^^^^^^^^^^^ -The 'spice' audio backend is similar to the 'none' backend in that +The ``spice`` audio backend is similar to the ``none`` backend in that it does not connect to any host audio framework. It exclusively allows a SPICE server to send and receive audio. This is the default backend when SPICE graphics are enabled in QEMU. @@ -7583,9 +7583,9 @@ backend when SPICE graphics are enabled in QEMU. File audio backend ^^^^^^^^^^^^^^^^^^ -The 'file' audio backend is an output only driver which records +The ``file`` audio backend is an output only driver which records audio to a file. The file format is implementation defined, and -defaults to 'WAV' with QEMU. +defaults to ``WAV`` with QEMU. :: -- 2.40.0

The test case is a subset of what the 'sound-device' case tests. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemuxml2argvdata/sound.args | 37 ------------------------- tests/qemuxml2argvdata/sound.xml | 34 ----------------------- tests/qemuxml2argvtest.c | 1 - tests/qemuxml2xmloutdata/sound.xml | 43 ------------------------------ tests/qemuxml2xmltest.c | 1 - 5 files changed, 116 deletions(-) delete mode 100644 tests/qemuxml2argvdata/sound.args delete mode 100644 tests/qemuxml2argvdata/sound.xml delete mode 100644 tests/qemuxml2xmloutdata/sound.xml diff --git a/tests/qemuxml2argvdata/sound.args b/tests/qemuxml2argvdata/sound.args deleted file mode 100644 index d077c37c76..0000000000 --- a/tests/qemuxml2argvdata/sound.args +++ /dev/null @@ -1,37 +0,0 @@ -LC_ALL=C \ -PATH=/bin \ -HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ -USER=test \ -LOGNAME=test \ -XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ -XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ -XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -/usr/bin/qemu-system-i386 \ --name guest=QEMUGuest1,debug-threads=on \ --S \ --object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes \ --machine pc,usb=off,dump-guest-core=off \ --accel tcg \ --m 214 \ --overcommit mem-lock=off \ --smp 1,sockets=1,cores=1,threads=1 \ --uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ --display none \ --no-user-config \ --nodefaults \ --chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ --mon chardev=charmonitor,id=monitor,mode=control \ --rtc base=utc \ --no-shutdown \ --no-acpi \ --boot strict=on \ --usb \ --blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ --blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ --device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1 \ --audiodev '{"id":"audio1","driver":"none"}' \ --soundhw pcspk \ --device ES1370,id=sound1,audiodev=audio1,bus=pci.0,addr=0x2 \ --device sb16,id=sound2,audiodev=audio1 \ --device AC97,id=sound3,audiodev=audio1,bus=pci.0,addr=0x3 \ --msg timestamp=on diff --git a/tests/qemuxml2argvdata/sound.xml b/tests/qemuxml2argvdata/sound.xml deleted file mode 100644 index dd45361a69..0000000000 --- a/tests/qemuxml2argvdata/sound.xml +++ /dev/null @@ -1,34 +0,0 @@ -<domain type='qemu'> - <name>QEMUGuest1</name> - <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> - <memory unit='KiB'>219136</memory> - <currentMemory unit='KiB'>219136</currentMemory> - <vcpu placement='static'>1</vcpu> - <os> - <type arch='i686' machine='pc'>hvm</type> - <boot dev='hd'/> - </os> - <clock offset='utc'/> - <on_poweroff>destroy</on_poweroff> - <on_reboot>restart</on_reboot> - <on_crash>destroy</on_crash> - <devices> - <emulator>/usr/bin/qemu-system-i386</emulator> - <disk type='block' device='disk'> - <driver name='qemu' type='raw'/> - <source dev='/dev/HostVG/QEMUGuest1'/> - <target dev='hda' bus='ide'/> - <address type='drive' controller='0' bus='0' target='0' unit='0'/> - </disk> - <controller type='usb' index='0'/> - <controller type='ide' index='0'/> - <controller type='pci' index='0' model='pci-root'/> - <input type='mouse' bus='ps2'/> - <input type='keyboard' bus='ps2'/> - <sound model='pcspk'/> - <sound model='es1370'/> - <sound model='sb16'/> - <sound model='ac97'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 3c75a2dce2..755e8fd664 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1691,7 +1691,6 @@ mymain(void) QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE); DO_TEST_NOCAPS("balloon-device-auto"); DO_TEST_NOCAPS("balloon-device-period"); - DO_TEST_NOCAPS("sound"); DO_TEST("sound-device", QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_HDA_MICRO, QEMU_CAPS_HDA_OUTPUT, diff --git a/tests/qemuxml2xmloutdata/sound.xml b/tests/qemuxml2xmloutdata/sound.xml deleted file mode 100644 index 1ffa7412d6..0000000000 --- a/tests/qemuxml2xmloutdata/sound.xml +++ /dev/null @@ -1,43 +0,0 @@ -<domain type='qemu'> - <name>QEMUGuest1</name> - <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> - <memory unit='KiB'>219136</memory> - <currentMemory unit='KiB'>219136</currentMemory> - <vcpu placement='static'>1</vcpu> - <os> - <type arch='i686' machine='pc'>hvm</type> - <boot dev='hd'/> - </os> - <clock offset='utc'/> - <on_poweroff>destroy</on_poweroff> - <on_reboot>restart</on_reboot> - <on_crash>destroy</on_crash> - <devices> - <emulator>/usr/bin/qemu-system-i386</emulator> - <disk type='block' device='disk'> - <driver name='qemu' type='raw'/> - <source dev='/dev/HostVG/QEMUGuest1'/> - <target dev='hda' bus='ide'/> - <address type='drive' controller='0' bus='0' target='0' unit='0'/> - </disk> - <controller type='usb' index='0'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> - </controller> - <controller type='ide' index='0'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> - </controller> - <controller type='pci' index='0' model='pci-root'/> - <input type='mouse' bus='ps2'/> - <input type='keyboard' bus='ps2'/> - <sound model='pcspk'/> - <sound model='es1370'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> - </sound> - <sound model='sb16'/> - <sound model='ac97'> - <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> - </sound> - <audio id='1' type='none'/> - <memballoon model='none'/> - </devices> -</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 066c5a49c4..8e9da95efb 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -449,7 +449,6 @@ mymain(void) DO_TEST("net-hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_NOCAPS("net-midonet"); DO_TEST_NOCAPS("net-openvswitch"); - DO_TEST_NOCAPS("sound"); DO_TEST("sound-device", QEMU_CAPS_DEVICE_ICH9_INTEL_HDA, QEMU_CAPS_OBJECT_USB_AUDIO, -- 2.40.0

Drop the unnecessary disk definition and use x86_64 emulator. For 'qemuxml2argvtest' replace the fake-caps invocation by a 4.2.0 version-locked invocation and add a '_CAPS_LATEST' invocation. For 'qemuxml2xmltest' convert to use '_CAPS_LATEST' only. There are no sound-device relevant changes in the output files. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- ...ce.args => sound-device.x86_64-4.2.0.args} | 11 ++-- .../sound-device.x86_64-latest.args | 50 +++++++++++++++++++ tests/qemuxml2argvdata/sound-device.xml | 10 +--- tests/qemuxml2argvtest.c | 7 +-- ...ice.xml => sound-device.x86_64-latest.xml} | 15 +++--- tests/qemuxml2xmltest.c | 7 +-- 6 files changed, 66 insertions(+), 34 deletions(-) rename tests/qemuxml2argvdata/{sound-device.args => sound-device.x86_64-4.2.0.args} (82%) create mode 100644 tests/qemuxml2argvdata/sound-device.x86_64-latest.args rename tests/qemuxml2xmloutdata/{sound-device.xml => sound-device.x86_64-latest.xml} (83%) diff --git a/tests/qemuxml2argvdata/sound-device.args b/tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args similarity index 82% rename from tests/qemuxml2argvdata/sound-device.args rename to tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args index 0a9a3e5ddb..121b37ff99 100644 --- a/tests/qemuxml2argvdata/sound-device.args +++ b/tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args @@ -6,12 +6,13 @@ LOGNAME=test \ XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -/usr/bin/qemu-system-i386 \ +/usr/bin/qemu-system-x86_64 \ -name guest=QEMUGuest1,debug-threads=on \ -S \ -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes \ --machine pc,usb=off,dump-guest-core=off \ +-machine pc-i440fx-4.2,usb=off,dump-guest-core=off \ -accel tcg \ +-cpu qemu64 \ -m 214 \ -overcommit mem-lock=off \ -smp 1,sockets=1,cores=1,threads=1 \ @@ -25,10 +26,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -no-shutdown \ -no-acpi \ -boot strict=on \ --usb \ --blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ --blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ --device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1 \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ -audiodev '{"id":"audio1","driver":"none"}' \ -soundhw pcspk \ -device ES1370,id=sound1,audiodev=audio1,bus=pci.0,addr=0x2 \ @@ -48,4 +46,5 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device hda-output,id=sound7-codec2,bus=sound7.0,cad=2,audiodev=audio1 \ -device usb-audio,id=sound8,audiodev=audio1,bus=usb.0,port=1 \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/sound-device.x86_64-latest.args b/tests/qemuxml2argvdata/sound-device.x86_64-latest.args new file mode 100644 index 0000000000..3132760fe0 --- /dev/null +++ b/tests/qemuxml2argvdata/sound-device.x86_64-latest.args @@ -0,0 +1,50 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ +-accel tcg \ +-cpu qemu64 \ +-m 214 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-soundhw pcspk \ +-device '{"driver":"ES1370","id":"sound1","audiodev":"audio1","bus":"pci.0","addr":"0x2"}' \ +-device '{"driver":"sb16","id":"sound2","audiodev":"audio1"}' \ +-device '{"driver":"AC97","id":"sound3","audiodev":"audio1","bus":"pci.0","addr":"0x3"}' \ +-device '{"driver":"intel-hda","id":"sound4","bus":"pci.0","addr":"0x4"}' \ +-device '{"driver":"hda-duplex","id":"sound4-codec0","bus":"sound4.0","cad":0,"audiodev":"audio1"}' \ +-device '{"driver":"intel-hda","id":"sound5","bus":"pci.0","addr":"0x5"}' \ +-device '{"driver":"hda-micro","id":"sound5-codec0","bus":"sound5.0","cad":0,"audiodev":"audio1"}' \ +-device '{"driver":"hda-duplex","id":"sound5-codec1","bus":"sound5.0","cad":1,"audiodev":"audio1"}' \ +-device '{"driver":"hda-output","id":"sound5-codec2","bus":"sound5.0","cad":2,"audiodev":"audio1"}' \ +-device '{"driver":"ich9-intel-hda","id":"sound6","bus":"pci.0","addr":"0x6"}' \ +-device '{"driver":"hda-duplex","id":"sound6-codec0","bus":"sound6.0","cad":0,"audiodev":"audio1"}' \ +-device '{"driver":"ich9-intel-hda","id":"sound7","bus":"pci.0","addr":"0x7"}' \ +-device '{"driver":"hda-micro","id":"sound7-codec0","bus":"sound7.0","cad":0,"audiodev":"audio1"}' \ +-device '{"driver":"hda-duplex","id":"sound7-codec1","bus":"sound7.0","cad":1,"audiodev":"audio1"}' \ +-device '{"driver":"hda-output","id":"sound7-codec2","bus":"sound7.0","cad":2,"audiodev":"audio1"}' \ +-device '{"driver":"usb-audio","id":"sound8","audiodev":"audio1","bus":"usb.0","port":"1"}' \ +-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x8"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/sound-device.xml b/tests/qemuxml2argvdata/sound-device.xml index b9427f880a..35a60da197 100644 --- a/tests/qemuxml2argvdata/sound-device.xml +++ b/tests/qemuxml2argvdata/sound-device.xml @@ -5,20 +5,14 @@ <currentMemory unit='KiB'>219100</currentMemory> <vcpu placement='static'>1</vcpu> <os> - <type arch='i686' machine='pc'>hvm</type> - <boot dev='hd'/> + <type arch='x86_64' machine='pc'>hvm</type> </os> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <devices> - <emulator>/usr/bin/qemu-system-i386</emulator> - <disk type='block' device='disk'> - <source dev='/dev/HostVG/QEMUGuest1'/> - <target dev='hda' bus='ide'/> - <address type='drive' controller='0' bus='0' target='0' unit='0'/> - </disk> + <emulator>/usr/bin/qemu-system-x86_64</emulator> <controller type='usb' index='0'/> <controller type='ide' index='0'/> <controller type='pci' index='0' model='pci-root'/> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 755e8fd664..3100078b54 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1691,11 +1691,8 @@ mymain(void) QEMU_CAPS_VIRTIO_BALLOON_AUTODEFLATE); DO_TEST_NOCAPS("balloon-device-auto"); DO_TEST_NOCAPS("balloon-device-period"); - DO_TEST("sound-device", - QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_HDA_MICRO, - QEMU_CAPS_HDA_OUTPUT, - QEMU_CAPS_DEVICE_ICH9_INTEL_HDA, - QEMU_CAPS_OBJECT_USB_AUDIO); + DO_TEST_CAPS_VER("sound-device", "4.2.0"); + DO_TEST_CAPS_LATEST("sound-device"); DO_TEST_CAPS_LATEST("fs9p"); DO_TEST_CAPS_ARCH_LATEST("fs9p-ccw", "s390x"); diff --git a/tests/qemuxml2xmloutdata/sound-device.xml b/tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml similarity index 83% rename from tests/qemuxml2xmloutdata/sound-device.xml rename to tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml index 87d9a5524c..89f537bb01 100644 --- a/tests/qemuxml2xmloutdata/sound-device.xml +++ b/tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml @@ -5,22 +5,19 @@ <currentMemory unit='KiB'>219100</currentMemory> <vcpu placement='static'>1</vcpu> <os> - <type arch='i686' machine='pc'>hvm</type> + <type arch='x86_64' machine='pc'>hvm</type> <boot dev='hd'/> </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <devices> - <emulator>/usr/bin/qemu-system-i386</emulator> - <disk type='block' device='disk'> - <driver name='qemu' type='raw'/> - <source dev='/dev/HostVG/QEMUGuest1'/> - <target dev='hda' bus='ide'/> - <address type='drive' controller='0' bus='0' target='0' unit='0'/> - </disk> - <controller type='usb' index='0'> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='piix3-uhci'> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <controller type='ide' index='0'> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 8e9da95efb..93202e8e18 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -449,12 +449,7 @@ mymain(void) DO_TEST("net-hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_NOCAPS("net-midonet"); DO_TEST_NOCAPS("net-openvswitch"); - DO_TEST("sound-device", - QEMU_CAPS_DEVICE_ICH9_INTEL_HDA, - QEMU_CAPS_OBJECT_USB_AUDIO, - QEMU_CAPS_HDA_MICRO, - QEMU_CAPS_HDA_DUPLEX, - QEMU_CAPS_HDA_OUTPUT); + DO_TEST_CAPS_LATEST("sound-device"); DO_TEST_NOCAPS("watchdog"); DO_TEST_CAPS_LATEST("watchdog-q35-multiple"); DO_TEST("net-bandwidth", QEMU_CAPS_DEVICE_VGA, QEMU_CAPS_VNC); -- 2.40.0

Use our modern cleanup path pattern. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 19 +++++++------------ src/conf/domain_conf.h | 1 + 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ac7165bad4..204b6a85e1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11654,16 +11654,15 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt, xmlXPathContextPtr ctxt, unsigned int flags) { - virDomainSoundDef *def; + g_autoptr(virDomainSoundDef) def = g_new0(virDomainSoundDef, 1); VIR_XPATH_NODE_AUTORESTORE(ctxt) xmlNodePtr audioNode; - def = g_new0(virDomainSoundDef, 1); ctxt->node = node; if (virXMLPropEnum(node, "model", virDomainSoundModelTypeFromString, VIR_XML_PROP_REQUIRED, &def->model) < 0) - goto error; + return NULL; if (virDomainSoundModelSupportsCodecs(def)) { int ncodecs; @@ -11672,7 +11671,7 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt, /* parse the <codec> subelements for sound models that support it */ ncodecs = virXPathNodeSet("./codec", ctxt, &codecNodes); if (ncodecs < 0) - goto error; + return NULL; if (ncodecs > 0) { size_t i; @@ -11682,7 +11681,7 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt, for (i = 0; i < ncodecs; i++) { virDomainSoundCodecDef *codec = virDomainSoundCodecDefParseXML(codecNodes[i]); if (codec == NULL) - goto error; + return NULL; codec->cad = def->ncodecs; /* that will do for now */ def->codecs[def->ncodecs++] = codec; @@ -11695,17 +11694,13 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt, if (virXMLPropUInt(audioNode, "id", 10, VIR_XML_PROP_REQUIRED | VIR_XML_PROP_NONZERO, &def->audioId) < 0) - goto error; + return NULL; } if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, flags) < 0) - goto error; - - return def; + return NULL; - error: - virDomainSoundDefFree(def); - return NULL; + return g_steal_pointer(&def); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 88aef29912..a04f7decc6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3569,6 +3569,7 @@ void virDomainSoundCodecDefFree(virDomainSoundCodecDef *def); ssize_t virDomainSoundDefFind(const virDomainDef *def, const virDomainSoundDef *sound); void virDomainSoundDefFree(virDomainSoundDef *def); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainSoundDef, virDomainSoundDefFree); virDomainSoundDef *virDomainSoundDefRemove(virDomainDef *def, size_t idx); void virDomainAudioDefFree(virDomainAudioDef *def); void virDomainMemballoonDefFree(virDomainMemballoonDef *def); -- 2.40.0

Allow users controlling the multi-channel mode by adding a 'multichannel' property parsed for USB audio devices and wire up the support in the qemu driver. Closes: https://gitlab.com/libvirt/libvirt/-/issues/472 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/formatdomain.rst | 5 ++++ src/conf/domain_conf.c | 23 +++++++++++++++++++ src/conf/domain_conf.h | 4 ++++ src/conf/schemas/domaincommon.rng | 5 ++++ src/qemu/qemu_command.c | 3 +++ .../sound-device.x86_64-4.2.0.args | 2 +- .../sound-device.x86_64-latest.args | 2 +- tests/qemuxml2argvdata/sound-device.xml | 2 +- .../sound-device.x86_64-latest.xml | 2 +- 9 files changed, 44 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index d62bda9adb..99383e725c 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7235,6 +7235,11 @@ Valid values are: </devices> ... +:since:`Since 9.4.0` the ``usb`` sound device can be optionally switched into +multi-channel mode by using the ``multichannel`` attribute:: + + <sound model='usb' multichannel='yes'/> + Each ``sound`` element has an optional sub-element ``<address>`` which can tie the device to a particular PCI slot. See `Device Addresses`_. diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 204b6a85e1..6a864a8db9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11689,6 +11689,12 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt, } } + if (def->model == VIR_DOMAIN_SOUND_MODEL_USB) { + if (virXMLPropTristateBool(node, "multichannel", VIR_XML_PROP_NONE, + &def->multichannel) < 0) + return NULL; + } + audioNode = virXPathNode("./audio", ctxt); if (audioNode) { if (virXMLPropUInt(audioNode, "id", 10, @@ -11721,6 +11727,9 @@ virDomainSoundDefEquals(const virDomainSoundDef *a, return false; } + if (a->multichannel != b->multichannel) + return false; + if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && !virDomainDeviceInfoAddressIsEqual(&a->info, &b->info)) return false; @@ -20010,6 +20019,14 @@ virDomainSoundDefCheckABIStability(virDomainSoundDef *src, return false; } + if (src->multichannel != dst->multichannel) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target sound card multichannel setting '%1$s' does not match source '%2$s'"), + virTristateBoolTypeToString(dst->multichannel), + virTristateBoolTypeToString(src->multichannel)); + return false; + } + if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info)) return false; @@ -24531,6 +24548,12 @@ virDomainSoundDefFormat(virBuffer *buf, virBufferAsprintf(&attrBuf, " model='%s'", model); + if (def->model == VIR_DOMAIN_SOUND_MODEL_USB && + def->multichannel != VIR_TRISTATE_BOOL_ABSENT) { + virBufferAsprintf(&attrBuf, " multichannel='%s'", + virTristateBoolTypeToString(def->multichannel)); + } + virXMLFormatElement(buf, "sound", &attrBuf, &childBuf); return 0; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a04f7decc6..c1cb2ed69d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1596,6 +1596,10 @@ struct _virDomainSoundDef { size_t ncodecs; virDomainSoundCodecDef **codecs; + /* VIR_DOMAIN_SOUND_MODEL_USB can be optionally switched to + * multi-channel mode */ + virTristateBool multichannel; + unsigned int audioId; }; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 57fb4a5e33..f8c7b6a648 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -4969,6 +4969,11 @@ <value>usb</value> </choice> </attribute> + <optional> + <attribute name="multichannel"> + <ref name="virYesNo"/> + </attribute> + </optional> <interleave> <optional> <ref name="alias"/> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index dcad449413..2a6d9408f6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4384,6 +4384,7 @@ qemuBuildSoundDevCmd(virCommand *cmd, g_autoptr(virJSONValue) props = NULL; const char *model = NULL; g_autofree char *audioid = NULL; + virTristateBool multichannel = VIR_TRISTATE_BOOL_ABSENT; switch (sound->model) { case VIR_DOMAIN_SOUND_MODEL_ES1370: @@ -4397,6 +4398,7 @@ qemuBuildSoundDevCmd(virCommand *cmd, break; case VIR_DOMAIN_SOUND_MODEL_USB: model = "usb-audio"; + multichannel = sound->multichannel; break; case VIR_DOMAIN_SOUND_MODEL_ICH9: model = "ich9-intel-hda"; @@ -4419,6 +4421,7 @@ qemuBuildSoundDevCmd(virCommand *cmd, "s:driver", model, "s:id", sound->info.alias, "S:audiodev", audioid, + "T:multi", multichannel, NULL) < 0) return -1; diff --git a/tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args b/tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args index 121b37ff99..b2a5afd8c8 100644 --- a/tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args +++ b/tests/qemuxml2argvdata/sound-device.x86_64-4.2.0.args @@ -44,7 +44,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device hda-micro,id=sound7-codec0,bus=sound7.0,cad=0,audiodev=audio1 \ -device hda-duplex,id=sound7-codec1,bus=sound7.0,cad=1,audiodev=audio1 \ -device hda-output,id=sound7-codec2,bus=sound7.0,cad=2,audiodev=audio1 \ --device usb-audio,id=sound8,audiodev=audio1,bus=usb.0,port=1 \ +-device usb-audio,id=sound8,audiodev=audio1,multi=on,bus=usb.0,port=1 \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/sound-device.x86_64-latest.args b/tests/qemuxml2argvdata/sound-device.x86_64-latest.args index 3132760fe0..e0a2f21b31 100644 --- a/tests/qemuxml2argvdata/sound-device.x86_64-latest.args +++ b/tests/qemuxml2argvdata/sound-device.x86_64-latest.args @@ -44,7 +44,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"hda-micro","id":"sound7-codec0","bus":"sound7.0","cad":0,"audiodev":"audio1"}' \ -device '{"driver":"hda-duplex","id":"sound7-codec1","bus":"sound7.0","cad":1,"audiodev":"audio1"}' \ -device '{"driver":"hda-output","id":"sound7-codec2","bus":"sound7.0","cad":2,"audiodev":"audio1"}' \ --device '{"driver":"usb-audio","id":"sound8","audiodev":"audio1","bus":"usb.0","port":"1"}' \ +-device '{"driver":"usb-audio","id":"sound8","audiodev":"audio1","multi":true,"bus":"usb.0","port":"1"}' \ -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x8"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/sound-device.xml b/tests/qemuxml2argvdata/sound-device.xml index 35a60da197..c58033235c 100644 --- a/tests/qemuxml2argvdata/sound-device.xml +++ b/tests/qemuxml2argvdata/sound-device.xml @@ -34,7 +34,7 @@ <codec type='duplex'/> <codec type='output'/> </sound> - <sound model='usb'/> + <sound model='usb' multichannel='yes'/> <memballoon model='virtio'/> </devices> </domain> diff --git a/tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml b/tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml index 89f537bb01..29d700cebb 100644 --- a/tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml +++ b/tests/qemuxml2xmloutdata/sound-device.x86_64-latest.xml @@ -52,7 +52,7 @@ <codec type='output'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </sound> - <sound model='usb'/> + <sound model='usb' multichannel='yes'/> <audio id='1' type='none'/> <memballoon model='virtio'> <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> -- 2.40.0

On a Tuesday in 2023, Peter Krempa wrote:
Peter Krempa (5): docs: formatdomain: Use code blocks to emphasize various sound device options qemuxml2(argv|xml)test: Remove 'sound' case qemuxml2(argv|xml)test: Modernize 'sound-device' case conf: Register autoptr cleanup for 'virDomainSoundDef' and refactor virDomainSoundDefParseXML conf: qemu: Add support for multi-channel mode for 'usb' sound cards
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa