if (r < 0)
return r;
if (entries.n_swaps == 0)
- return log_debug_errno(SYNTHETIC_ERRNO(ENOENT), "No swap space available for hibernation.");
+ return log_debug_errno(SYNTHETIC_ERRNO(ENOSPC), "No swap space available for hibernation.");
FOREACH_ARRAY(swap, entries.swaps, entries.n_swaps) {
r = swap_entry_get_resume_config(swap);
if (!entry) {
/* No need to check n_swaps == 0, since it's rejected early */
assert(resume_config_devno > 0);
- return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Cannot find swap entry corresponding to /sys/power/resume.");
+ return log_debug_errno(SYNTHETIC_ERRNO(ENOSPC), "Cannot find swap entry corresponding to /sys/power/resume.");
}
if (ret_device)
int hibernation_is_safe(void) {
unsigned long long active;
uint64_t size, used;
- bool resume_set;
+ bool resume_set, bypass_space_check;
int r;
+ bypass_space_check = getenv_bool("SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK") > 0;
+
r = find_suitable_hibernation_device_full(NULL, &size, &used);
+ if (r == -ENOSPC && bypass_space_check)
+ /* If we don't have any available swap space at all, and SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK
+ * is set, skip all remaining checks since we can't do that properly anyway. It is quite
+ * possible that the user is using a setup similar to #30083. When we actually perform
+ * hibernation in sleep.c we'll check everything again. */
+ return 0;
if (r < 0)
return r;
resume_set = r > 0;
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Not running on EFI and resume= is not set. Hibernation is not safe.");
- if (getenv_bool("SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK") > 0)
+ if (bypass_space_check)
return true;
r = get_proc_meminfo_active(&active);