Skip to content

Commit

Permalink
units: introduce systemd-hibernate-resume-clear-efi.service
Browse files Browse the repository at this point in the history
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
  • Loading branch information
YHNdnzj committed Apr 2, 2024
1 parent 89a93cf commit d3c2969
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion man/rules/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand Down
8 changes: 8 additions & 0 deletions man/systemd-hibernate-resume.service.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

<refnamediv>
<refname>systemd-hibernate-resume.service</refname>
<refname>systemd-hibernate-resume-clear-efi.service</refname>
<refname>systemd-hibernate-resume</refname>
<refpurpose>Resume from hibernation</refpurpose>
</refnamediv>

<refsynopsisdiv>
<para><filename>systemd-hibernate-resume.service</filename></para>
<para><filename>systemd-hibernate-resume-clear-efi.service</filename></para>
<para><filename>/usr/lib/systemd/systemd-hibernate-resume</filename></para>
</refsynopsisdiv>

Expand All @@ -37,6 +39,12 @@
<filename>/sys/power/resume</filename>, along with the offset in memory pages
(<filename>/sys/power/resume_offset</filename>) if supported.</para>

<para>The resume device node is either passed directly through arguments, or automatically acquired
from kernel command line options and/or <varname>HibernateLocation</varname> EFI variable. The latter
will normally be cleared by <filename>systemd-hibernate-resume.service</filename> on resumption.
If a stale variable is detected, it would be cleared by
<filename>systemd-hibernate-resume-clear-efi.service</filename>.</para>

<para>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.</para>
Expand Down
5 changes: 5 additions & 0 deletions units/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand Down
23 changes: 23 additions & 0 deletions units/systemd-hibernate-resume-clear-efi.service.in
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit d3c2969

Please sign in to comment.