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.)
This commit is contained in:
Lennart Poettering
2025-04-01 16:44:20 +02:00
parent c5855d9640
commit e735bc49ac
+30 -22
View 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) {