I have a well-working PCI-passthrough setup with NixOS using libvirt, where audio from the guest is piped into Pulseaudio. This works, just only not during a reboot where the state of the guest is resumed; if the host is restarted without first shutting down the guest I’m unable to properly start Pulseaudio — the guest must first be shut down before restarting the host.
If this is not done, manual invocation of Pulseaudio yields “bind(): Address already in use”. Running pulseaudio -k yields “No such process”.
As a work-around I tried to apply virtualisation.libvirtd.onShutdown = "shutdown" but this, oddly enough, had no effect.
I figure I could resolve this by making sure guests aren’t resumed until Pulseaudio have been fully started. How would I do this?
The general approach would be to change the libvirt systemd unit to instruct it to start after PulseAudio.
Looking in the nixpkgs source code I see that systemd.services.libvirtd is defined in nixos/modules/virtualisation/libvirtd.nix. So now all that needs to be done is add something like this in the nixos configuration:
One complication is the pulseaudio might be tied to a user session.
pulseaudio should run in a user session unless it is running on a dedicated appliance (media center, smart-speaker, or similar) so the proposed fix will not do the trick.
After updating to 18.09 Pulseaudio works as expected on the host, but now the guest has no connection to it; a lot of ALSA/PulseAudio “Unable to connect: Connection refused” errors are logged. Perhaps guest resumes across host reboots using QEMU_AUDIO_DRV=pa QEMU_PA_SERVER=/run/user/1000/pulse/native are not supported?
I created a PR so that the option is used, but the guests are still fired up — before the Pulseaudio units, I presume — when powering on the system again,
which works — even when resuming a suspended domain — but I’m not sure of its limitations; I think the domain will eventually start if I idle at the login screen, and there would then be no Pulseaudio daemon to talk to.
Surely, though, there must be a better solution; is it possible to make a system unit depend on a user unit? Or is it possible to somehow force a Pulseaudio to start for a user before that user has logged in?
The alternative is to override ExecStart in libvirt-guests.service to an empty string, requiring one to manually start/resume the domain instead.