summaryrefslogtreecommitdiffstats
path: root/man2/open_by_handle_at.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/open_by_handle_at.2')
-rw-r--r--man2/open_by_handle_at.2787
1 files changed, 0 insertions, 787 deletions
diff --git a/man2/open_by_handle_at.2 b/man2/open_by_handle_at.2
deleted file mode 100644
index 26bb9c2..0000000
--- a/man2/open_by_handle_at.2
+++ /dev/null
@@ -1,787 +0,0 @@
-.\" Copyright (c) 2014 by Michael Kerrisk <mtk.manpages@gmail.com>
-.\"
-.\" SPDX-License-Identifier: Linux-man-pages-copyleft
-.\"
-.TH open_by_handle_at 2 2023-10-31 "Linux man-pages 6.7"
-.SH NAME
-name_to_handle_at, open_by_handle_at \- obtain handle
-for a pathname and open file via a handle
-.SH LIBRARY
-Standard C library
-.RI ( libc ", " \-lc )
-.SH SYNOPSIS
-.nf
-.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
-.B #include <fcntl.h>
-.P
-.BI "int name_to_handle_at(int " dirfd ", const char *" pathname ,
-.BI " struct file_handle *" handle ,
-.BI " int *" mount_id ", int " flags );
-.BI "int open_by_handle_at(int " mount_fd ", struct file_handle *" handle ,
-.BI " int " flags );
-.fi
-.SH DESCRIPTION
-The
-.BR name_to_handle_at ()
-and
-.BR open_by_handle_at ()
-system calls split the functionality of
-.BR openat (2)
-into two parts:
-.BR name_to_handle_at ()
-returns an opaque handle that corresponds to a specified file;
-.BR open_by_handle_at ()
-opens the file corresponding to a handle returned by a previous call to
-.BR name_to_handle_at ()
-and returns an open file descriptor.
-.\"
-.\"
-.SS name_to_handle_at()
-The
-.BR name_to_handle_at ()
-system call returns a file handle and a mount ID corresponding to
-the file specified by the
-.I dirfd
-and
-.I pathname
-arguments.
-The file handle is returned via the argument
-.IR handle ,
-which is a pointer to a structure of the following form:
-.P
-.in +4n
-.EX
-struct file_handle {
- unsigned int handle_bytes; /* Size of f_handle [in, out] */
- int handle_type; /* Handle type [out] */
- unsigned char f_handle[0]; /* File identifier (sized by
- caller) [out] */
-};
-.EE
-.in
-.P
-It is the caller's responsibility to allocate the structure
-with a size large enough to hold the handle returned in
-.IR f_handle .
-Before the call, the
-.I handle_bytes
-field should be initialized to contain the allocated size for
-.IR f_handle .
-(The constant
-.BR MAX_HANDLE_SZ ,
-defined in
-.IR <fcntl.h> ,
-specifies the maximum expected size for a file handle.
-It is not a
-guaranteed upper limit as future filesystems may require more space.)
-Upon successful return, the
-.I handle_bytes
-field is updated to contain the number of bytes actually written to
-.IR f_handle .
-.P
-The caller can discover the required size for the
-.I file_handle
-structure by making a call in which
-.I handle\->handle_bytes
-is zero;
-in this case, the call fails with the error
-.B EOVERFLOW
-and
-.I handle\->handle_bytes
-is set to indicate the required size;
-the caller can then use this information to allocate a structure
-of the correct size (see EXAMPLES below).
-Some care is needed here as
-.B EOVERFLOW
-can also indicate that no file handle is available for this particular
-name in a filesystem which does normally support file-handle lookup.
-This case can be detected when the
-.B EOVERFLOW
-error is returned without
-.I handle_bytes
-being increased.
-.P
-Other than the use of the
-.I handle_bytes
-field, the caller should treat the
-.I file_handle
-structure as an opaque data type: the
-.I handle_type
-and
-.I f_handle
-fields can be used in a subsequent call to
-.BR open_by_handle_at ().
-The caller can also use the opaque
-.I file_handle
-to compare the identity of filesystem objects
-that were queried at different times and possibly
-at different paths.
-The
-.BR fanotify (7)
-subsystem can report events
-with an information record containing a
-.I file_handle
-to identify the filesystem object.
-.P
-The
-.I flags
-argument is a bit mask constructed by ORing together zero or more of
-.BR AT_HANDLE_FID ,
-.BR AT_EMPTY_PATH ,
-and
-.BR AT_SYMLINK_FOLLOW ,
-described below.
-.P
-When
-.I flags
-contain the
-.BR AT_HANDLE_FID " (since Linux 6.5)"
-.\" commit 96b2b072ee62be8ae68c8ecf14854c4d0505a8f8
-flag, the caller indicates that the returned
-.I file_handle
-is needed to identify the filesystem object,
-and not for opening the file later,
-so it should be expected that a subsequent call to
-.BR open_by_handle_at ()
-with the returned
-.I file_handle
-may fail.
-.P
-Together, the
-.I pathname
-and
-.I dirfd
-arguments identify the file for which a handle is to be obtained.
-There are four distinct cases:
-.IP \[bu] 3
-If
-.I pathname
-is a nonempty string containing an absolute pathname,
-then a handle is returned for the file referred to by that pathname.
-In this case,
-.I dirfd
-is ignored.
-.IP \[bu]
-If
-.I pathname
-is a nonempty string containing a relative pathname and
-.I dirfd
-has the special value
-.BR AT_FDCWD ,
-then
-.I pathname
-is interpreted relative to the current working directory of the caller,
-and a handle is returned for the file to which it refers.
-.IP \[bu]
-If
-.I pathname
-is a nonempty string containing a relative pathname and
-.I dirfd
-is a file descriptor referring to a directory, then
-.I pathname
-is interpreted relative to the directory referred to by
-.IR dirfd ,
-and a handle is returned for the file to which it refers.
-(See
-.BR openat (2)
-for an explanation of why "directory file descriptors" are useful.)
-.IP \[bu]
-If
-.I pathname
-is an empty string and
-.I flags
-specifies the value
-.BR AT_EMPTY_PATH ,
-then
-.I dirfd
-can be an open file descriptor referring to any type of file,
-or
-.BR AT_FDCWD ,
-meaning the current working directory,
-and a handle is returned for the file to which it refers.
-.P
-The
-.I mount_id
-argument returns an identifier for the filesystem
-mount that corresponds to
-.IR pathname .
-This corresponds to the first field in one of the records in
-.IR /proc/self/mountinfo .
-Opening the pathname in the fifth field of that record yields a file
-descriptor for the mount point;
-that file descriptor can be used in a subsequent call to
-.BR open_by_handle_at ().
-.I mount_id
-is returned both for a successful call and for a call that results
-in the error
-.BR EOVERFLOW .
-.P
-By default,
-.BR name_to_handle_at ()
-does not dereference
-.I pathname
-if it is a symbolic link, and thus returns a handle for the link itself.
-If
-.B AT_SYMLINK_FOLLOW
-is specified in
-.IR flags ,
-.I pathname
-is dereferenced if it is a symbolic link
-(so that the call returns a handle for the file referred to by the link).
-.P
-.BR name_to_handle_at ()
-does not trigger a mount when the final component of the pathname is an
-automount point.
-When a filesystem supports both file handles and
-automount points, a
-.BR name_to_handle_at ()
-call on an automount point will return with error
-.B EOVERFLOW
-without having increased
-.IR handle_bytes .
-This can happen since Linux 4.13
-.\" commit 20fa19027286983ab2734b5910c4a687436e0c31
-with NFS when accessing a directory
-which is on a separate filesystem on the server.
-In this case, the automount can be triggered by adding a "/" to the end
-of the pathname.
-.SS open_by_handle_at()
-The
-.BR open_by_handle_at ()
-system call opens the file referred to by
-.IR handle ,
-a file handle returned by a previous call to
-.BR name_to_handle_at ().
-.P
-The
-.I mount_fd
-argument is a file descriptor for any object (file, directory, etc.)
-in the mounted filesystem with respect to which
-.I handle
-should be interpreted.
-The special value
-.B AT_FDCWD
-can be specified, meaning the current working directory of the caller.
-.P
-The
-.I flags
-argument
-is as for
-.BR open (2).
-If
-.I handle
-refers to a symbolic link, the caller must specify the
-.B O_PATH
-flag, and the symbolic link is not dereferenced; the
-.B O_NOFOLLOW
-flag, if specified, is ignored.
-.P
-The caller must have the
-.B CAP_DAC_READ_SEARCH
-capability to invoke
-.BR open_by_handle_at ().
-.SH RETURN VALUE
-On success,
-.BR name_to_handle_at ()
-returns 0,
-and
-.BR open_by_handle_at ()
-returns a file descriptor (a nonnegative integer).
-.P
-In the event of an error, both system calls return \-1 and set
-.I errno
-to indicate the error.
-.SH ERRORS
-.BR name_to_handle_at ()
-and
-.BR open_by_handle_at ()
-can fail for the same errors as
-.BR openat (2).
-In addition, they can fail with the errors noted below.
-.P
-.BR name_to_handle_at ()
-can fail with the following errors:
-.TP
-.B EFAULT
-.IR pathname ,
-.IR mount_id ,
-or
-.I handle
-points outside your accessible address space.
-.TP
-.B EINVAL
-.I flags
-includes an invalid bit value.
-.TP
-.B EINVAL
-.I handle\->handle_bytes
-is greater than
-.BR MAX_HANDLE_SZ .
-.TP
-.B ENOENT
-.I pathname
-is an empty string, but
-.B AT_EMPTY_PATH
-was not specified in
-.IR flags .
-.TP
-.B ENOTDIR
-The file descriptor supplied in
-.I dirfd
-does not refer to a directory,
-and it is not the case that both
-.I flags
-includes
-.B AT_EMPTY_PATH
-and
-.I pathname
-is an empty string.
-.TP
-.B EOPNOTSUPP
-The filesystem does not support decoding of a pathname to a file handle.
-.TP
-.B EOVERFLOW
-The
-.I handle\->handle_bytes
-value passed into the call was too small.
-When this error occurs,
-.I handle\->handle_bytes
-is updated to indicate the required size for the handle.
-.\"
-.\"
-.P
-.BR open_by_handle_at ()
-can fail with the following errors:
-.TP
-.B EBADF
-.I mount_fd
-is not an open file descriptor.
-.TP
-.B EBADF
-.I pathname
-is relative but
-.I dirfd
-is neither
-.B AT_FDCWD
-nor a valid file descriptor.
-.TP
-.B EFAULT
-.I handle
-points outside your accessible address space.
-.TP
-.B EINVAL
-.I handle\->handle_bytes
-is greater than
-.B MAX_HANDLE_SZ
-or is equal to zero.
-.TP
-.B ELOOP
-.I handle
-refers to a symbolic link, but
-.B O_PATH
-was not specified in
-.IR flags .
-.TP
-.B EPERM
-The caller does not have the
-.B CAP_DAC_READ_SEARCH
-capability.
-.TP
-.B ESTALE
-The specified
-.I handle
-is not valid for opening a file.
-This error will occur if, for example, the file has been deleted.
-This error can also occur if the
-.I handle
-was acquired using the
-.B AT_HANDLE_FID
-flag and the filesystem does not support
-.BR open_by_handle_at ().
-.SH VERSIONS
-FreeBSD has a broadly similar pair of system calls in the form of
-.BR getfh ()
-and
-.BR openfh ().
-.SH STANDARDS
-Linux.
-.SH HISTORY
-Linux 2.6.39,
-glibc 2.14.
-.SH NOTES
-A file handle can be generated in one process using
-.BR name_to_handle_at ()
-and later used in a different process that calls
-.BR open_by_handle_at ().
-.P
-Some filesystem don't support the translation of pathnames to
-file handles, for example,
-.IR /proc ,
-.IR /sys ,
-and various network filesystems.
-Some filesystems support the translation of pathnames to
-file handles, but do not support using those file handles in
-.BR open_by_handle_at ().
-.P
-A file handle may become invalid ("stale") if a file is deleted,
-or for other filesystem-specific reasons.
-Invalid handles are notified by an
-.B ESTALE
-error from
-.BR open_by_handle_at ().
-.P
-These system calls are designed for use by user-space file servers.
-For example, a user-space NFS server might generate a file handle
-and pass it to an NFS client.
-Later, when the client wants to open the file,
-it could pass the handle back to the server.
-.\" https://lwn.net/Articles/375888/
-.\" "Open by handle" - Jonathan Corbet, 2010-02-23
-This sort of functionality allows a user-space file server to operate in
-a stateless fashion with respect to the files it serves.
-.P
-If
-.I pathname
-refers to a symbolic link and
-.I flags
-does not specify
-.BR AT_SYMLINK_FOLLOW ,
-then
-.BR name_to_handle_at ()
-returns a handle for the link (rather than the file to which it refers).
-.\" commit bcda76524cd1fa32af748536f27f674a13e56700
-The process receiving the handle can later perform operations
-on the symbolic link by converting the handle to a file descriptor using
-.BR open_by_handle_at ()
-with the
-.B O_PATH
-flag, and then passing the file descriptor as the
-.I dirfd
-argument in system calls such as
-.BR readlinkat (2)
-and
-.BR fchownat (2).
-.SS Obtaining a persistent filesystem ID
-The mount IDs in
-.I /proc/self/mountinfo
-can be reused as filesystems are unmounted and mounted.
-Therefore, the mount ID returned by
-.BR name_to_handle_at ()
-(in
-.IR *mount_id )
-should not be treated as a persistent identifier
-for the corresponding mounted filesystem.
-However, an application can use the information in the
-.I mountinfo
-record that corresponds to the mount ID
-to derive a persistent identifier.
-.P
-For example, one can use the device name in the fifth field of the
-.I mountinfo
-record to search for the corresponding device UUID via the symbolic links in
-.IR /dev/disks/by\-uuid .
-(A more comfortable way of obtaining the UUID is to use the
-.\" e.g., http://stackoverflow.com/questions/6748429/using-libblkid-to-find-uuid-of-a-partition
-.BR libblkid (3)
-library.)
-That process can then be reversed,
-using the UUID to look up the device name,
-and then obtaining the corresponding mount point,
-in order to produce the
-.I mount_fd
-argument used by
-.BR open_by_handle_at ().
-.SH EXAMPLES
-The two programs below demonstrate the use of
-.BR name_to_handle_at ()
-and
-.BR open_by_handle_at ().
-The first program
-.RI ( t_name_to_handle_at.c )
-uses
-.BR name_to_handle_at ()
-to obtain the file handle and mount ID
-for the file specified in its command-line argument;
-the handle and mount ID are written to standard output.
-.P
-The second program
-.RI ( t_open_by_handle_at.c )
-reads a mount ID and file handle from standard input.
-The program then employs
-.BR open_by_handle_at ()
-to open the file using that handle.
-If an optional command-line argument is supplied, then the
-.I mount_fd
-argument for
-.BR open_by_handle_at ()
-is obtained by opening the directory named in that argument.
-Otherwise,
-.I mount_fd
-is obtained by scanning
-.I /proc/self/mountinfo
-to find a record whose mount ID matches the mount ID
-read from standard input,
-and the mount directory specified in that record is opened.
-(These programs do not deal with the fact that mount IDs are not persistent.)
-.P
-The following shell session demonstrates the use of these two programs:
-.P
-.in +4n
-.EX
-$ \fBecho \[aq]Can you please think about it?\[aq] > cecilia.txt\fP
-$ \fB./t_name_to_handle_at cecilia.txt > fh\fP
-$ \fB./t_open_by_handle_at < fh\fP
-open_by_handle_at: Operation not permitted
-$ \fBsudo ./t_open_by_handle_at < fh\fP # Need CAP_SYS_ADMIN
-Read 31 bytes
-$ \fBrm cecilia.txt\fP
-.EE
-.in
-.P
-Now we delete and (quickly) re-create the file so that
-it has the same content and (by chance) the same inode.
-Nevertheless,
-.BR open_by_handle_at ()
-.\" Christoph Hellwig: That's why the file handles contain a generation
-.\" counter that gets incremented in this case.
-recognizes that the original file referred to by the file handle
-no longer exists.
-.P
-.in +4n
-.EX
-$ \fBstat \-\-printf="%i\en" cecilia.txt\fP # Display inode number
-4072121
-$ \fBrm cecilia.txt\fP
-$ \fBecho \[aq]Can you please think about it?\[aq] > cecilia.txt\fP
-$ \fBstat \-\-printf="%i\en" cecilia.txt\fP # Check inode number
-4072121
-$ \fBsudo ./t_open_by_handle_at < fh\fP
-open_by_handle_at: Stale NFS file handle
-.EE
-.in
-.SS Program source: t_name_to_handle_at.c
-\&
-.\" SRC BEGIN (t_name_to_handle_at.c)
-.EX
-#define _GNU_SOURCE
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-\&
-int
-main(int argc, char *argv[])
-{
- int mount_id, fhsize, flags, dirfd;
- char *pathname;
- struct file_handle *fhp;
-\&
- if (argc != 2) {
- fprintf(stderr, "Usage: %s pathname\en", argv[0]);
- exit(EXIT_FAILURE);
- }
-\&
- pathname = argv[1];
-\&
- /* Allocate file_handle structure. */
-\&
- fhsize = sizeof(*fhp);
- fhp = malloc(fhsize);
- if (fhp == NULL)
- err(EXIT_FAILURE, "malloc");
-\&
- /* Make an initial call to name_to_handle_at() to discover
- the size required for file handle. */
-\&
- dirfd = AT_FDCWD; /* For name_to_handle_at() calls */
- flags = 0; /* For name_to_handle_at() calls */
- fhp\->handle_bytes = 0;
- if (name_to_handle_at(dirfd, pathname, fhp,
- &mount_id, flags) != \-1
- || errno != EOVERFLOW)
- {
- fprintf(stderr, "Unexpected result from name_to_handle_at()\en");
- exit(EXIT_FAILURE);
- }
-\&
- /* Reallocate file_handle structure with correct size. */
-\&
- fhsize = sizeof(*fhp) + fhp\->handle_bytes;
- fhp = realloc(fhp, fhsize); /* Copies fhp\->handle_bytes */
- if (fhp == NULL)
- err(EXIT_FAILURE, "realloc");
-\&
- /* Get file handle from pathname supplied on command line. */
-\&
- if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
- err(EXIT_FAILURE, "name_to_handle_at");
-\&
- /* Write mount ID, file handle size, and file handle to stdout,
- for later reuse by t_open_by_handle_at.c. */
-\&
- printf("%d\en", mount_id);
- printf("%u %d ", fhp\->handle_bytes, fhp\->handle_type);
- for (size_t j = 0; j < fhp\->handle_bytes; j++)
- printf(" %02x", fhp\->f_handle[j]);
- printf("\en");
-\&
- exit(EXIT_SUCCESS);
-}
-.EE
-.\" SRC END
-.SS Program source: t_open_by_handle_at.c
-\&
-.\" SRC BEGIN (t_open_by_handle_at.c)
-.EX
-#define _GNU_SOURCE
-#include <err.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-\&
-/* Scan /proc/self/mountinfo to find the line whose mount ID matches
- \[aq]mount_id\[aq]. (An easier way to do this is to install and use the
- \[aq]libmount\[aq] library provided by the \[aq]util\-linux\[aq] project.)
- Open the corresponding mount path and return the resulting file
- descriptor. */
-\&
-static int
-open_mount_path_by_id(int mount_id)
-{
- int mi_mount_id, found;
- char mount_path[PATH_MAX];
- char *linep;
- FILE *fp;
- size_t lsize;
- ssize_t nread;
-\&
- fp = fopen("/proc/self/mountinfo", "r");
- if (fp == NULL)
- err(EXIT_FAILURE, "fopen");
-\&
- found = 0;
- linep = NULL;
- while (!found) {
- nread = getline(&linep, &lsize, fp);
- if (nread == \-1)
- break;
-\&
- nread = sscanf(linep, "%d %*d %*s %*s %s",
- &mi_mount_id, mount_path);
- if (nread != 2) {
- fprintf(stderr, "Bad sscanf()\en");
- exit(EXIT_FAILURE);
- }
-\&
- if (mi_mount_id == mount_id)
- found = 1;
- }
- free(linep);
-\&
- fclose(fp);
-\&
- if (!found) {
- fprintf(stderr, "Could not find mount point\en");
- exit(EXIT_FAILURE);
- }
-\&
- return open(mount_path, O_RDONLY);
-}
-\&
-int
-main(int argc, char *argv[])
-{
- int mount_id, fd, mount_fd, handle_bytes;
- char buf[1000];
-#define LINE_SIZE 100
- char line1[LINE_SIZE], line2[LINE_SIZE];
- char *nextp;
- ssize_t nread;
- struct file_handle *fhp;
-\&
- if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
- fprintf(stderr, "Usage: %s [mount\-path]\en", argv[0]);
- exit(EXIT_FAILURE);
- }
-\&
- /* Standard input contains mount ID and file handle information:
-\&
- Line 1: <mount_id>
- Line 2: <handle_bytes> <handle_type> <bytes of handle in hex>
- */
-\&
- if (fgets(line1, sizeof(line1), stdin) == NULL ||
- fgets(line2, sizeof(line2), stdin) == NULL)
- {
- fprintf(stderr, "Missing mount_id / file handle\en");
- exit(EXIT_FAILURE);
- }
-\&
- mount_id = atoi(line1);
-\&
- handle_bytes = strtoul(line2, &nextp, 0);
-\&
- /* Given handle_bytes, we can now allocate file_handle structure. */
-\&
- fhp = malloc(sizeof(*fhp) + handle_bytes);
- if (fhp == NULL)
- err(EXIT_FAILURE, "malloc");
-\&
- fhp\->handle_bytes = handle_bytes;
-\&
- fhp\->handle_type = strtoul(nextp, &nextp, 0);
-\&
- for (size_t j = 0; j < fhp\->handle_bytes; j++)
- fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
-\&
- /* Obtain file descriptor for mount point, either by opening
- the pathname specified on the command line, or by scanning
- /proc/self/mounts to find a mount that matches the \[aq]mount_id\[aq]
- that we received from stdin. */
-\&
- if (argc > 1)
- mount_fd = open(argv[1], O_RDONLY);
- else
- mount_fd = open_mount_path_by_id(mount_id);
-\&
- if (mount_fd == \-1)
- err(EXIT_FAILURE, "opening mount fd");
-\&
- /* Open file using handle and mount point. */
-\&
- fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
- if (fd == \-1)
- err(EXIT_FAILURE, "open_by_handle_at");
-\&
- /* Try reading a few bytes from the file. */
-\&
- nread = read(fd, buf, sizeof(buf));
- if (nread == \-1)
- err(EXIT_FAILURE, "read");
-\&
- printf("Read %zd bytes\en", nread);
-\&
- exit(EXIT_SUCCESS);
-}
-.EE
-.\" SRC END
-.SH SEE ALSO
-.BR open (2),
-.BR libblkid (3),
-.BR blkid (8),
-.BR findfs (8),
-.BR mount (8)
-.P
-The
-.I libblkid
-and
-.I libmount
-documentation in the latest
-.I util\-linux
-release at
-.UR https://www.kernel.org/pub/linux/utils/util\-linux/
-.UE