]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/condition: add envvar override for the check for first-boot
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 13 Oct 2022 12:05:01 +0000 (14:05 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 23 May 2023 13:09:39 +0000 (15:09 +0200)
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
src/shared/condition.c

index 2ba222d3a627571aee6180c8fae937d08cebd89a..f1b9fd7715c79b15681252c9919f3d32bbf2c2be 100644 (file)
@@ -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.
 
index e5a80757e095352adcb8027efc571d5ee31f399f..fce3fc2afbb7eb3612ebe48ce2ead388d4e6ea2a 100644 (file)
@@ -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) {