From: Lennart Poettering Date: Mon, 24 Feb 2025 22:35:57 +0000 (+0100) Subject: unit: don't bother determining unit install state for transient or perpetual units X-Git-Tag: v258-rc1~966^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e735bc49ac2a64a9b044731cfa36ed0950884ea3;p=thirdparty%2Fsystemd.git 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.) --- 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) {