Spice audio does not work when spicy is opened from lxc console --type vga

Hi,

Audio does not work when spicy is opened using:

lxc console win11 --type vga

However audio works with this same instance if I open spicy from cli and use this same spice socket:

spicy --uri=spice+unix:///home/mika/snap/lxd/common/config/sockets/1062376126.spice

This is probably related to some privilege issue (e.g. cannot connect to dbus) when spicy is opened from lxd snap package.

Lxc console command outputs errors like:

(spicy:1633481): dbind-WARNING **: 23:05:45.126: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
GSpice-Message: 23:05:45.182: main channel: opened
/dev/shm/jack_db-0/__db.001: No such file or directory

These errors are not shown if I open spicy from cli.

Instance configuration is:

lxc config show win11
architecture: x86_64
config:
  limits.cpu: "4"
  limits.memory: 8GiB
  raw.qemu: -audio spice -device ich9-intel-hda -device hda-micro
  volatile.cloud-init.instance-id: c77e9688-e8ce-4b50-9d1b-79b53998732c
  volatile.eth0.host_name: tap7437aeb3
  volatile.eth0.hwaddr: 00:16:3e:42:a1:ae
  volatile.last_state.power: RUNNING
  volatile.last_state.ready: "false"
  volatile.uuid: 49c1e18e-208a-4115-bf58-1fa7e47a3cd0
  volatile.uuid.generation: 49c1e18e-208a-4115-bf58-1fa7e47a3cd0
  volatile.vsock_id: "2399700194"
devices:
  install:
    boot.priority: "10"
    source: /home/mika/work/windows-lxd/win11.lxd.iso
    type: disk
  root:
    path: /
    pool: default
    size: 50GiB
    type: disk
  vtpm:
    path: /dev/tpm0
    type: tpm
ephemeral: false
profiles:
- default
stateful: false
description: ""
1 Like

Hey,

Could you please let us know a bit more about your environment so that we can try to reproduce the issue? What’s the host OS (lsb_release -rc), kernel version (uname -a) and LXD version (snap list lxd)?

Thanks

Hi,

Certainly:

> uname -a
Linux SOLPF4F14Z4 6.5.0-35-generic #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May  7 09:00:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
> lsb_release -rc
Release:	22.04
Codename:	jammy
> snap list lxd
Name  Version         Rev    Tracking       Publisher   Notes
lxd   5.21.1-2d13beb  28463  latest/stable  canonicalâś“  -
> snap connections lxd
Interface       Plug                  Slot             Notes
content         lxd:ceph-conf         -                -
content         lxd:ovn-certificates  -                -
content         lxd:ovn-chassis       -                -
lxd             -                     lxd:lxd          -
lxd-support     lxd:lxd-support       :lxd-support     -
network         lxd:network           :network         -
network-bind    lxd:network-bind      :network-bind    -
system-observe  lxd:system-observe    :system-observe  -

Here is a process tree view of this situation:

In the top spicy the audio works but in spicy forked from lxc process audio does not work.

This is perfectly fine but please know that latest/stable is a moving target so currently is has 5.21 which is an LTS version but when we publish a new feature release (soon), it will have your machine upgrade to a non-LTS.

In other words, please double check that you intend to be on a feature track and not the last LTS one. If you want to switch, now’s a good time, see LXD 5.21.1 LTS has been released for the exact snap refresh command to use.

Now, thanks for providing the version information, I’ll try to replicate the issue here.

1 Like

One way to easily circumvent this issue is to use other spice clients than spicy or virt-viewer e.g. remmina or install them from other source than apt e.g. flathub so that lxd cannot find them.

Then you can just start your favorite spice client manually and use the socket from lxc console command output.

Maybe cli applications like lxd should not open graphical applications because this seems like a permission rabit hole which is not otherwise needed in lxd package.

I have the same problem. After reading this, I realized it has to do with how the viewer process gets spawned.

As a workaround, I use xdg-open with the socket url, and replaced in “/snap/lxd/current/bin/remote-viewer” this line:

exec unshare -U -r chroot "/var/lib/snapd/hostfs/" "${CMD}" "$@"

with this:

    # Use xdg-open instead of launching the viewer in a new ns
    # must have a valid audio device, e.g.:
    # lxc config set VM_NAME raw.qemu -- "-device intel-hda -device hda-duplex -audio spice"
    xdg-open "$@"
    VIEWER=$(echo "/usr/bin/${CMD} $@" | sed 's/\+/\./g' )
    echo "waiting for viewer to close..."
    echo "VIEWER: $VIEWER"
    
    VIEWER_PID=$(pgrep -f "${VIEWER}")
    echo "VIEWER_PID: $VIEWER_PID"
    
    while [ -n "$VIEWER_PID" ]; do
        VIEWER_PID=$(pgrep -f "${VIEWER}")
        sleep 1s
    done
    
    echo "release socket"
    exit 0

To use the modified script, I mount it over the existing one in the lxd snap:
sudo mount --bind ${HOME}/remote-viewer /snap/lxd/current/bin/remote-viewer

With this I have working sound (including mic) in the an ubuntu vm. The vm must have a valid audio device, e.g.:
lxc config set VM_NAME raw.qemu -- "-device intel-hda -device hda-duplex -audio spice"

See also this LXD vga type console login blocks audio devices in host OS · Issue #13402 · canonical/lxd · GitHub where I have attached the complete file remote-viewer .

@sdeziel1 might this be something we could incorporate into the LXD snap remote-viewer wrapper?

That’s an interesting workaround. Thanks for providing it!

I am not a fan of the wait loop but don’t know how to avoid it either :confused:

Was that config bit solely to get your working mic? In other words, was the audio working fine (minus the mic) with just your bind mounted script?

I think it needs some rework, because this has a few issues. When using “xdg-open” there is no knowledge about the PID nor the actual command that is associated with the actual URL pattern. In other words, my workaround only works because I have installed only “remote-viewer”. To give you an example (without testing it): If I would have also installed “spicy”, and made that the default URL handler, my check for the viewer process to get the PID would not work. It would look for “remote-viewer” process because that is the first command which gets tested. But that would have not been invoked by “xdg-open”, and therefore it would immediately close the socket, even though spicy is connected.

If we would get the PID from “xdg-open”, this would be a solid workaround, and would not even depend on the actual viewer. I think “remmina” would also able to handle it with the proper plugin installed. I believe that if no handler is installed, “xdg-open” does not return “SUCCESS”.

What I will try later, is to modify the script to be independent of the viewer command. Basically only checking which process has opened the socket. I believe this should also work.

I will report back with the result.

No. Audio was not working for me at all. That’s why I came up with the idea to look at how the viewer gets spawned.
No. Just bind mounting the original script does not change anything. It will have the same result, that the audio is not working. See the “gst” errors/warnings below when just bind mounting a copy of the original script:

(remote-viewer:967736): IBUS-WARNING **: 10:37:52.955: Unable to connect to ibus: Exhausted all available authentication mechanisms (tried: EXTERNAL) (available: EXTERNAL)

(remote-viewer:967736): GLib-GObject-CRITICAL **: 10:37:53.006: g_object_get_is_valid_property: object class 'GstAutoAudioSink' has no property named 'volume'

(remote-viewer:967736): GLib-GObject-CRITICAL **: 10:37:53.013: g_object_get_is_valid_property: object class 'GstAutoAudioSrc' has no property named 'volume'

(remote-viewer:967736): GSpice-WARNING **: 10:37:53.049: playback: ignoring volume change on audiosink

(remote-viewer:967736): GSpice-WARNING **: 10:37:53.049: playback: ignoring mute change on audiosink

(remote-viewer:967736): GSpice-WARNING **: 10:37:53.061: record: ignoring volume change on audiosrc

(remote-viewer:967736): GSpice-WARNING **: 10:37:53.062: record: ignoring mute change on audiosrc

What I tried initially was to invoke the viewer directly:

    #exec unshare -U -r chroot "/var/lib/snapd/hostfs/" "${CMD}" "$@"
    HFS="/var/lib/snapd/hostfs/"
    export PATH="${HFS}/usr/local/sbin:${HFS}/usr/local/bin:${HFS}/usr/sbin:${HFS}/usr/bin:${HFS}/sbin:${HFS}/bin"
    export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${HFS}/usr/lib:${HFS}/lib:${HFS}/lib/x86_64-linux-gnu:${HFS}/usr/lib/x86_64-linux-gnu"
    exec "${CMD}" "$@"

But I had problems with the runtime linker, probably due to the “snap” confinement

remote-viewer: symbol lookup error: /var/lib/snapd/hostfs/lib/x86_64-linux-gnu/libc.so.6: undefined symbol: __tunable_is_initialized, version GLIBC_PRIVATE

I then tried to LD_PRELOAD the glibc which ultimately resulted in a segfault

LD_PRELOAD=${HFS}/lib64/ld-linux-x86-64.so.2 exec "${CMD}" "$@"

I have to admit, that I am not an expert when it comes to “snap” packages.

I works for remote-viewer, but spicy does not register itself as URL handler for “spice+unix://” so you end up with a popup asking to install an app from the gnome-store.

I modified this

    ...
    xdg-open "$@" || exit 1
    VIEWER=$(echo "/usr.*$@" | sed 's/\+/\./g' )
    ...

and for testing I removed the “find” functionality from this function, because the command does not get used anyway:

find_and_spawn() {
    run_cmd JUST_USE_URL "${1}"
}