Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing DISPLAY environment variable in systemd user service after first start #45

Open
OlliC opened this issue May 2, 2018 · 12 comments
Labels
bug Something isn't working

Comments

@OlliC
Copy link
Contributor

OlliC commented May 2, 2018

Hi,

i have started using the new custom user script functionality to put my Nvidia GPU into performance mode. I am using this config for that:

[custom]
; Custom scripts (executed using the shell) when gamemode starts and ends
start=notify-send "GameMode started"
    nvidia-settings -a '[gpu:0]/GPUPowerMizerMode=1'

end=notify-send "GameMode ended"
    nvidia-settings -a '[gpu:0]/GPUPowerMizerMode=0'

The problem with this is sometimes nvidia-settings fails to run because it needs the DISPLAY enviroment variable (+ XAUTHORITY probably), which is missing when the service first gets started.

I can see with systemctl --user show-environment that the variables are there. But when i look at the actual environment from the gamemoded process with tr '\0' '\n' < /proc/<pid>/environ they are missing. But after a service restart the variables are there. I suspect the problem is that the service is run too early before the X server had time to execute /etc/X11/xinit/xinitrc.d/50-systemd-user.sh (See [1]) which source these variables into systemds user daemon.

By using a small delay with ExecStartPre=/usr/bin/sleep 5 the problem is gone, but there must be a better solution to this. I have this problem on Fedora and Arch Linux so it probably affects all distros.

[1] https://wiki.archlinux.org/index.php/Systemd/User#DISPLAY_and_XAUTHORITY

@mdiluz mdiluz added the bug Something isn't working label May 2, 2018
@mdiluz
Copy link
Contributor

mdiluz commented May 2, 2018

Cheers @OlliC this is a good report.

So from what I'm aware it's complicated to get this right, see: this superuser post for discussions. Would be open to suggestions about clean ways, as it's unfortunate you can't just specify Wants=xorg.service!

@OlliC
Copy link
Contributor Author

OlliC commented May 3, 2018

My current workaround is to restart the service with Gnomes autostart feature with this desktop file:

$ cat .local/share/applications/gamemoded-restart.desktop 
[Desktop Entry]
Name=Restart gamemoded user service
Exec=systemctl --user try-restart gamemoded.service
Type=Application
Terminal=false

This works quite well and is probably better than sleep for 5 seconds, because the time to startup the desktop environment could vary. The real solution is probably to use graphical-session.target, but that only works when the desktop environments start using systemd to bring it up, which is a work in progress as it seems.

@mdiluz
Copy link
Contributor

mdiluz commented May 9, 2018

To be honest, you could just disable the service with systemctl entirely and only initialize it with gnome like that. A Meson option could probably be constructed to do that automatically.

mdiluz pushed a commit that referenced this issue May 16, 2018
As seen in Issue #45 (thanks OlliC)

This can be placed in ~/.local/share/applications/ to allow easier (re)launching of gamemode, in particular when the DISPLAY param is needed
@kakra
Copy link
Contributor

kakra commented May 27, 2018

The problem is how some distributions start the systemd bus... It should not be started by the Xorg script. I think it should be included in PAM. In Gentoo there's -session optional pam_systemd.so in /etc/pam.d/system-auth. According to man pam_systemd this would start the user session bus. User services will then see all variables the user login sees.

The Xorg script is only there to import environment:

#!/bin/sh

systemctl --user import-environment DISPLAY XAUTHORITY

if command -v dbus-update-activation-environment >/dev/null 2>&1; then
        dbus-update-activation-environment DISPLAY XAUTHORITY
fi

So it may be sufficient to start a process in Gnome to import the environment.

@kakra
Copy link
Contributor

kakra commented Oct 2, 2018

One other note: Can't we just make the service dbus activatable instead of autostarting with the session? Systemd has support for this. I could come up with a PR for this...

@kakra
Copy link
Contributor

kakra commented Oct 4, 2018

I think the underlying problem is completely different and should not be solved by injecting the DISPLAY variable into the gamemoded process. The DISPLAY variable is coupled to the game executed, not the session gamemoded is started in.

To properly solve this, we need to extract the environment of the game and inject it into the scripts started by gamemoded.

I've queued patches in my PRs which would make this easy. If they are merged, I'd work on a PR to solve this. Injecting the proper environment into the scripts would probably also solve some other problems which may arise.

@aejsmith
Copy link
Contributor

aejsmith commented Oct 8, 2018

One other note: Can't we just make the service dbus activatable instead of autostarting with the session? Systemd has support for this. I could come up with a PR for this...

This has already been done by commit 432a21f. I think existing installs will need to do systemctl --user disable gamemoded to disable the autostart, and then it'll be activated as needed.

@kakra
Copy link
Contributor

kakra commented Oct 8, 2018

We should still present the environment that the game is seeing to scripts, and not what the daemon is seeing, right? Since you merged the wine PR which contains a function to access the environment, I could start working on such a solution and close some open issues here while on the way. It's not really complicated to do now, actually it's really easy now.

@aejsmith
Copy link
Contributor

aejsmith commented Oct 9, 2018

Yeah, certainly I think DISPLAY should match what the game has.

@kakra
Copy link
Contributor

kakra commented Oct 9, 2018

Could you merge my cleanup PR first? Given it's fine for you...

afayaz-feral pushed a commit that referenced this issue May 26, 2020
As seen in Issue #45 (thanks OlliC)

This can be placed in ~/.local/share/applications/ to allow easier (re)launching of gamemode, in particular when the DISPLAY param is needed
@zany130
Copy link

zany130 commented Aug 17, 2021

I think I'm getting this issue on garuda Linux. I made a form post here https://forum.garudalinux.org/t/gamemode-not-working-with-steam the strange thing is i don't get this issue in vanilla arch. Should mention restating the service does not help in my case

@cheyngoodman
Copy link

I'm experiencing this issue on Wayland using SwayWM. The start / end scripts are helpful to work around SwayWM issues High refresh rate flickering #7087 and Variable refresh rate flickering #5076.

# ~/.config/gamemode.ini
[custom]
start=gamemode-script start
end=gamemode-script end
#!/bin/bash
# gamemode-script
case "$1" in
  'start') swaymsg "output * adaptive_sync on" && swaymsg "output * mode 2560x1440@143.972Hz" ;;
  'end')   swaymsg "output * adaptive_sync off" && swaymsg "output * mode 2560x1440@59.951Hz" ;;
  *) echo 'Requires start or end as a parameter'
esac

Adding this line to my sway config resolved the issue: exec --no-startup-id systemctl try-restart gamemoded.service --user

Thank you for that workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants