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:
5
NEWS
5
NEWS
@@ -1208,6 +1208,11 @@ CHANGES WITH 258 in spe:
|
||||
* 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:
|
||||
|
@@ -882,6 +882,7 @@ manpages = [
|
||||
'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'],
|
||||
|
@@ -55,10 +55,10 @@
|
||||
<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 */
|
||||
@@ -104,6 +104,7 @@
|
||||
<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>
|
||||
|
@@ -306,8 +306,7 @@
|
||||
|
||||
<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>
|
||||
|
||||
|
107
man/sd_pidfd_get_inode_id.xml
Normal file
107
man/sd_pidfd_get_inode_id.xml
Normal 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 <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>
|
@@ -1067,6 +1067,7 @@ global:
|
||||
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;
|
||||
|
@@ -18,8 +18,10 @@
|
||||
#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"
|
||||
@@ -752,6 +754,27 @@ finish:
|
||||
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;
|
||||
|
||||
|
@@ -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_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
|
||||
|
Reference in New Issue
Block a user