Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 822498 - media-video/pipewire: No sound, wireplumber fails to start when launching gentoo-pipewire-launcher
Summary: media-video/pipewire: No sound, wireplumber fails to start when launching gen...
Status: CONFIRMED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: AMD64 Linux
: Normal normal (vote)
Assignee: Sam James
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-11-09 01:00 UTC by Boris Carvajal
Modified: 2024-01-02 01:20 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Boris Carvajal 2021-11-09 01:00:23 UTC
My .xinitrc runs gentoo-pipewire-launcher at system start but wireplumber fails to connect to pipewire printing "Failed to connect to PipeWire" and stoping.

It seems wireplumber can be executed before pipewire is ready because of the way the script is coded.

gentoo-pipewire-launcher:
#!/bin/sh
/usr/bin/pipewire &
/usr/bin/pipewire -c pipewire-pulse.conf &
exec /usr/bin/wireplumber

A simple fix is putting a 'wait' command before starting wireplumber to be sure that pipewire has fully started.

Reproducible: Always
Comment 1 Small_Penguin 2021-11-10 12:23:00 UTC
I can confirm this. Adding sleep 2 after launching the pipewire core daemon helps, otherwise everything trying to start playback hard-locks.
Comment 2 Small_Penguin 2021-11-10 12:25:46 UTC
Actually not true. I still had my pre-0.3.39 configuration in /etc/pipewire. After commenting out the context.exec entries in /etc/pipewire/pipewire.conf, everything seems to work fine, or I have been lucky on the second attempt.
Comment 3 Niklāvs Koļesņikovs 2021-11-10 12:39:02 UTC
Could the original filer please report back, too (regarding having stale configuration)? In my limited testing I did not observe any issues when not using any delay between daemon startup, which is why it's not there right now.
Comment 4 Boris Carvajal 2021-11-11 01:13:17 UTC
I don't have a '/etc/pipewire/' directory.

Small_Penguin: If I try 'gentoo-pipewire-launcher' a second time after the failed attempt on system startup, it works, but it could be because the binaries are already cached so they run almost instantly.

I've checked the systemd unit file of wireplumber and it has both "After=pipewire.service" and "BindsTo=pipewire.service", these directives, specially 'After=', instruct wireplumber to run only after pipewire service is fully started.

That guarantee is not in 'gentoo-pipewire-launcher'.

I recommend to run the three commands straight without '&', the second command 'pipewire -c pipewire-pulse.conf' does wait for 'pipewire' though, but it seems there is some polling time, so in fact running it in parallel could be slower.
Comment 5 Niklāvs Koļesņikovs 2021-11-11 09:36:04 UTC
There is no such thing as guaranteed daemon startup order without systemd (especially for user services), therefore I'm not aware of any way to implement After= condition for OpenRC. ;)

My understanding is that pipewire -c pipewire-pulse.conf (a.k.a. pipewire-pulse) has long been fixed to reliably deal with getting started before the main pipewire -c pipewire.conf process, so startup order should not be a problem. I'm not sure how well WirePlumber can deal with getting initialized before PipeWire.

Regarding not using & from what I knew both then and now the daemons remain running in the foreground, so once pipewire starts, it will not move on to starting the 2nd daemon until the first has exited.

We could add a delay before starting WirePlumber but if it's only affecting one person, I'm a bit unsure if using a large value would be a good idea, and I doubt that just 1 second sleep will be reliable enough (and has it even been verified to help?).

It may be worth to do `ps aux | grep -Ei wire\|pulse` before and after running the the launcher to see in what state is the system before and after running it

Another thing to explore would be adding, say, sleep 1 after the pkill command since if there's already running daemons, they may not have managed to exit before pipewire & attempts to initialize.

On that note, what software is being started via .xinitrc? Might it be an XDG compliant desktop environment such as Xfce4 which would try to run the launcher a second time thanks to the XDG autostart?
Comment 6 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2021-11-11 22:10:03 UTC
Forgot to tag bug (sorry, I'd planned on), but this is fixed in 0.3.40 / 9999 with a sleep 1 as a hack for now.
Comment 7 Enne Eziarc 2021-11-12 03:45:17 UTC
I worked around it by copying the default pipewire.conf to ~/ and replacing/uncommenting mentions of pw-media-session with wireplumber. None of these workarounds are all that great though; I think it's on upstream to ship a default config and set of daemons that isn't broken out of the box.
Comment 8 Boris Carvajal 2021-11-12 04:11:40 UTC
Niklāvs Koļesņikovs:

> Regarding not using & from what I knew both then and now the daemons remain
> running in the foreground, so once pipewire starts, it will not move on to
> starting the 2nd daemon until the first has exited.

Oh yeah I forgot that when writting.

> We could add a delay before starting WirePlumber but if it's only affecting one
> person

I suppose very few people are testing pipewire plus 'gentoo-pipewire-launcher' script.

> I'm a bit unsure if using a large value would be a good idea, and I doubt that just 1
> second sleep will be reliable enough (and has it even been verified to help?).

It helps. But ideally wireplumber should implement this, I saw you in its GitLab repo
maybe a feature request could pay off.

> On that note, what software is being started via .xinitrc? Might it be an XDG
> compliant desktop environment such as Xfce4 which would try to run the launcher
> a second time thanks to the XDG autostart?

I'm using AwesomeWM so no XDG autostart files.


Sam James:

> Forgot to tag bug (sorry, I'd planned on), but this is fixed in 0.3.40 / 9999
> with a sleep 1 as a hack for now.

Ugly but it works. Thanks.


Enne Eziarc:

> I worked around it by copying the default pipewire.conf to ~/ and
> replacing/uncommenting mentions of pw-media-session with wireplumber.

That seems the most elegant solution.
Comment 9 Niklāvs Koļesņikovs 2021-11-12 16:56:59 UTC
There's three reasons we moved away from using the pipewire.conf method:
1. it's deprecated by upstream and meant only for the purpose of running tests and other specialized deployments
2. unlike some other custom patches we apply, that one had proven itself to require above average amount of maintenance, since it's at the end of the main configuration file and recurrently becomes unrecognizable to patch utility
3. no one really likes conditional patching in ebuilds (since it should not be applied to systemd user systems).

Regarding WirePlumber, the primary use case of systemd works reliably (ignoring the previously hidden Gentoo issues that WirePlumber uncovered in other components), so I doubt non-systemd is high on their agenda. I'm not sure what the upstream stance on non-systemd reliability is - a simple sleep patch is unlikely to be accepted upstream (IMO). While built-in wait loop for PipeWire to initialize may raise concerns about handling of failure modes where something has gone wrong and it will never show up (after all, systemd ensures that dependent units are started when the dependency is ready or that they will fail, too). And I'm not sure if upstream will be happy about re-implementing part of systemd core features inside WirePlumber either.

It may be more acceptable on our part for someone interested to improve the launcher script to do a wait on the PipeWire socket before starting pipewire-pulse and wireplumber (while ensuring that it
* does not loop forever
* cleans up if the socket does not show up or pipewire daemon fails to initialize and maybe tries a second time
* preferably can also predict where the socket will show up based on environment variables set
* gracefully exit with error message if D-Bus is missing, instructing user on how to fix the issue
* etc
* ideally written in POSIX Shell while being highly reliable and predictable (since C would be a tall order to accept and probably even PMS approved Bash 4.3 might be a stretch for a launcher)

If this sounds like a silly amount of work to badly and only partially re-implement what is already there, then you already know why we are using systemd instead (and also why we went with sleep 1 instead). ;)
Comment 10 Michael Perlov 2022-09-28 21:46:32 UTC
Also, /usr/bin/gentoo-pipewire-launcher kills all daemons at every execution, which is annoying, because every time AwesomeWM being restarted, youtube video/music stops playing.

Currently I use following script instead:

###
if ! pgrep -U "$USER" -f /usr/libexec/xdg-desktop-portal &>/dev/null; then
    if [[ -x /usr/libexec/xdg-desktop-portal ]]; then
        /usr/libexec/xdg-desktop-portal &
        sleep 1
    fi
fi

# The core daemon which by itself does probably nothing.
if ! pgrep -U "$USER" -x pipewire &>/dev/null; then
    /usr/bin/pipewire &
    /usr/bin/pipewire -c pipewire-pulse.conf &
    # Hack for bug #822498
    sleep 1
fi

# Finally a session manager is required for PipeWire to do anything.
if ! pgrep -U "$USER" -x wireplumber &>/dev/null; then
    exec /usr/bin/wireplumber
fi
###
Comment 11 Mantas M. 2022-11-09 13:15:44 UTC
(In reply to Niklāvs Koļesņikovs from comment #9) 
> Regarding WirePlumber, the primary use case of systemd works reliably
> (ignoring the previously hidden Gentoo issues that WirePlumber uncovered in
> other components), so I doubt non-systemd is high on their agenda. I'm not
> sure what the upstream stance on non-systemd reliability is - a simple sleep
> patch is unlikely to be accepted upstream (IMO). While built-in wait loop
> for PipeWire to initialize may raise concerns about handling of failure
> modes where something has gone wrong and it will never show up (after all,
> systemd ensures that dependent units are started when the dependency is
> ready or that they will fail, too).

It's not only that systemd ensures reliability – its trick is to establish the PipeWire socket before actually starting PipeWire (or any other user services), so that even if WirePlumber starts earlier, it is already able to connect() to that socket without issues. (The connect call will block until PipeWire is ready to accept().)

The socket handover can be implemented without requiring systemd (although, unfortunately, not in Bash nor POSIX sh) -- for example, I wrote this a few minutes ago for someone on IRC: https://git.nullroute.lt/cgit/hacks/sd-activate.git/tree/

$ ./sd-activate --listen=$XDG_RUNTIME_DIR/pipewire-0 --keepenv --fork pipewire

The socket is then ready while PipeWire is still initializing, without timers. This mostly mimics what pipewire.socket does in systemd, though it has the same failure handling as "pipewire &" in the current launcher (i.e. none whatsoever).
Comment 12 Alexander Weber 2023-11-03 09:00:03 UTC
I got this issue on my old slow device. The 1 second wait before starting wireplumber is not enough. I changed it to 3 and now the audio does launch right on boot.
Pls. add an parameter to the script with default 1, so it is possible to change the value in .config/gentoo-pipewire-launcher.conf
Comment 13 Mart Raudsepp gentoo-dev 2023-11-03 09:30:11 UTC
Hopefully we wouldn't need a parameter that would be fixing things out of the box. If not a socket handover, maybe the startup script could monitor for the presence of the needed socket being there already or not, check occasionally (every 100ms?) up to 5 seconds or so, as to still start fast, but not fail wen it's on a slower machine?
Comment 14 Esteve Varela Colominas 2024-01-02 01:20:33 UTC
After years of using "sleep 1", I've decided to revisit this. I'm "solving" it by essentially busylooping until the socket shows up[1]. The only thing is that I also had a problem with knowing when "wireplumber" *itself* is ready, as programs like polybar would not show the volume applet if it isn't. I'm solving this by busylooping the "amixer get Master" command.
Both of these loops run in parallel, and have a timeout, after which they just give up and leave the environment half-setup. This practically never happens, but I also can't really think of a good failure mode that wouldn't invole restarting the environment anyway. I'm using KillUserProcesses=yes in elogind.

Looking around at what other distributions do, an interesting proposition is what slackware does[2], which uses a program called daemon[3] that essentially re-runs the pipewire-related daemons if they crash, and allows them to exit once the elogind session is over with "--bind".

I've yet to look at other systemd-free distributions, but I fear most of them either still use pulseaudio by default or nab the current script from gentoo as-is. I think it's due time to fix this situation.

Ideally there'd be an upstream program, akin to "start-pulseaudio-x11", that forks the necessary daemons and only exits when they're completely up and running.

If upstream has no interest, we can always expand the gentoo-pipewire-launcher to do this, though I think Niklāvs' list of requirements is *very* imposing and anything would be preferable to get rid of "sleep 1". For example, I have no idea why "cleaning up" is any useful, when it doesn't make the resulting environment any less broken, and the script will rerun everything when it's executed again. And why posix shell is a requirement when we already have a history of small C programs in the tree (app-text/manpager), and failing that, distfiles could always be used, so any other language like Python is fair game as well. You don't need to do everything systemd does to get acceptable behavior, in this case. Keep it simple.

I think Mantas' solution has promise as well, and might be worth exploring instead of proposed busyloops (anything involving kernel-side locks is better :), though it doesn't deal with knowing when programs like "volumeicon" won't crash directly on startup.

Does anyone have any other examples? Has there been any form of discussion regarding this with upstream? 

[1]: https://github.com/mid-kid/config/blob/20642c62a5063fe7f8c496f7553a8e42c1bed0fc/i3/.config/i3/autostart#L7-L14
[2]: https://www.linuxquestions.org/questions/slackware-14/using-pipewire-instead-of-pulseaudio-in-slackware-15-a-4175693980/
[3]: https://github.com/raforg/daemon/