diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 8a2fa448dc..2944594640 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -3886,22 +3886,40 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
$MAINPID
- The PID of the unit's main process if it is
- known. This is only set for control processes as invoked by
- ExecReload= and similar.
+ 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 ExecReload= and similar.
+
+ $MAINPIDFDID
+
+ The 64bit inode ID of the file descriptor returned by pidfd_open3
+ for the main process (if supported). This is only set for control processes as invoked by
+ ExecReload= and similar.
+
+
+
+
$MANAGERPID
- The PID of the user systemd
- instance, set for processes spawned by it.
-
+ The PID of the per-user systemd service manager instance, set
+ for processes spawned by it.
+
+ $MANAGERPIDFDID
+
+ The pidfd_open() inode ID (see above) of the per-user
+ systemd service manager instance, set for processes spawned by it.
+
+
+
+
$LISTEN_FDS
$LISTEN_PID
diff --git a/src/core/service.c b/src/core/service.c
index e5d23f87dd..626a47f7a8 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -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;