If a unit has FileDescriptorStorePreserve=yes we'll keep its FDs
around in case it starts again. But if there are no reverse
dependencies referencing it, we'll also GC it and lose all the FDs,
which defeats the point of the setting (which is opt-in).
Do not GC units that have FDs stored to avoid this.
Follow-up for
b9c1883a9cd9b5126fe648f3e198143dc19a222d
file descriptor store is automatically released when the service is stopped; if
<constant>restart</constant> (the default) it is kept around as long as the unit is neither inactive
nor failed, or a job is queued for the service, or the service is expected to be restarted. If
- <constant>yes</constant> the file descriptor store is kept around until the unit is removed from
- memory (i.e. is not referenced anymore and inactive). The latter is useful to keep entries in the
- file descriptor store pinned until the service manager exits.</para>
+ <constant>yes</constant> the file descriptor store is kept around and garbage collection of the unit
+ is disabled. The latter is useful to keep entries in the file descriptor store pinned until the unit
+ is removed, the service manager exits, or the file descriptors get <constant>EPOLLHUP</constant> or
+ <constant>EPOLLERR</constant>.</para>
<para>Use <command>systemctl clean --what=fdstore …</command> to release the file descriptor store
explicitly.</para>
resources, …) are flushed out immediately after the unit completed, except for what is stored in the logging
subsystem. Defaults to <option>inactive</option>.</para>
+ <para>Since v261, if <varname>FileDescriptorStorePreserve=</varname> is set to <option>yes</option>,
+ and the unit has file descriptors stored, garbage collection will be disabled until the unit is
+ removed, the service manager exits, or the file descriptors get <constant>EPOLLHUP</constant> or
+ <constant>EPOLLERR</constant>.</para>
+
<xi:include href="version-info.xml" xpointer="v236"/>
</listitem>
</varlistentry>
return false;
/* Only allow collection of actually dead services, i.e. not those that are in the transitionary
- * SERVICE_DEAD_BEFORE_AUTO_RESTART/SERVICE_FAILED_BEFORE_AUTO_RESTART states. */
- if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_DEAD_RESOURCES_PINNED))
+ * SERVICE_DEAD_BEFORE_AUTO_RESTART/SERVICE_FAILED_BEFORE_AUTO_RESTART states, and not those
+ * that still have resources pinned (fd store with FileDescriptorStorePreserve=yes) in case they are
+ * started again later despite not having any reverse dependency. */
+ if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED))
return false;
return true;