]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
unit: don't bother determining unit install state for transient or perpetual units
authorLennart Poettering <lennart@poettering.net>
Mon, 24 Feb 2025 22:35:57 +0000 (23:35 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 1 Apr 2025 14:44:20 +0000 (16:44 +0200)
I noticed that we keep querying the preset database for transient units,
which makes little sense, since transient units are well, transient, and
hence not suject to enablement/disablement. Hence, let's shortcut things
and simply not check the preset database for them.

While we are at it, shortcut unit file state checks for transient units,
too.  We know they are transient already, we can return that directly,
no need to go to disk.

Finally, treat perpetual units like transient units for the the preset
case: also bypass the preset database. (But keep checking for the unit
file state for them, since it *is* relevant to know whether they were
generated or not.)

src/core/unit.c

index 1254091d74ed241731b0356781dc9b24949fc800..476c5332da9be42b9809007da2d28a4e4469da95 100644 (file)
@@ -4149,15 +4149,21 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
 
         assert(u);
 
-        if (u->unit_file_state < 0 && u->fragment_path) {
-                r = unit_file_get_state(
-                                u->manager->runtime_scope,
-                                NULL,
-                                u->id,
-                                &u->unit_file_state);
-                if (r < 0)
-                        u->unit_file_state = UNIT_FILE_BAD;
-        }
+        if (u->unit_file_state >= 0 || !u->fragment_path)
+                return u->unit_file_state;
+
+        /* If we know this is a transient unit no need to ask the unit file state for details. Let's bypass
+         * the more expensive on-disk check. */
+        if (u->transient)
+                return (u->unit_file_state = UNIT_FILE_TRANSIENT);
+
+        r = unit_file_get_state(
+                        u->manager->runtime_scope,
+                        /* root_dir= */ NULL,
+                        u->id,
+                        &u->unit_file_state);
+        if (r < 0)
+                u->unit_file_state = UNIT_FILE_BAD;
 
         return u->unit_file_state;
 }
@@ -4167,24 +4173,26 @@ PresetAction unit_get_unit_file_preset(Unit *u) {
 
         assert(u);
 
-        if (u->unit_file_preset < 0 && u->fragment_path) {
-                _cleanup_free_ char *bn = NULL;
+        if (u->unit_file_preset >= 0 || !u->fragment_path)
+                return u->unit_file_preset;
 
-                r = path_extract_filename(u->fragment_path, &bn);
-                if (r < 0)
-                        return (u->unit_file_preset = r);
+        /* If this is a transient or perpetual unit file it doesn't make much sense to ask the preset
+         * database about this, because enabling/disabling makes no sense for either. Hence don't. */
+        if (u->transient || u->perpetual)
+                return (u->unit_file_preset = -ENOEXEC);
 
-                if (r == O_DIRECTORY)
-                        return (u->unit_file_preset = -EISDIR);
+        _cleanup_free_ char *bn = NULL;
+        r = path_extract_filename(u->fragment_path, &bn);
+        if (r < 0)
+                return (u->unit_file_preset = r);
+        if (r == O_DIRECTORY)
+                return (u->unit_file_preset = -EISDIR);
 
-                u->unit_file_preset = unit_file_query_preset(
+        return (u->unit_file_preset = unit_file_query_preset(
                                 u->manager->runtime_scope,
-                                NULL,
+                                /* root_dir= */ NULL,
                                 bn,
-                                NULL);
-        }
-
-        return u->unit_file_preset;
+                                /* cache= */ NULL));
 }
 
 Unit* unit_ref_set(UnitRef *ref, Unit *source, Unit *target) {