1
0
mirror of https://github.com/systemd/systemd synced 2025-10-06 00:13:24 +02:00

sd-daemon: add sd_pidfd_get_inode_id()

We nowadays expose pidfdid at various places, e.g. envvars
and dbus properties. Also the sd_notify() MAINPID= message
has been complemented with MAINPIDFDID=. But acquiring
pidfdid is actually non-trivial especially considering
the 32-bit case, hence let's introduce a public helper
in sd-daemon specifically for that purpose.
This commit is contained in:
Mike Yuan
2025-06-01 09:12:13 +02:00
parent a842c26be3
commit 46b0844743
8 changed files with 145 additions and 6 deletions

5
NEWS
View File

@@ -1208,6 +1208,11 @@ CHANGES WITH 258 in spe:
* sd-bus: a new API call sd_bus_message_dump_json() returns a JSON * sd-bus: a new API call sd_bus_message_dump_json() returns a JSON
representation of a D-Bus message. representation of a D-Bus message.
* sd-daemon: a new call sd_pidfd_get_inode_id() has been added
for acquiring the unique inode ID of a pidfd, coupling the
$MAINPIDFDID/$MANAGERPIDFDID and session/machine leader pidfd IDs
exposed as described above.
— <place>, <date> — <place>, <date>
CHANGES WITH 257: CHANGES WITH 257:

View File

@@ -882,6 +882,7 @@ manpages = [
'sd_pidfd_get_user_slice', 'sd_pidfd_get_user_slice',
'sd_pidfd_get_user_unit'], 'sd_pidfd_get_user_unit'],
'HAVE_PAM'], 'HAVE_PAM'],
['sd_pidfd_get_inode_id', '3', [], ''],
['sd_seat_get_active', ['sd_seat_get_active',
'3', '3',
['sd_seat_can_graphical', 'sd_seat_can_tty', 'sd_seat_get_sessions'], ['sd_seat_can_graphical', 'sd_seat_can_tty', 'sd_seat_get_sessions'],

View File

@@ -55,10 +55,10 @@
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry> <citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
for more information about the functions implemented. In addition and <citerefentry><refentrytitle>sd_pidfd_get_inode_id</refentrytitle><manvolnum>3</manvolnum></citerefentry>
to these functions, a couple of logging prefixes are defined as for more information about the functions implemented. In addition to these functions, a couple of
macros:</para> logging prefixes are defined as macros:</para>
<programlisting>#define SD_EMERG "&lt;0&gt;" /* system is unusable */ <programlisting>#define SD_EMERG "&lt;0&gt;" /* system is unusable */
#define SD_ALERT "&lt;1&gt;" /* action must be taken immediately */ #define SD_ALERT "&lt;1&gt;" /* action must be taken immediately */
@@ -104,6 +104,7 @@
<member><citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>sd_is_fifo</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd_pidfd_get_inode_id</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry></member> <member><citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>

View File

@@ -306,8 +306,7 @@
<listitem><para>The pidfd inode number of the new main process (specified through <varname>MAINPID=</varname>). <listitem><para>The pidfd inode number of the new main process (specified through <varname>MAINPID=</varname>).
This information can be acquired through This information can be acquired through
<citerefentry project='man-pages'><refentrytitle>name_to_handle_at</refentrytitle><manvolnum>2</manvolnum></citerefentry> <citerefentry><refentrytitle>sd_pidfd_get_inode_id</refentrytitle><manvolnum>3</manvolnum></citerefentry>
or <citerefentry project='man-pages'><refentrytitle>fstat</refentrytitle><manvolnum>2</manvolnum></citerefentry>
on the pidfd and is used to identify the process in a race-free fashion. Alternatively, on the pidfd and is used to identify the process in a race-free fashion. Alternatively,
a pidfd can be sent directly to the service manager (see <varname>MAINPIDFD=1</varname> below).</para> a pidfd can be sent directly to the service manager (see <varname>MAINPIDFD=1</varname> below).</para>

View File

@@ -0,0 +1,107 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="sd_pidfd_get_inode_id"
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>sd_pidfd_get_inode_id</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>sd_pidfd_get_inode_id</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd_pidfd_get_inode_id</refname>
<refpurpose>Acquire the 64-bit inode ID of a PID file descriptor (PIDFD)</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_pidfd_get_inode_id</function></funcdef>
<paramdef>int <parameter>pidfd</parameter></paramdef>
<paramdef>uint64_t *<parameter>ret</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>sd_pidfd_get_inode_id()</function> may be invoked to acquire the 64-bit inode ID of
a PID file descriptor (PIDFD), which can be used to reliably identify a process for the current boot.</para>
<para>As a typical example, the service manager sets <varname>$MAINPIDFDID</varname> and <varname>$MANAGERPIDFDID</varname>
environment variables to the inode IDs of the service main process and the service manager itself, respectively,
if such functionality is supported by the kernel.</para>
<para>On 64-bit architectures, the inode ID can be directly obtained via a call to
<citerefentry project='man-pages'><refentrytitle>fstat</refentrytitle><manvolnum>2</manvolnum></citerefentry>
on a given pidfd. However, on 32-bit architectures <structname>struct stat</structname>'s .st_ino
field is also 32-bit, which similar to PIDs is subject to reuse. Therefore, a second mechanism leveraging
<citerefentry project='man-pages'><refentrytitle>name_to_handle_at</refentrytitle><manvolnum>2</manvolnum></citerefentry>
has been added to kernel in v6.14. This helper is added to simplify downstream handling of pidfd/pidfs internals.
</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para>On success, the function returns 0 or a positive integer. On failure, a negative errno-style
error code is returned.</para>
<refsect2>
<title>Errors</title>
<para>Returned errors may indicate the following problems:</para>
<variablelist>
<varlistentry>
<term><constant>-EOPNOTSUPP</constant></term>
<listitem><para>The stable PIDFD inode ID is not supported by the running kernel, or the system
is 32-bit and <function>name_to_handle_at()</function> is unavailable.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-EBADF</constant></term>
<listitem><para>The specified file descriptor is invalid, or is not a PIDFD.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<refsect1>
<title>Notes</title>
<xi:include href="libsystemd-pkgconfig.xml" xpointer="pkgconfig-text"/>
</refsect1>
<refsect1>
<title>History</title>
<para><function>sd_pidfd_get_inode_id()</function> was added in version 258.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry>

View File

@@ -1067,6 +1067,7 @@ global:
sd_device_get_sysattr_value_with_size; sd_device_get_sysattr_value_with_size;
sd_json_variant_type_from_string; sd_json_variant_type_from_string;
sd_json_variant_type_to_string; sd_json_variant_type_to_string;
sd_pidfd_get_inode_id;
sd_varlink_get_current_method; sd_varlink_get_current_method;
sd_varlink_get_description; sd_varlink_get_description;
sd_varlink_get_input_fd; sd_varlink_get_input_fd;

View File

@@ -18,8 +18,10 @@
#include "io-util.h" #include "io-util.h"
#include "iovec-util.h" #include "iovec-util.h"
#include "log.h" #include "log.h"
#include "missing_magic.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pidfd-util.h"
#include "process-util.h" #include "process-util.h"
#include "socket-util.h" #include "socket-util.h"
#include "stat-util.h" #include "stat-util.h"
@@ -752,6 +754,27 @@ finish:
return r; return r;
} }
_public_ int sd_pidfd_get_inode_id(int pidfd, uint64_t *ret) {
int r;
assert_return(pidfd >= 0, -EBADF);
/* Are pidfds backed by pidfs where the unique inode id is relevant? Note that the pidfd
* passed to us is extrinsic and hence cannot be trusted to initialize our "have_pidfs" cache,
* instead pidfd_check_pidfs() will allocate one internally. */
r = pidfd_check_pidfs(/* pid_fd = */ -EBADF);
if (r <= 0)
return -EOPNOTSUPP;
r = fd_is_fs_type(pidfd, PID_FS_MAGIC);
if (r < 0)
return r;
if (r == 0)
return -EBADF; /* pidfs is definitely around, so it's the fd that's of invalid type */
return pidfd_get_inode_id_impl(pidfd, ret);
}
_public_ int sd_booted(void) { _public_ int sd_booted(void) {
int r; int r;

View File

@@ -311,6 +311,8 @@ int sd_notify_barrier(int unset_environment, uint64_t timeout);
*/ */
int sd_pid_notify_barrier(pid_t pid, int unset_environment, uint64_t timeout); int sd_pid_notify_barrier(pid_t pid, int unset_environment, uint64_t timeout);
int sd_pidfd_get_inode_id(int pidfd, uint64_t *ret);
/* /*
Returns > 0 if the system was booted with systemd. Returns < 0 on Returns > 0 if the system was booted with systemd. Returns < 0 on
error. Returns 0 if the system was not booted with systemd. Note error. Returns 0 if the system was not booted with systemd. Note