From e735bc49ac2a64a9b044731cfa36ed0950884ea3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Feb 2025 23:35:57 +0100 Subject: [PATCH] unit: don't bother determining unit install state for transient or perpetual units 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 | 52 ++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/core/unit.c b/src/core/unit.c index 1254091d74e..476c5332da9 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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) { -- 2.47.3