basic: update in_first_boot() to return an error
This commit tweaks the in_first_boot() code to make it a proper shared helper. It tweaks the comments about the caching policy. This is important because while this is simialr to `in_initrd()` there is a suble difference: we never cache the result of access() because other parts of systemd will use this file to signal if anything about firstboot changes. This also tweaks it to return an int instead of a bool. So any error is returned as -errno. This allows other parts of systemd (like the random-seed) that need to make decisions about "unknown" first-boot state. This also means that the consumers need to get updated and we can now also use the new helper in random-seed-tool.c and have only a single helper to check for first-boot.
This commit is contained in:
+17
-17
@@ -1,13 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "env-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "log.h"
|
||||
#include "parse-util.h"
|
||||
|
||||
static int saved_in_initrd = -1;
|
||||
|
||||
@@ -41,24 +39,26 @@ void in_initrd_force(bool value) {
|
||||
saved_in_initrd = value;
|
||||
}
|
||||
|
||||
bool in_first_boot(void) {
|
||||
static int first_boot = -1;
|
||||
int in_first_boot(void) {
|
||||
static int first_boot_env_parse_cached = -1;
|
||||
int r;
|
||||
|
||||
if (first_boot >= 0)
|
||||
return first_boot;
|
||||
if (first_boot_env_parse_cached >= 0)
|
||||
return first_boot_env_parse_cached;
|
||||
|
||||
const char *e = secure_getenv("SYSTEMD_FIRST_BOOT");
|
||||
if (e) {
|
||||
r = parse_boolean(e);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse $SYSTEMD_FIRST_BOOT, ignoring: %m");
|
||||
else
|
||||
return (first_boot = r);
|
||||
}
|
||||
r = secure_getenv_bool("SYSTEMD_FIRST_BOOT");
|
||||
if (r >= 0)
|
||||
return (first_boot_env_parse_cached = r);
|
||||
if (r != -ENXIO)
|
||||
log_debug_errno(r, "Failed to parse $SYSTEMD_FIRST_BOOT, ignoring: %m");
|
||||
|
||||
/* This is not cached and must *never* be cached, other parts of systemd write it to signal
|
||||
* an update to the first-boot state. */
|
||||
r = RET_NERRNO(access("/run/systemd/first-boot", F_OK));
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_debug_errno(r, "Failed to check if /run/systemd/first-boot exists, assuming no: %m");
|
||||
return r >= 0;
|
||||
if (r >= 0)
|
||||
return true;
|
||||
if (r == -ENOENT)
|
||||
return false;
|
||||
|
||||
return log_debug_errno(r, "Failed to check /run/systemd/first-boot: %m");
|
||||
}
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
bool in_initrd(void);
|
||||
void in_initrd_force(bool value);
|
||||
|
||||
bool in_first_boot(void);
|
||||
int in_first_boot(void);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "format-table.h"
|
||||
#include "fs-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "io-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
@@ -88,8 +89,8 @@ static CreditEntropy may_credit(int seed_fd) {
|
||||
/* Don't credit the random seed if we are in first-boot mode, because we are supposed to start from
|
||||
* scratch. This is a safety precaution for cases where people ship "golden" images with empty
|
||||
* /etc but populated /var that contains a random seed. */
|
||||
r = RET_NERRNO(access("/run/systemd/first-boot", F_OK));
|
||||
if (r == -ENOENT)
|
||||
r = in_first_boot();
|
||||
if (r == 0)
|
||||
/* All is good, we are not in first-boot mode. */
|
||||
return CREDIT_ENTROPY_YES_PLEASE;
|
||||
if (r < 0) {
|
||||
|
||||
@@ -974,7 +974,7 @@ static int condition_test_first_boot(Condition *c, char **env) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return in_first_boot() == r;
|
||||
return (in_first_boot() > 0) == r;
|
||||
}
|
||||
|
||||
static int condition_test_environment(Condition *c, char **env) {
|
||||
|
||||
@@ -1277,7 +1277,10 @@ static int check_null_key_policy(CredentialFlags flags) {
|
||||
* exists yet); the decision itself is made in credential_boot_policy_accepts_null(). */
|
||||
|
||||
CredentialBootPolicy policy = query_credential_boot_policy();
|
||||
bool first_boot = in_first_boot(), have_tpm2 = efi_has_tpm2(), secure_boot = is_efi_secure_boot();
|
||||
|
||||
bool have_tpm2 = efi_has_tpm2(), secure_boot = is_efi_secure_boot();
|
||||
/* in_first_boot() can return <0 on error: use the safe default in this case (not-first-boot). */
|
||||
bool first_boot = in_first_boot() > 0;
|
||||
|
||||
if (!credential_boot_policy_accepts_null(policy, first_boot, have_tpm2, secure_boot))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON),
|
||||
|
||||
Reference in New Issue
Block a user