mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
pidfd-util: preferably acquire pidfd inode id through name_to_handle_at()
See rationales described in kernel commit:
b3caba8f7a
This commit is contained in:
committed by
Lennart Poettering
parent
cc524bc1fe
commit
9c039ef5ff
@@ -306,7 +306,8 @@
|
||||
|
||||
<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>fstat</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
<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>
|
||||
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>
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
#include "fileio.h"
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
#include "missing_fs.h"
|
||||
#include "missing_magic.h"
|
||||
#include "missing_threads.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "pidfd-util.h"
|
||||
@@ -226,6 +228,7 @@ int pidfd_get_cgroupid(int fd, uint64_t *ret) {
|
||||
}
|
||||
|
||||
int pidfd_get_inode_id(int fd, uint64_t *ret) {
|
||||
static bool file_handle_supported = true;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
@@ -236,6 +239,30 @@ int pidfd_get_inode_id(int fd, uint64_t *ret) {
|
||||
if (r == 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (file_handle_supported) {
|
||||
union {
|
||||
struct file_handle file_handle;
|
||||
uint8_t space[offsetof(struct file_handle, f_handle) + sizeof(uint64_t)];
|
||||
} fh = {
|
||||
.file_handle.handle_bytes = sizeof(uint64_t),
|
||||
.file_handle.handle_type = FILEID_KERNFS,
|
||||
};
|
||||
int mnt_id;
|
||||
|
||||
r = RET_NERRNO(name_to_handle_at(fd, "", &fh.file_handle, &mnt_id, AT_EMPTY_PATH));
|
||||
if (r >= 0) {
|
||||
if (ret)
|
||||
*ret = *(uint64_t*) fh.file_handle.f_handle;
|
||||
return 0;
|
||||
}
|
||||
assert(r != -EOVERFLOW);
|
||||
if (is_name_to_handle_at_fatal_error(r))
|
||||
return r;
|
||||
|
||||
file_handle_supported = false;
|
||||
}
|
||||
|
||||
#if SIZEOF_INO_T == 8
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
@@ -243,6 +270,16 @@ int pidfd_get_inode_id(int fd, uint64_t *ret) {
|
||||
if (ret)
|
||||
*ret = (uint64_t) st.st_ino;
|
||||
return 0;
|
||||
|
||||
#elif SIZEOF_INO_T == 4
|
||||
/* On 32-bit systems (where sizeof(ino_t) == 4), the inode id returned by fstat() cannot be used to
|
||||
* reliably identify the process, nor can we communicate the origin of the id with the clients.
|
||||
* Hence let's just refuse to acquire pidfdid through fstat() here. All clients shall also insist on
|
||||
* the 64-bit id from name_to_handle_at(). */
|
||||
return -EOPNOTSUPP;
|
||||
#else
|
||||
# error Unsupported ino_t size
|
||||
#endif
|
||||
}
|
||||
|
||||
int pidfd_get_inode_id_self_cached(uint64_t *ret) {
|
||||
|
||||
Reference in New Issue
Block a user