#1092135 libvirt-daemon-driver-qemu: apparmor policy prevents using qemu pipewire plugin

Package:
libvirt-daemon-driver-qemu
Source:
libvirt-daemon-driver-qemu
Description:
Virtualization daemon QEMU connection driver
Submitter:
Paul Aurich
Date:
2025-01-05 01:57:03 UTC
Severity:
normal
#1092135#5
Date:
2025-01-05 01:43:59 UTC
From:
To:
<audio type="pipewire"> doesn't work with libvirt launching a qemu VM --
apparmor prevents qemu from reading pipewire's config files:

    error loading config '/usr/share/pipewire/client.conf': Permission denied

Full error from libvirt:

    Error starting domain: internal error: QEMU unexpectedly closed the monitor (vm='windows'): [W][00072.258380] pw.conf      | [          conf.c:  425 conf_load()] 0x56525efc1b90: error loading config '/usr/share/pipewire/client.conf': Permission denied
    [W][00072.258417] pw.conf      | [          conf.c: 1214 try_load_conf()] can't load config client.conf: Permission denied
    [E][00072.258425] pw.conf      | [          conf.c: 1243 pw_conf_load_conf_for_context()] can't load config client.conf: Permission denied
    2025-01-04T19:47:34.028540Z qemu-system-x86_64: Could not create PipeWire context: Permission denied

    Traceback (most recent call last):
      File "/usr/share/virt-manager/virtManager/asyncjob.py", line 71, in cb_wrapper
        callback(asyncjob, *args, **kwargs)
      File "/usr/share/virt-manager/virtManager/asyncjob.py", line 107, in tmpcb
        callback(*args, **kwargs)
      File "/usr/share/virt-manager/virtManager/object/libvirtobject.py", line 57, in newfn
        ret = fn(self, *args, **kwargs)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/share/virt-manager/virtManager/object/domain.py", line 1384, in startup
        self._backend.create()
      File "/usr/lib/python3/dist-packages/libvirt.py", line 1379, in create
        raise libvirtError('virDomainCreate() failed')
    libvirt.libvirtError: internal error: QEMU unexpectedly closed the monitor (vm='windows'): [W][00072.258380] pw.conf      | [          conf.c:  425 conf_load()] 0x56525efc1b90: error loading config '/usr/share/pipewire/client.conf': Permission denied
    [W][00072.258417] pw.conf      | [          conf.c: 1214 try_load_conf()] can't load config client.conf: Permission denied
    [E][00072.258425] pw.conf      | [          conf.c: 1243 pw_conf_load_conf_for_context()] can't load config client.conf: Permission denied
    2025-01-04T19:47:34.028540Z qemu-system-x86_64: Could not create PipeWire context: Permission denied


The pertinent bits of the domain XML:

<domain type="kvm">
[...]
  <devices>
    [...]
    <sound model="ich9">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
    </sound>
    <audio id="1" type="pipewire" runtimeDir="/run/user/1000">
      <input name="qemuinput"/>
      <output name="qemuoutput"/>
    </audio>
    [...]
  </devices>
</domain>

I fixed this by adding an '#include <abstraction/audio>' to the libvirt-qemu
apparmor policy and then reloading apparmor:

    paul@redcloak ~ % cat /etc/apparmor.d/abstractions/libvirt-qemu.d/local-audio
    # Allow libvirt QEMU VMs access to audio stuff (i.e. pipewire config files and
    # pipes)

    #include <abstractions/audio>
    paul@redcloak ~ %

(This also worked when included in the /etc/apparmor/libvirt/ file for
a specific VM).


I also had to add 'user = "paul"' into /etc/libvirt/qemu.conf, otherwise
libvirt reported:

    2025-01-05T01:22:07.268875Z qemu-system-x86_64: Failed to connect to PipeWire instance: Host is down

(I'm just mentioning that for sake of completeness.  I was expecting to need
to make that config change.)