* sd-bus: a new API call sd_bus_message_dump_json() returns a JSON
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>
CHANGES WITH 257:
'sd_pidfd_get_user_slice',
'sd_pidfd_get_user_unit'],
'HAVE_PAM'],
+ ['sd_pidfd_get_inode_id', '3', [], ''],
['sd_seat_get_active',
'3',
['sd_seat_can_graphical', 'sd_seat_can_tty', 'sd_seat_get_sessions'],
<citerefentry><refentrytitle>sd_notify</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_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- for more information about the functions implemented. In addition
- to these functions, a couple of logging prefixes are defined as
- macros:</para>
+ <citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ and <citerefentry><refentrytitle>sd_pidfd_get_inode_id</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ for more information about the functions implemented. In addition to these functions, a couple of
+ logging prefixes are defined as macros:</para>
<programlisting>#define SD_EMERG "<0>" /* system is unusable */
#define SD_ALERT "<1>" /* action must be taken immediately */
<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_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>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
<listitem><para>The pidfd inode number of the new main process (specified through <varname>MAINPID=</varname>).
This information can be acquired through
- <citerefentry project='man-pages'><refentrytitle>name_to_handle_at</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- or <citerefentry project='man-pages'><refentrytitle>fstat</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>sd_pidfd_get_inode_id</refentrytitle><manvolnum>3</manvolnum></citerefentry>
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>
--- /dev/null
+<?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 <systemd/sd-daemon.h></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>
sd_device_get_sysattr_value_with_size;
sd_json_variant_type_from_string;
sd_json_variant_type_to_string;
+ sd_pidfd_get_inode_id;
sd_varlink_get_current_method;
sd_varlink_get_description;
sd_varlink_get_input_fd;
#include "io-util.h"
#include "iovec-util.h"
#include "log.h"
+#include "missing_magic.h"
#include "parse-util.h"
#include "path-util.h"
+#include "pidfd-util.h"
#include "process-util.h"
#include "socket-util.h"
#include "stat-util.h"
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) {
int r;
*/
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
error. Returns 0 if the system was not booted with systemd. Note