From bd3beda2834a1400faa1ad83e0eb27ce2a1d0cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 13 Oct 2022 14:05:01 +0200 Subject: [PATCH] shared/condition: add envvar override for the check for first-boot Before 7cd43e34c5a302ff323c013f437092d2ff5ccbbf, it was possible to use SYSTEMD_PROC_CMDLINE=systemd.condition-first-boot to override autodetection. But now this doesn't work anymore, and it's useful to be able to do that for testing. --- docs/ENVIRONMENT.md | 3 +++ src/shared/condition.c | 33 +++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 2ba222d3a62..f1b9fd7715c 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -35,6 +35,9 @@ All tools: as `start` into no-ops. If that's what's explicitly desired, you might consider setting `$SYSTEMD_OFFLINE=1`. +* `$SYSTEMD_FIRST_BOOT=0|1` — if set, assume "first boot" condition to be false + or true, instead of checking the flag file created by PID 1. + * `$SD_EVENT_PROFILE_DELAYS=1` — if set, the sd-event event loop implementation will print latency information at runtime. diff --git a/src/shared/condition.c b/src/shared/condition.c index e5a80757e09..fce3fc2afbb 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -821,22 +821,43 @@ static int condition_test_needs_update(Condition *c, char **env) { return timespec_load_nsec(&usr.st_mtim) > timestamp; } +static bool in_first_boot(void) { + static int first_boot = -1; + int r; + + if (first_boot >= 0) + return first_boot; + + 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 = 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; +} + static int condition_test_first_boot(Condition *c, char **env) { - int r, q; + int r; assert(c); assert(c->parameter); assert(c->type == CONDITION_FIRST_BOOT); + // TODO: Parse c->parameter immediately when reading the config. + // Apply negation when parsing too. + r = parse_boolean(c->parameter); if (r < 0) return 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, assuming no: %m"); - - return (q >= 0) == r; + return in_first_boot() == r; } static int condition_test_environment(Condition *c, char **env) {