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:
commit
184ce19841
@ -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");
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user