]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: do not GC units that have FDs stored 41435/head
authorLuca Boccassi <luca.boccassi@gmail.com>
Thu, 2 Apr 2026 11:11:01 +0000 (12:11 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 2 Apr 2026 11:22:43 +0000 (12:22 +0100)
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

man/systemd.service.xml
man/systemd.unit.xml
src/core/service.c

index 549f36af1db777e970d933bd3344c0d7b1c49f1e..d4a19785230112d7c15e397701ccc30b81e8559c 100644 (file)
@@ -1250,9 +1250,10 @@ RestartMaxDelaySec=160s</programlisting>
         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>
index 8bbff2f210a7f755f70dd54839a51740bba6e549..47c30d869fcbed897d087efaea0180cde2bfd049 100644 (file)
         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>
index f3e5a5f85b78e093da07abf962c3146af881ae60..569a6871d602f41c14571ad505a74329c14d1f55 100644 (file)
@@ -3959,8 +3959,10 @@ static bool service_may_gc(Unit *u) {
                 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;