This reverts 5fdf2d51c2, except for one improved
log message.

Fixes #10613.

Checking if resume= is configured is a good idea, but it turns out we cannot do
it reliably:
- the code only supported boot options with sd-boot, and it's not very widely
  used. This means that for most systemd we could only check the current
  commandline, not the next one.
- Various systems resume without, e.g. Debian has
  /etc/initramfs-tools/conf.d/resume in the initramfs.

Making those checks better would be possible with enough effort, but there'll
be always new systems that boot in a slightly different way and we would need
to keep adding new cases. Longer term, we want to rely on autodetecting the
resume partition, and then checks like this will not be necessary at all. It is
quite clear from the number of bug reports that the number of poeple impacted
by this is quite high now, so let's just drop this.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2018-11-21 10:21:28 +01:00 committed by Lennart Poettering
parent 053254e3cb
commit 6d176522f5
2 changed files with 1 additions and 92 deletions

View File

@ -1779,8 +1779,6 @@ static int method_do_shutdown_or_sleep(
return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Not enough swap space for hibernation");
if (r == -ENOMEDIUM)
return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Kernel image has been removed, can't hibernate");
if (r == -EADV)
return sd_bus_error_set(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Resume not configured, can't hibernate");
if (r == 0)
return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb \"%s\" not supported", sleep_verb);
if (r < 0)
@ -2209,7 +2207,7 @@ static int method_can_shutdown_or_sleep(
if (sleep_verb) {
r = can_sleep(sleep_verb);
if (IN_SET(r, 0, -ENOSPC, -ENOMEDIUM, -EADV))
if (IN_SET(r, 0, -ENOSPC, -ENOMEDIUM))
return sd_bus_reply_method_return(message, "s", "na");
if (r < 0)
return r;

View File

@ -16,7 +16,6 @@
#include "sd-id128.h"
#include "alloc-util.h"
#include "bootspec.h"
#include "conf-parser.h"
#include "def.h"
#include "env-util.h"
@ -26,7 +25,6 @@
#include "macro.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
#include "sleep-config.h"
#include "string-util.h"
#include "strv.h"
@ -294,88 +292,6 @@ static bool enough_swap_for_hibernation(void) {
return r;
}
static int check_resume_keys(const char *key, const char *value, void *data) {
assert_se(key);
assert_se(data);
int *resume = data;
if (*resume == 0)
/* Exit if we already know we can't resume. */
return 0;
if (streq(key, "noresume")) {
log_debug("Found \"noresume\" on the kernel command line, hibernation is disabled.");
*resume = 0;
} else if (streq(key, "resume")) {
log_debug("Found resume= option on the kernel command line, hibernation is possible.");
*resume = 1;
}
return 0;
}
static int resume_configured_in_options(const char *options) {
int resume = -1, r;
/* We don't use PROC_CMDLINE_STRIP_RD_PREFIX here, so rd.resume is *not* supported. */
r = proc_cmdline_parse_given(options, check_resume_keys, &resume, 0);
if (r < 0)
return r;
if (resume < 0)
log_debug("Couldn't find resume= option, hibernation is disabled.");
return resume > 0;
}
static int resume_configured(void) {
_cleanup_(boot_config_free) BootConfig config = {};
const BootEntry *e;
int r;
/* Check whether a valid resume= option is present. If possible, we query the boot options
* for the default kernel. If the system is not using sd-boot, fall back to checking the
* current kernel command line. This is not perfect, but should suffice for most cases. */
r = find_default_boot_entry(NULL, NULL, &config, &e);
if (r == -ENOKEY)
log_debug_errno(r, "Cannot find the ESP partition mount point, falling back to other checks.");
else if (r < 0)
return log_debug_errno(r, "Cannot read boot configuration from ESP, assuming hibernation is not possible.");
else {
_cleanup_free_ char *options = NULL;
options = strv_join(e->options, " ");
if (!options)
return log_oom();
r = resume_configured_in_options(options);
if (r < 0)
return log_error_errno(r, "Failed to parse kernel options in \"%s\": %m",
strnull(e->path));
return r;
}
/* If we can't figure out the default boot entry, let's fall back to current kernel cmdline */
_cleanup_free_ char *line = NULL;
r = proc_cmdline(&line);
if (IN_SET(r, -EPERM, -EACCES, -ENOENT))
log_debug_errno(r, "Cannot access /proc/cmdline: %m");
else if (r < 0)
return log_error_errno(r, "Failed to query /proc/cmdline: %m");
else {
r = resume_configured_in_options(line);
if (r < 0)
return log_error_errno(r, "Failed to parse kernel proc cmdline: %m");
return r;
}
log_debug("Couldn't detect any resume mechanism, hibernation is disabled.");
return false;
}
static int kernel_exists(void) {
struct utsname u;
sd_id128_t m;
@ -585,11 +501,6 @@ static int can_sleep_internal(const char *verb, bool check_allowed) {
if (!enough_swap_for_hibernation())
return -ENOSPC;
r = resume_configured();
if (r <= 0)
/* We squash all errors (e.g. EPERM) into a single value for reporting. */
return -EADV;
return true;
}