From 841c0987f7c199f06c92e7cc77d61b45fc552389 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 09:18:58 +0200 Subject: [PATCH 01/12] condition: check if path is absolute first We should do this check first since it is done on the string itself without any conditioning of system state otherwise. It is a weird to do this test only if /etc is read-only. --- src/shared/condition.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/shared/condition.c b/src/shared/condition.c index c83a4ba0eb8..e5de303a4b6 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -553,16 +553,15 @@ static int condition_test_needs_update(Condition *c, char **env) { assert(c->parameter); assert(c->type == CONDITION_NEEDS_UPDATE); + if (!path_is_absolute(c->parameter)) + return true; + /* If the file system is read-only we shouldn't suggest an update */ if (path_is_read_only_fs(c->parameter) > 0) return false; - /* Any other failure means we should allow the condition to be true, - * so that we rather invoke too many update tools than too - * few. */ - - if (!path_is_absolute(c->parameter)) - return true; + /* Any other failure means we should allow the condition to be true, so that we rather invoke too + * many update tools than too few. */ p = strjoina(c->parameter, "/.updated"); if (lstat(p, &other) < 0) From df1f5dc1d9d361b0d80bc98ae6cbbdb53c92d1f3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 09:20:24 +0200 Subject: [PATCH 02/12] condition: add debug log messages on unexpected errors --- src/shared/condition.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/shared/condition.c b/src/shared/condition.c index e5de303a4b6..45f36781a02 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -546,29 +546,40 @@ static int condition_test_capability(Condition *c, char **env) { } static int condition_test_needs_update(Condition *c, char **env) { - const char *p; struct stat usr, other; + const char *p; + int r; assert(c); assert(c->parameter); assert(c->type == CONDITION_NEEDS_UPDATE); - if (!path_is_absolute(c->parameter)) + if (!path_is_absolute(c->parameter)) { + log_debug("Specified condition parameter '%s' is not absolute, assuming an update is needed.", c->parameter); return true; + } /* If the file system is read-only we shouldn't suggest an update */ - if (path_is_read_only_fs(c->parameter) > 0) + r = path_is_read_only_fs(c->parameter); + if (r < 0) + log_debug_errno(r, "Failed to determine if '%s' is read-only, ignoring: %m", c->parameter); + if (r > 0) return false; /* Any other failure means we should allow the condition to be true, so that we rather invoke too * many update tools than too few. */ p = strjoina(c->parameter, "/.updated"); - if (lstat(p, &other) < 0) + if (lstat(p, &other) < 0) { + if (errno != ENOENT) + log_debug_errno(errno, "Failed to stat() '%s', assuming an update is needed: %m", p); return true; + } - if (lstat("/usr/", &usr) < 0) + if (lstat("/usr/", &usr) < 0) { + log_debug_errno(errno, "Failed to stat() /usr/, assuming an update is needed: %m"); return true; + } /* * First, compare seconds as they are always accurate... @@ -587,7 +598,6 @@ static int condition_test_needs_update(Condition *c, char **env) { if (usr.st_mtim.tv_nsec > 0 && other.st_mtim.tv_nsec == 0) { _cleanup_free_ char *timestamp_str = NULL; uint64_t timestamp; - int r; r = parse_env_file(NULL, p, "TIMESTAMP_NSEC", ×tamp_str); if (r < 0) { From f33cd69b5ce06c6c6ddc93622e9d9ece1660b678 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 09:27:04 +0200 Subject: [PATCH 03/12] condition: downgrade a few log messages to debug Condition checks shouldn't log loudly, since they run all the time. Let's make things debuggable, by keeping the messages in LOG_DEBUG in, but don't make more noise than necessary. --- src/shared/condition.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shared/condition.c b/src/shared/condition.c index 45f36781a02..4784c7db7de 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -601,16 +601,16 @@ static int condition_test_needs_update(Condition *c, char **env) { r = parse_env_file(NULL, p, "TIMESTAMP_NSEC", ×tamp_str); if (r < 0) { - log_error_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p); + log_debug_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p); return true; } else if (r == 0) { - log_debug("No data in timestamp file '%s', using mtime", p); + log_debug("No data in timestamp file '%s', using mtime.", p); return true; } r = safe_atou64(timestamp_str, ×tamp); if (r < 0) { - log_error_errno(r, "Failed to parse timestamp value '%s' in file '%s', using mtime: %m", timestamp_str, p); + log_debug_errno(r, "Failed to parse timestamp value '%s' in file '%s', using mtime: %m", timestamp_str, p); return true; } From b2d1ad757cd7713a492c4d9c1a254d5cbdfc4034 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 09:27:59 +0200 Subject: [PATCH 04/12] condition: when reading /etc/ modification timestamp, let's actualy compare it as-is Previously, we'd only compare the nsec component of it, which sounds needlessly fragile. Let's instead compare the timestamp as it is. --- src/shared/condition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/condition.c b/src/shared/condition.c index 4784c7db7de..2d9702d8732 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -614,7 +614,7 @@ static int condition_test_needs_update(Condition *c, char **env) { return true; } - timespec_store(&other.st_mtim, timestamp); + return timespec_load_nsec(&usr.st_mtim) > timestamp; } return usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec; From 3931056767acb5c44721a9f0870135646b39b70e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 09:37:27 +0200 Subject: [PATCH 05/12] proc-cmdline: add some explanatory comments --- src/basic/proc-cmdline.c | 6 +++--- src/basic/proc-cmdline.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index d3d99d9a7f9..d8d30b0f1df 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -268,17 +268,17 @@ int proc_cmdline_get_bool(const char *key, bool *ret) { r = proc_cmdline_get_key(key, PROC_CMDLINE_VALUE_OPTIONAL, &v); if (r < 0) return r; - if (r == 0) { + if (r == 0) { /* key not specified at all */ *ret = false; return 0; } - if (v) { /* parameter passed */ + if (v) { /* key with parameter passed */ r = parse_boolean(v); if (r < 0) return r; *ret = r; - } else /* no parameter passed */ + } else /* key without parameter passed */ *ret = true; return 1; diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h index 4115fdbc99f..275f46c89ec 100644 --- a/src/basic/proc-cmdline.h +++ b/src/basic/proc-cmdline.h @@ -6,9 +6,9 @@ #include "log.h" typedef enum ProcCmdlineFlags { - PROC_CMDLINE_STRIP_RD_PREFIX = 1 << 0, - PROC_CMDLINE_VALUE_OPTIONAL = 1 << 1, - PROC_CMDLINE_RD_STRICT = 1 << 2, + PROC_CMDLINE_STRIP_RD_PREFIX = 1 << 0, /* automatically strip "rd." prefix if it is set (and we are in the initrd, since otherwise we'd not consider it anyway) */ + PROC_CMDLINE_VALUE_OPTIONAL = 1 << 1, /* the value is optional (for boolean switches that can omit the value) */ + PROC_CMDLINE_RD_STRICT = 1 << 2, /* ignore this in the initrd */ } ProcCmdlineFlags; typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data); From f8b4ae29c74abbabecb8a109689771a2a6ff6a5f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 09:55:57 +0200 Subject: [PATCH 06/12] condition: allow overriding of ConditionNeedsUpdate= on the kernel command line This should be useful for addressing #15724. --- man/kernel-command-line.xml | 9 +++++++++ man/systemd-update-done.service.xml | 4 ++++ man/systemd.unit.xml | 7 +++++++ src/shared/condition.c | 7 +++++++ 4 files changed, 27 insertions(+) diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 4aac14ea180..b0cc3fea01c 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -436,6 +436,15 @@ will not query the user for basic system settings, even if the system boots up for the first time and the relevant settings are not initialized yet. + + + systemd.condition-needs-update= + + Takes a boolean argument. If specified, overrides the result of + ConditionNeedsUpdate= unit condition checks. See + systemd.unit5 for + details. + diff --git a/man/systemd-update-done.service.xml b/man/systemd-update-done.service.xml index ad412691a94..91196dff301 100644 --- a/man/systemd-update-done.service.xml +++ b/man/systemd-update-done.service.xml @@ -58,6 +58,10 @@ touch1 on it. + Note that if the systemd.condition-needs-update= kernel command line option is + used it overrides the ConditionNeedsUpdate= unit condition checks. In that case + systemd-update-done.service will not reset the condition state until a follow-up + reboot where the kernel switch is not specified anymore. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index b91c1ad0ecc..e8563bcc0a0 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1294,6 +1294,13 @@ systemd-update-done.service8, to make sure they run before the stamp file's modification time gets reset indicating a completed update. + + If the systemd.condition-needs-update= option is specified on the kernel + command line (taking a boolean), it will override the result of this condition check, taking + precedence over any file modification time checks. If it is used + systemd-update-done.service will not have immediate effect on any following + ConditionNeedsUpdate= checks, until the system is rebooted where the kernel + command line option is not specified anymore. diff --git a/src/shared/condition.c b/src/shared/condition.c index 2d9702d8732..2e29d4cca70 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -548,12 +548,19 @@ static int condition_test_capability(Condition *c, char **env) { static int condition_test_needs_update(Condition *c, char **env) { struct stat usr, other; const char *p; + bool b; int r; assert(c); assert(c->parameter); assert(c->type == CONDITION_NEEDS_UPDATE); + r = proc_cmdline_get_bool("systemd.condition-needs-update", &b); + if (r < 0) + log_debug_errno(r, "Failed to parse systemd.condition-needs-update= kernel command line argument, ignoring: %m"); + if (r > 0) + return b; + if (!path_is_absolute(c->parameter)) { log_debug("Specified condition parameter '%s' is not absolute, assuming an update is needed.", c->parameter); return true; From ce0f7f554685d5d4a2afffca9caf4fc142c5bc8a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 18 May 2020 20:11:27 +0200 Subject: [PATCH 07/12] condition: reverse if check to lower indentation level No change in behaviour. Let's just prefer early exit over deeper indentation. --- src/shared/condition.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/shared/condition.c b/src/shared/condition.c index 2e29d4cca70..b25e4f12b14 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -602,29 +602,27 @@ static int condition_test_needs_update(Condition *c, char **env) { * AND the target file's nanoseconds == 0 * (otherwise the filesystem supports nsec timestamps, see stat(2)). */ - if (usr.st_mtim.tv_nsec > 0 && other.st_mtim.tv_nsec == 0) { - _cleanup_free_ char *timestamp_str = NULL; - uint64_t timestamp; + if (usr.st_mtim.tv_nsec == 0 || other.st_mtim.tv_nsec > 0) + return usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec; - r = parse_env_file(NULL, p, "TIMESTAMP_NSEC", ×tamp_str); - if (r < 0) { - log_debug_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p); - return true; - } else if (r == 0) { - log_debug("No data in timestamp file '%s', using mtime.", p); - return true; - } - - r = safe_atou64(timestamp_str, ×tamp); - if (r < 0) { - log_debug_errno(r, "Failed to parse timestamp value '%s' in file '%s', using mtime: %m", timestamp_str, p); - return true; - } - - return timespec_load_nsec(&usr.st_mtim) > timestamp; + _cleanup_free_ char *timestamp_str = NULL; + r = parse_env_file(NULL, p, "TIMESTAMP_NSEC", ×tamp_str); + if (r < 0) { + log_debug_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p); + return true; + } else if (r == 0) { + log_debug("No data in timestamp file '%s', using mtime.", p); + return true; } - return usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec; + uint64_t timestamp; + r = safe_atou64(timestamp_str, ×tamp); + if (r < 0) { + log_debug_errno(r, "Failed to parse timestamp value '%s' in file '%s', using mtime: %m", timestamp_str, p); + return true; + } + + return timespec_load_nsec(&usr.st_mtim) > timestamp; } static int condition_test_first_boot(Condition *c, char **env) { From 5439d8212c97d7dd8af48f9b52146710ecda4767 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 10:07:34 +0200 Subject: [PATCH 08/12] condition: debug log if F_OK check on /run/systemd/first-boot fails unexpectedly --- src/shared/condition.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/shared/condition.c b/src/shared/condition.c index b25e4f12b14..b17403855a4 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -626,7 +626,7 @@ static int condition_test_needs_update(Condition *c, char **env) { } static int condition_test_first_boot(Condition *c, char **env) { - int r; + int r, q; assert(c); assert(c->parameter); @@ -636,7 +636,11 @@ static int condition_test_first_boot(Condition *c, char **env) { if (r < 0) return r; - return (access("/run/systemd/first-boot", F_OK) >= 0) == !!r; + q = access("/run/systemd/first-boot", F_OK); + if (q < 0 && errno != ENOENT) + log_debug_errno(errno, "Failed to check if /run/systemd/first-boot exists, ignoring: %m"); + + return (q >= 0) == !!r; } static int condition_test_environment(Condition *c, char **env) { From 814872e925ed79c70a13fdf9a9ca7eb30e551110 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 10:11:56 +0200 Subject: [PATCH 09/12] condition: introduce systemd.condition-first-boot= kernel command line switch Much like systemd.condition-needs-update= this new switch allows overriding of a unit file condition, but this time its ConditionFirstBoot=. Usecase is also primarily debugging, but could be useful for other schemes too. --- man/kernel-command-line.xml | 18 ++++++++++++++++-- man/systemd.unit.xml | 4 ++++ src/shared/condition.c | 7 +++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index b0cc3fea01c..8a899aee56a 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -433,8 +433,11 @@ Takes a boolean argument, defaults to on. If off, systemd-firstboot.service8 - will not query the user for basic system settings, even if the system boots up for the first time and the - relevant settings are not initialized yet. + will not query the user for basic system settings, even if the system boots up for the first time and + the relevant settings are not initialized yet. Not to be confused with + systemd.condition-first-boot= (see below), which overrides the result of the + ConditionFirstBoot= unit file condition, and thus controls more than just + systemd-firstboot.service behaviour. @@ -445,6 +448,17 @@ systemd.unit5 for details. + + + systemd.condition-first-boot= + + Takes a boolean argument. If specified, overrides the result of + ConditionFirstBoot= unit condition checks. See + systemd.unit5 for + details. Not to be confused with systemd.firstboot= which only controls behaviour + of the systemd-firstboot.service system service but has no effect on the + condition check (see above). + diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index e8563bcc0a0..fa8ed1b47bb 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1312,6 +1312,10 @@ (specifically: an /etc with no /etc/machine-id). This may be used to populate /etc on the first boot after factory reset, or when a new system instance boots up for the first time. + + If the systemd.condition-first-boot= option is specified on the kernel + command line (taking a boolean), it will override the result of this condition check, taking + precedence over /etc/machine-id existence checks. diff --git a/src/shared/condition.c b/src/shared/condition.c index b17403855a4..bf3b5fa1622 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -627,11 +627,18 @@ static int condition_test_needs_update(Condition *c, char **env) { static int condition_test_first_boot(Condition *c, char **env) { int r, q; + bool b; assert(c); assert(c->parameter); assert(c->type == CONDITION_FIRST_BOOT); + r = proc_cmdline_get_bool("systemd.condition-first-boot", &b); + if (r < 0) + log_debug_errno(r, "Failed to parse systemd.condition-first-boot= kernel command line argument, ignoring: %m"); + if (r > 0) + return b == !!r; + r = parse_boolean(c->parameter); if (r < 0) return r; From 3753325bef425f54928cee8f4ac06c7833e8dc77 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 10:41:47 +0200 Subject: [PATCH 10/12] main: add a kernel command line option for setting the system clock early during boot --- man/kernel-command-line.xml | 8 ++++++++ src/core/main.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 8a899aee56a..fd49b65a8d4 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -459,6 +459,14 @@ of the systemd-firstboot.service system service but has no effect on the condition check (see above). + + + systemd.clock-usec= + + Takes a decimal, numeric timestamp in µs since January 1st 1970, 00:00am, to set the + system clock to. The system time is set to the specified timestamp early during + boot. It is not propagated to the hardware clock (RTC). + diff --git a/src/core/main.c b/src/core/main.c index c9eaf70bd6c..3ab4aa4e198 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -146,6 +146,7 @@ static EmergencyAction arg_cad_burst_action; static OOMPolicy arg_default_oom_policy; static CPUSet arg_cpu_affinity; static NUMAPolicy arg_numa_policy; +static usec_t arg_clock_usec; /* A copy of the original environment block */ static char **saved_env = NULL; @@ -491,6 +492,15 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat (void) parse_path_argument_and_warn(value, false, &arg_watchdog_device); + } else if (proc_cmdline_key_streq(key, "systemd.clock_usec")) { + + if (proc_cmdline_value_missing(key, value)) + return 0; + + r = safe_atou64(value, &arg_clock_usec); + if (r < 0) + log_warning_errno(r, "Failed to parse systemd.clock_usec= argument, ignoring: %s", value); + } else if (streq(key, "quiet") && !value) { if (arg_show_status == _SHOW_STATUS_INVALID) @@ -1504,6 +1514,9 @@ static int become_shutdown( static void initialize_clock(void) { int r; + /* This is called very early on, before we parse the kernel command line or otherwise figure out why + * we are running, but only once. */ + if (clock_is_localtime(NULL) > 0) { int min; @@ -1542,6 +1555,25 @@ static void initialize_clock(void) { log_info("System time before build time, advancing clock."); } +static void apply_clock_update(void) { + struct timespec ts; + + /* This is called later than initialize_clock(), i.e. after we parsed configuration files/kernel + * command line and such. */ + + if (arg_clock_usec == 0) + return; + + if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, arg_clock_usec)) < 0) + log_error_errno(errno, "Failed to set system clock to time specified on kernel command line: %m"); + else { + char buf[FORMAT_TIMESTAMP_MAX]; + + log_info("Set system clock to %s, as specified on the kernel command line.", + format_timestamp(buf, sizeof(buf), arg_clock_usec)); + } +} + static void initialize_coredump(bool skip_setup) { #if ENABLE_COREDUMP if (getpid_cached() != 1) @@ -2658,6 +2690,8 @@ int main(int argc, char *argv[]) { assert_se(chdir("/") == 0); if (arg_action == ACTION_RUN) { + /* Apply the systemd.clock_usec= kernel command line switch */ + apply_clock_update(); /* A core pattern might have been specified via the cmdline. */ initialize_core_pattern(skip_setup); From 34293dfafd2a81d80727938199769906dab321bd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 11:01:31 +0200 Subject: [PATCH 11/12] core: allow overriding the system hostname with systemd.hostname= on the kernel command line --- man/kernel-command-line.xml | 8 ++++++++ src/core/hostname-setup.c | 36 ++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index fd49b65a8d4..0f2972a0b68 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -467,6 +467,14 @@ system clock to. The system time is set to the specified timestamp early during boot. It is not propagated to the hardware clock (RTC). + + + systemd.hostname= + + Accepts a hostname to set during early boot. If specified takes precedence over what + is set in /etc/hostname. Note that this does not bar later runtime changes to + the hostname, it simply controls the initial hostname set during early boot. + diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c index 83cce88131e..6d047db8388 100644 --- a/src/core/hostname-setup.c +++ b/src/core/hostname-setup.c @@ -10,29 +10,41 @@ #include "hostname-util.h" #include "log.h" #include "macro.h" +#include "proc-cmdline.h" #include "string-util.h" #include "util.h" int hostname_setup(void) { _cleanup_free_ char *b = NULL; + const char *hn = NULL; bool enoent = false; - const char *hn; int r; - r = read_etc_hostname(NULL, &b); - if (r < 0) { - if (r == -ENOENT) - enoent = true; - else - log_warning_errno(r, "Failed to read configured hostname: %m"); + r = proc_cmdline_get_key("systemd.hostname", 0, &b); + if (r < 0) + log_warning_errno(r, "Failed to retrieve system hostname from kernel command line, ignoring: %m"); + else if (r > 0) { + if (hostname_is_valid(b, true)) + hn = b; + else { + log_warning("Hostname specified on kernel command line is invalid, ignoring: %s", b); + b = mfree(b); + } + } - hn = NULL; - } else - hn = b; + if (!hn) { + r = read_etc_hostname(NULL, &b); + if (r < 0) { + if (r == -ENOENT) + enoent = true; + else + log_warning_errno(r, "Failed to read configured hostname: %m"); + } else + hn = b; + } if (isempty(hn)) { - /* Don't override the hostname if it is already set - * and not explicitly configured */ + /* Don't override the hostname if it is already set and not explicitly configured */ if (hostname_is_set()) return 0; From c6526b8d6650b543523b6aa76f92520d797e00b6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 May 2020 10:13:40 +0200 Subject: [PATCH 12/12] update TODO --- TODO | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TODO b/TODO index 792f2d4be1a..42f2fcfe149 100644 --- a/TODO +++ b/TODO @@ -252,8 +252,7 @@ Features: that are linked to these places instead of copied. After all they are constant vendor data. -* maybe add kernel cmdline params: 1) to force first-boot mode + 2) to force - random seed crediting +* maybe add kernel cmdline params: to force random seed crediting * nspawn: on cgroupsv1 issue cgroup empty handler process based on host events, so that we make cgroup agent logic safe