Skip to content

Instantly share code, notes, and snippets.

@DejfCold
Last active July 22, 2025 21:20
Show Gist options
  • Select an option

  • Save DejfCold/4fab61cbca742c7393e11a6cde88fb7f to your computer and use it in GitHub Desktop.

Select an option

Save DejfCold/4fab61cbca742c7393e11a6cde88fb7f to your computer and use it in GitHub Desktop.
Fixes nvidia not switching to previously active VT after waking up from hibernation from suspend-then-hibernate. The original `/usr/lib/systemd/system-sleep/nvidia` claims it should be handled by systemd nvidia-resume.service which in my case, never runs.
#!/usr/bin/sh
# Fixes nvidia not switching to previously active VT after waking up from hibernation from suspend-then-hibernate.
# Original /usr/lib/systemd/system-sleep/nvidia claims it should be handled by systemd nvidia-resume.service which in my case, never runs.
#
# Requires already setup hibernation and suspend functionality using nvidia official drivers.
# Tested with Fedora 42, nvidia driver 575.64.03 (from RPM Fusion - https://rpmfusion.org/Howto/NVIDIA) and nvidia T500 GPU
# Place this script in /usr/lib/systemd/system-sleep/ and chmod +x
#
# The event order of failed hibernation isn't specified
# and neither whether suspend-after-failed-hibernate and post:hibernate are mutually exclusive,
# so we'll use 2 approaches to handle this:
# 1) create a failure flag and then detect it if pre:suspend-after-failed-hibernate runs before post:hibernate
# 2) resume and suspend again if post:hibernate runs before pre:suspend-after-failed-hibernate
# This will always properly resume if there's no failure
# If there is a failure the GPU won't go to sleep in an active VT.
FLAG="/run/nvidia_failed_hibernate_flag"
if [ "${2}" = "suspend-then-hibernate" ] && [ -f "/proc/driver/nvidia/suspend" ]; then
case "${1}:${SYSTEMD_SLEEP_ACTION}" in
pre:suspend-after-failed-hibernate)
# If a hibernation fails, we'll create a failure flag file, so other stages can know about it.
# That's in case pre:hibernate runs after this step.
touch "${FLAG}"
# If VT is not set to the nvidia idle VT, we'll run full nvidia suspend,
# otherwise we do nothing, and we'll let /usr/lib/systemd/system-sleep/nvidia handle this case.
# That's in case post:hibernate runs before this step when failure flag did not exist yet.
if [ "$(fgconsole)" != "63" ]; then
# something (post:hibernate) must have recently changed VT, so let's wait a little
sleep 4
/usr/bin/nvidia-sleep.sh "suspend"
fi
;;
pre:hibernate)
# we started a new cycle - failure couldn't have happened yet, so we'll remove the flag
rm -f "${FLAG}"
;;
post:hibernate)
# If a failure doesn't happen, the flag won't exist, so we resume.
# If pre:suspend-after-failed-hibernate ran earlier, we won't resume.
# If pre:suspend-after-failed-hibernate will run after, we will resume now, and then suspend again in pre:suspend-after-failed-hibernate
if [ ! -f "${FLAG}" ]; then
/usr/bin/nvidia-sleep.sh "resume"
fi
;;
esac
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment