<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>
#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"
}
int pidfd_get_inode_id(int fd, uint64_t *ret) {
+ static bool file_handle_supported = true;
int r;
assert(fd >= 0);
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;
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) {