1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-08 08:58:27 +03:00

gpt-auto: take timeout opts in rootflags= into account; hibernate-resume: always respect user-defined timeout (#35518)

This commit is contained in:
Luca Boccassi 2024-12-12 11:01:40 +00:00 committed by GitHub
commit 184ce19841
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 136 additions and 129 deletions

View File

@ -518,7 +518,7 @@ static int create_disk(
"After=modprobe@loop.service\n",
u_escaped);
r = generator_write_timeouts(arg_dest, device, name, options, &filtered);
r = generator_write_device_timeout(arg_dest, device, options, &filtered);
if (r < 0)
log_warning_errno(r, "Failed to write device timeout drop-in: %m");

View File

@ -289,7 +289,7 @@ static int add_swap(
return log_error_errno(r, "Failed to write unit file %s: %m", name);
/* use what as where, to have a nicer error message */
r = generator_write_timeouts(arg_dest, what, what, options, NULL);
r = generator_write_device_timeout(arg_dest, what, options, NULL);
if (r < 0)
return r;
@ -325,47 +325,9 @@ static bool mount_in_initrd(const char *where, const char *options, bool accept_
(where && PATH_IN_SET(where, "/usr", accept_root ? "/" : NULL));
}
static int write_timeout(
FILE *f,
const char *where,
const char *opts,
const char *filter,
const char *unit_setting) {
_cleanup_free_ char *timeout = NULL;
usec_t u;
int r;
assert(f);
assert(where);
assert(filter);
assert(unit_setting);
r = fstab_filter_options(opts, filter, NULL, &timeout, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to parse options for '%s': %m", where);
if (r == 0)
return 0;
r = parse_sec_fix_0(timeout, &u);
if (r < 0) {
log_warning_errno(r, "Failed to parse timeout '%s' for '%s', ignoring: %m", timeout, where);
return 0;
}
fprintf(f, "%s=%s\n", unit_setting, FORMAT_TIMESPAN(u, 0));
return 0;
}
static int write_idle_timeout(FILE *f, const char *where, const char *opts) {
return write_timeout(f, where, opts,
"x-systemd.idle-timeout\0", "TimeoutIdleSec");
}
static int write_mount_timeout(FILE *f, const char *where, const char *opts) {
return write_timeout(f, where, opts,
"x-systemd.mount-timeout\0", "TimeoutSec");
return generator_write_unit_timeout(f, where, opts,
"x-systemd.idle-timeout\0", "TimeoutIdleSec");
}
static int write_dependency(
@ -670,11 +632,11 @@ static int add_mount(
fprintf(f, "Type=%s\n", t);
}
r = generator_write_timeouts(dest, what, where, opts, &filtered);
r = generator_write_device_timeout(dest, what, opts, &filtered);
if (r < 0)
return r;
r = generator_write_device_deps(dest, what, where, opts);
r = generator_write_network_device_deps(dest, what, where, opts);
if (r < 0)
return r;
@ -684,7 +646,7 @@ static int add_mount(
return r;
}
r = write_mount_timeout(f, where, opts);
r = generator_write_mount_timeout(f, where, opts);
if (r < 0)
return r;

View File

@ -51,9 +51,12 @@ STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
STATIC_DESTRUCTOR_REGISTER(arg_root_fstype, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root_options, freep);
#define LOADER_PARTITION_IDLE_USEC (120 * USEC_PER_SEC)
static int add_cryptsetup(
const char *id,
const char *what,
const char *mount_opts,
bool rw,
bool require,
bool measure,
@ -126,6 +129,10 @@ static int add_cryptsetup(
if (r < 0)
return log_error_errno(r, "Failed to write file %s: %m", n);
r = generator_write_device_timeout(arg_dest, what, mount_opts, /* filtered = */ NULL);
if (r < 0)
return r;
r = generator_add_symlink(arg_dest, d, "wants", n);
if (r < 0)
return r;
@ -178,7 +185,7 @@ static int add_mount(
const char *description,
const char *post) {
_cleanup_free_ char *unit = NULL, *crypto_what = NULL;
_cleanup_free_ char *unit = NULL, *crypto_what = NULL, *opts_filtered = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
@ -194,7 +201,9 @@ static int add_mount(
log_debug("Adding %s: %s fstype=%s", where, what, fstype ?: "(any)");
if (streq_ptr(fstype, "crypto_LUKS")) {
r = add_cryptsetup(id, what, rw, /* require= */ true, measure, &crypto_what);
/* Mount options passed are determined by partition_pick_mount_options(), whose result
* is known to not contain timeout options. */
r = add_cryptsetup(id, what, /* mount_opts = */ NULL, rw, /* require= */ true, measure, &crypto_what);
if (r < 0)
return r;
@ -211,6 +220,10 @@ static int add_mount(
fstype, where);
}
r = generator_write_device_timeout(arg_dest, what, options, &opts_filtered);
if (r < 0)
return r;
r = unit_name_from_path(where, ".mount", &unit);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@ -246,8 +259,12 @@ static int add_mount(
if (fstype)
fprintf(f, "Type=%s\n", fstype);
if (options)
fprintf(f, "Options=%s\n", options);
if (opts_filtered)
fprintf(f, "Options=%s\n", opts_filtered);
r = generator_write_mount_timeout(f, where, opts_filtered);
if (r < 0)
return r;
r = fflush_and_check(f);
if (r < 0)
@ -366,7 +383,7 @@ static int add_partition_swap(DissectedPartition *p) {
}
if (streq_ptr(p->fstype, "crypto_LUKS")) {
r = add_cryptsetup("swap", p->node, /* rw= */ true, /* require= */ true, /* measure= */ false, &crypto_what);
r = add_cryptsetup("swap", p->node, /* mount_opts = */ NULL, /* rw= */ true, /* require= */ true, /* measure= */ false, &crypto_what);
if (r < 0)
return r;
what = crypto_what;
@ -499,7 +516,7 @@ static int add_partition_xbootldr(DissectedPartition *p) {
/* growfs= */ false,
options,
"Boot Loader Partition",
120 * USEC_PER_SEC);
LOADER_PARTITION_IDLE_USEC);
}
#if ENABLE_EFI
@ -566,7 +583,7 @@ static int add_partition_esp(DissectedPartition *p, bool has_xbootldr) {
/* growfs= */ false,
options,
"EFI System Partition Automount",
120 * USEC_PER_SEC);
LOADER_PARTITION_IDLE_USEC);
}
#else
static int add_partition_esp(DissectedPartition *p, bool has_xbootldr) {
@ -644,7 +661,7 @@ static int add_root_cryptsetup(void) {
/* If a device /dev/gpt-auto-root-luks appears, then make it pull in systemd-cryptsetup-root.service, which
* sets it up, and causes /dev/gpt-auto-root to appear which is all we are looking for. */
return add_cryptsetup("root", "/dev/gpt-auto-root-luks", /* rw= */ true, /* require= */ false, /* measure= */ true, NULL);
return add_cryptsetup("root", "/dev/gpt-auto-root-luks", arg_root_options, /* rw= */ true, /* require= */ false, /* measure= */ true, NULL);
#else
return 0;
#endif

View File

@ -64,24 +64,21 @@ static int process_resume(const HibernateInfo *info) {
if (r < 0)
return log_error_errno(r, "Failed to generate device unit name from path '%s': %m", info->device);
/* If hibernate info is acquired from EFI variable, don't wait forever by default. Otherwise, if
* swap device is not present and HibernateLocation was not correctly cleared, we end up blocking
* the boot process infinitely. */
r = write_drop_in_format(arg_dest, device_unit, 40, "device-timeout",
"# Automatically generated by systemd-hibernate-resume-generator\n\n"
"[Unit]\n"
"JobTimeoutSec=%s\n",
info->cmdline ? "infinity" : "2min");
if (r < 0)
log_warning_errno(r, "Failed to write device timeout drop-in, ignoring: %m");
r = generator_write_timeouts(arg_dest,
info->device,
info->device,
arg_resume_options ?: arg_root_options,
NULL);
r = generator_write_device_timeout(arg_dest, info->device, arg_resume_options ?: arg_root_options, NULL);
if (r < 0)
log_warning_errno(r, "Failed to write device timeout drop-in, ignoring: %m");
if (r <= 0) {
/* No timeout explicitly defined? Wait infinitely if resume= is specified, 2min if from EFI
* HibernateLocation variable. In the latter case, we avoid blocking the boot process forever
* if a stale var is detected while the swap device is not present. */
r = write_drop_in_format(arg_dest, device_unit, 40, "device-timeout",
"# Automatically generated by systemd-hibernate-resume-generator\n\n"
"[Unit]\n"
"JobTimeoutSec=%s\n",
info->cmdline ? "infinity" : "2min");
if (r < 0)
log_warning_errno(r, "Failed to write fallback device timeout drop-in, ignoring: %m");
}
r = write_drop_in_format(arg_dest, SPECIAL_HIBERNATE_RESUME_SERVICE, 90, "device-dependency",
"# Automatically generated by systemd-hibernate-resume-generator\n\n"

View File

@ -368,10 +368,9 @@ int generator_write_fsck_deps(
return 0;
}
int generator_write_timeouts(
int generator_write_device_timeout(
const char *dir,
const char *what,
const char *where,
const char *opts,
char **filtered) {
@ -383,6 +382,9 @@ int generator_write_timeouts(
usec_t u;
int r;
assert(dir);
assert(what);
r = fstab_filter_options(opts, "comment=systemd.device-timeout\0"
"x-systemd.device-timeout\0",
NULL, &timeout, NULL, filtered);
@ -395,7 +397,7 @@ int generator_write_timeouts(
r = parse_sec_fix_0(timeout, &u);
if (r < 0) {
log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
log_warning("Failed to parse timeout for device '%s', ignoring: %s", what, timeout);
return 0;
}
@ -403,25 +405,62 @@ int generator_write_timeouts(
if (!node)
return log_oom();
if (!is_device_path(node)) {
log_warning("x-systemd.device-timeout ignored for %s", what);
log_warning("'%s' is not a device path, ignoring x-systemd.device-timeout= option.", node);
return 0;
}
r = unit_name_from_path(node, ".device", &unit);
if (r < 0)
return log_error_errno(r, "Failed to make unit name from path: %m");
return log_error_errno(r, "Failed to make unit name from device path '%s': %m", node);
return write_drop_in_format(dir, unit, 50, "device-timeout",
"# Automatically generated by %s\n"
"# from supplied options \"%s\"\n\n"
"[Unit]\n"
"JobRunningTimeoutSec=%s",
program_invocation_short_name,
opts,
timeout);
r = write_drop_in_format(dir, unit, 50, "device-timeout",
"# Automatically generated by %s\n"
"# from supplied options \"%s\"\n\n"
"[Unit]\n"
"JobRunningTimeoutSec=%s",
program_invocation_short_name,
opts,
timeout);
if (r < 0)
return r;
return 1;
}
int generator_write_device_deps(
int generator_write_unit_timeout(
FILE *f,
const char *where,
const char *opts,
const char *filter,
const char *unit_setting) {
_cleanup_free_ char *timeout = NULL;
usec_t u;
int r;
assert(f);
assert(where);
assert(filter);
assert(unit_setting);
r = fstab_filter_options(opts, filter, NULL, &timeout, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to parse options for '%s': %m", where);
if (r == 0)
return 0;
r = parse_sec_fix_0(timeout, &u);
if (r < 0) {
log_warning_errno(r, "Failed to parse timeout '%s' for '%s', ignoring: %m", timeout, where);
return 0;
}
fprintf(f, "%s=%s\n", unit_setting, FORMAT_TIMESPAN(u, 0));
return 0;
}
int generator_write_network_device_deps(
const char *dir,
const char *what,
const char *where,
@ -435,6 +474,10 @@ int generator_write_device_deps(
_cleanup_free_ char *node = NULL, *unit = NULL;
int r;
assert(dir);
assert(what);
assert(where);
if (fstab_is_extrinsic(where, opts))
return 0;
@ -451,8 +494,7 @@ int generator_write_device_deps(
r = unit_name_from_path(node, ".device", &unit);
if (r < 0)
return log_error_errno(r, "Failed to make unit name from path \"%s\": %m",
node);
return log_error_errno(r, "Failed to make unit name from path \"%s\": %m", node);
/* See mount_add_default_dependencies for explanation why we create such
* dependencies. */
@ -787,10 +829,7 @@ int generator_enable_remount_fs_service(const char *dir) {
SYSTEM_DATA_UNIT_DIR "/" SPECIAL_REMOUNT_FS_SERVICE);
}
int generator_write_blockdev_dependency(
FILE *f,
const char *what) {
int generator_write_blockdev_dependency(FILE *f, const char *what) {
_cleanup_free_ char *escaped = NULL;
int r;
@ -811,10 +850,7 @@ int generator_write_blockdev_dependency(
return 0;
}
int generator_write_cryptsetup_unit_section(
FILE *f,
const char *source) {
int generator_write_cryptsetup_unit_section(FILE *f, const char *source) {
assert(f);
fprintf(f,
@ -886,10 +922,7 @@ int generator_write_cryptsetup_service_section(
return 0;
}
int generator_write_veritysetup_unit_section(
FILE *f,
const char *source) {
int generator_write_veritysetup_unit_section(FILE *f, const char *source) {
assert(f);
fprintf(f,

View File

@ -7,13 +7,11 @@
#include "main-func.h"
int generator_open_unit_file_full(const char *dest, const char *source, const char *name, FILE **ret_file, char **ret_final_path, char **ret_temp_path);
static inline int generator_open_unit_file(const char *dest, const char *source, const char *name, FILE **ret_file) {
return generator_open_unit_file_full(dest, source, name, ret_file, NULL, NULL);
}
int generator_add_symlink_full(const char *dir, const char *dst, const char *dep_type, const char *src, const char *instance);
static inline int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src) {
return generator_add_symlink_full(dir, dst, dep_type, src, NULL);
}
@ -25,49 +23,32 @@ int generator_write_fsck_deps(
const char *where,
const char *type);
int generator_write_timeouts(
int generator_write_device_timeout(
const char *dir,
const char *what,
const char *where,
const char *opts,
char **filtered);
int generator_write_blockdev_dependency(
int generator_write_unit_timeout(
FILE *f,
const char *what);
const char *where,
const char *opts,
const char *filter,
const char *unit_setting);
static inline int generator_write_mount_timeout(FILE *f, const char *where, const char *opts) {
return generator_write_unit_timeout(f, where, opts,
"x-systemd.mount-timeout\0", "TimeoutSec");
}
int generator_write_cryptsetup_unit_section(
FILE *f,
const char *source);
int generator_write_blockdev_dependency(FILE *f, const char *what);
int generator_write_cryptsetup_service_section(
FILE *f,
const char *name,
const char *what,
const char *password,
const char *options);
int generator_write_veritysetup_unit_section(
FILE *f,
const char *source);
int generator_write_veritysetup_service_section(
FILE *f,
const char *name,
const char *data_what,
const char *hash_what,
const char *roothash,
const char *options);
int generator_write_device_deps(
int generator_write_network_device_deps(
const char *dir,
const char *what,
const char *where,
const char *opts);
int generator_write_initrd_root_device_deps(
const char *dir,
const char *what);
int generator_write_initrd_root_device_deps(const char *dir, const char *what);
int generator_hook_up_mkswap(
const char *dir,
@ -96,6 +77,23 @@ int generator_hook_up_quotaon(
const char *where,
const char *target);
int generator_write_cryptsetup_unit_section(FILE *f, const char *source);
int generator_write_cryptsetup_service_section(
FILE *f,
const char *name,
const char *what,
const char *password,
const char *options);
int generator_write_veritysetup_unit_section(FILE *f, const char *source);
int generator_write_veritysetup_service_section(
FILE *f,
const char *name,
const char *data_what,
const char *hash_what,
const char *roothash,
const char *options);
int generator_enable_remount_fs_service(const char *dir);
void log_setup_generator(void);