From d3c29695ed0fabba6086f9b7537a67b3d3589eec Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 31 Mar 2024 20:52:39 +0800 Subject: [PATCH] units: introduce systemd-hibernate-resume-clear-efi.service that clears stale HibernateLocation EFI variable Currently, if the HibernateLocation EFI variable exists, but we failed to resume from it, the boot carries on without clearing the stale variable. Therefore, the subsequent boots would still be waiting for the device timeout, unless the variable is purged manually. There's no point to keep trying to resume after a successful switch-root, because the hibernation image state would have been invalidated by then. OTOH, we don't want to clear the variable prematurely either, i.e. in initrd, since if the resume device is the same as root one, the boot won't succeed and the user might be able to try resuming again. So, let's introduce a new systemd-hibernate-resume-clear-efi.service unit, that only runs after switch-root. Fixes #32021 --- man/rules/meson.build | 2 +- man/systemd-hibernate-resume.service.xml | 8 +++++++ units/meson.build | 5 ++++ ...temd-hibernate-resume-clear-efi.service.in | 23 +++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 units/systemd-hibernate-resume-clear-efi.service.in diff --git a/man/rules/meson.build b/man/rules/meson.build index e483196c5c5d0..7b89afef9578b 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -944,7 +944,7 @@ manpages = [ ['systemd-hibernate-resume-generator', '8', [], 'ENABLE_HIBERNATE'], ['systemd-hibernate-resume.service', '8', - ['systemd-hibernate-resume'], + ['systemd-hibernate-resume', 'systemd-hibernate-resume-clear-efi.service'], 'ENABLE_HIBERNATE'], ['systemd-homed.service', '8', ['systemd-homed'], 'ENABLE_HOMED'], ['systemd-hostnamed.service', '8', ['systemd-hostnamed'], 'ENABLE_HOSTNAMED'], diff --git a/man/systemd-hibernate-resume.service.xml b/man/systemd-hibernate-resume.service.xml index f6cdefdd3a0fb..c64901461d544 100644 --- a/man/systemd-hibernate-resume.service.xml +++ b/man/systemd-hibernate-resume.service.xml @@ -17,12 +17,14 @@ systemd-hibernate-resume.service + systemd-hibernate-resume-clear-efi.service systemd-hibernate-resume Resume from hibernation systemd-hibernate-resume.service + systemd-hibernate-resume-clear-efi.service /usr/lib/systemd/systemd-hibernate-resume @@ -37,6 +39,12 @@ /sys/power/resume, along with the offset in memory pages (/sys/power/resume_offset) if supported. + The resume device node is either passed directly through arguments, or automatically acquired + from kernel command line options and/or HibernateLocation EFI variable. The latter + will normally be cleared by systemd-hibernate-resume.service on resumption. + If a stale variable is detected, it would be cleared by + systemd-hibernate-resume-clear-efi.service. + Failing to initiate a resume is not an error condition. It may mean that there was no resume image (e. g. if the system has been simply powered off and not hibernated). In such cases, the boot is ordinarily continued. diff --git a/units/meson.build b/units/meson.build index 6fecbea0a1b52..6145d45df8cbc 100644 --- a/units/meson.build +++ b/units/meson.build @@ -316,6 +316,11 @@ units = [ 'file' : 'systemd-hibernate-resume.service.in', 'conditions' : ['ENABLE_HIBERNATE'], }, + { + 'file' : 'systemd-hibernate-resume-clear-efi.service.in', + 'conditions' : ['ENABLE_HIBERNATE', 'ENABLE_EFI'], + 'symlinks' : ['sysinit.target.wants/'], + }, { 'file' : 'systemd-hibernate.service.in', 'conditions' : ['ENABLE_HIBERNATE'], diff --git a/units/systemd-hibernate-resume-clear-efi.service.in b/units/systemd-hibernate-resume-clear-efi.service.in new file mode 100644 index 0000000000000..6db6d39fa9066 --- /dev/null +++ b/units/systemd-hibernate-resume-clear-efi.service.in @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Clear Stale Hibernate EFI Variable +Documentation=man:systemd-hibernate-resume-clear-efi.service(8) + +ConditionPathExists=/sys/firmware/efi/efivars/HibernateLocation-8cf2644b-4b0b-428f-9387-6d876050dc67 +ConditionPathExists=!/etc/initrd-release + +DefaultDependencies=no +Before=sysinit.target shutdown.target +Conflicts=shutdown.target + +[Service] +Type=oneshot +ExecStart={{LIBEXECDIR}}/systemd-hibernate-resume --clear-efi