]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pid1: pass pidfdids to invoked services in $MAINPIDFDID and $MANAGERPIDFDID
authorLennart Poettering <lennart@poettering.net>
Fri, 17 Jan 2025 13:09:53 +0000 (14:09 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 20 Jan 2025 20:51:40 +0000 (21:51 +0100)
man/systemd.exec.xml
src/core/service.c

index 8a2fa448dc7cc79c438ae7b6ca0bab693ac1347d..294459464094e15621fcd3a70a3ce55d52ad836c 100644 (file)
@@ -3886,22 +3886,40 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
         <varlistentry>
           <term><varname>$MAINPID</varname></term>
 
-          <listitem><para>The PID of the unit's main process if it is
-          known. This is only set for control processes as invoked by
-          <varname>ExecReload=</varname> and similar.</para>
+          <listitem><para>The UNIX process ID (PID) of the unit's main process if it is known. This is only
+          set for control processes as invoked by <varname>ExecReload=</varname> and similar.</para>
 
           <xi:include href="version-info.xml" xpointer="v209"/></listitem>
         </varlistentry>
 
         <varlistentry>
-          <term><varname>$MANAGERPID</varname></term>
+          <term><varname>$MAINPIDFDID</varname></term>
 
-          <listitem><para>The PID of the user <command>systemd</command>
-          instance, set for processes spawned by it.</para>
+          <listitem><para>The 64bit inode ID of the file descriptor returned by <citerefentry
+          project='man-pages'><refentrytitle>pidfd_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+          for the main process (if supported). This is only set for control processes as invoked by
+          <varname>ExecReload=</varname> and similar.</para>
 
+          <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><varname>$MANAGERPID</varname></term>
+
+          <listitem><para>The PID of the per-user <command>systemd</command> service manager instance, set
+          for processes spawned by it.</para>
           <xi:include href="version-info.xml" xpointer="v208"/></listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>$MANAGERPIDFDID</varname></term>
+
+          <listitem><para>The <function>pidfd_open()</function> inode ID (see above) of the per-user
+          <command>systemd</command> service manager instance, set for processes spawned by it.</para>
+
+          <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>$LISTEN_FDS</varname></term>
           <term><varname>$LISTEN_PID</varname></term>
index e5d23f87dd0976524bed56d8d656d8ade5e0e8c9..626a47f7a8fd0aae8237b7cc8136ea0536b82726 100644 (file)
@@ -36,6 +36,7 @@
 #include "open-file.h"
 #include "parse-util.h"
 #include "path-util.h"
+#include "pidfd-util.h"
 #include "process-util.h"
 #include "random-util.h"
 #include "selinux-util.h"
@@ -1769,7 +1770,7 @@ static int service_spawn_internal(
         if (r < 0)
                 return r;
 
-        our_env = new0(char*, 13);
+        our_env = new0(char*, 15);
         if (!our_env)
                 return -ENOMEM;
 
@@ -1781,14 +1782,25 @@ static int service_spawn_internal(
                                 return -ENOMEM;
         }
 
-        if (pidref_is_set(&s->main_pid))
+        if (pidref_is_set(&s->main_pid)) {
                 if (asprintf(our_env + n_env++, "MAINPID="PID_FMT, s->main_pid.pid) < 0)
                         return -ENOMEM;
 
-        if (MANAGER_IS_USER(UNIT(s)->manager))
+                if (pidref_acquire_pidfd_id(&s->main_pid) >= 0)
+                        if (asprintf(our_env + n_env++, "MAINPIDFDID=%" PRIu64, s->main_pid.fd_id) < 0)
+                                return -ENOMEM;
+        }
+
+        if (MANAGER_IS_USER(UNIT(s)->manager)) {
                 if (asprintf(our_env + n_env++, "MANAGERPID="PID_FMT, getpid_cached()) < 0)
                         return -ENOMEM;
 
+                uint64_t pidfdid;
+                if (pidfd_get_inode_id_self_cached(&pidfdid) >= 0)
+                        if (asprintf(our_env + n_env++, "MANAGERPIDFDID=%" PRIu64, pidfdid) < 0)
+                                return -ENOMEM;
+        }
+
         if (s->pid_file)
                 if (asprintf(our_env + n_env++, "PIDFILE=%s", s->pid_file) < 0)
                         return -ENOMEM;