1 .\" Copyright (c) 2014 by Michael Kerrisk <mtk.manpages@gmail.com>
3 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .TH OPEN_BY_HANDLE_AT 2 2022-09-17 "Linux man-pages (unreleased)"
7 name_to_handle_at, open_by_handle_at \- obtain handle
8 for a pathname and open file via a handle
11 .RI ( libc ", " \-lc )
14 .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
17 .BI "int name_to_handle_at(int " dirfd ", const char *" pathname ,
18 .BI " struct file_handle *" handle ,
19 .BI " int *" mount_id ", int " flags );
20 .BI "int open_by_handle_at(int " mount_fd ", struct file_handle *" handle ,
25 .BR name_to_handle_at ()
27 .BR open_by_handle_at ()
28 system calls split the functionality of
31 .BR name_to_handle_at ()
32 returns an opaque handle that corresponds to a specified file;
33 .BR open_by_handle_at ()
34 opens the file corresponding to a handle returned by a previous call to
35 .BR name_to_handle_at ()
36 and returns an open file descriptor.
39 .SS name_to_handle_at()
41 .BR name_to_handle_at ()
42 system call returns a file handle and a mount ID corresponding to
43 the file specified by the
48 The file handle is returned via the argument
50 which is a pointer to a structure of the following form:
55 unsigned int handle_bytes; /* Size of f_handle [in, out] */
56 int handle_type; /* Handle type [out] */
57 unsigned char f_handle[0]; /* File identifier (sized by
63 It is the caller's responsibility to allocate the structure
64 with a size large enough to hold the handle returned in
68 field should be initialized to contain the allocated size for
74 specifies the maximum expected size for a file handle.
76 guaranteed upper limit as future filesystems may require more space.)
77 Upon successful return, the
79 field is updated to contain the number of bytes actually written to
82 The caller can discover the required size for the
84 structure by making a call in which
85 .I handle\->handle_bytes
87 in this case, the call fails with the error
90 .I handle\->handle_bytes
91 is set to indicate the required size;
92 the caller can then use this information to allocate a structure
93 of the correct size (see EXAMPLES below).
94 Some care is needed here as
96 can also indicate that no file handle is available for this particular
97 name in a filesystem which does normally support file-handle lookup.
98 This case can be detected when the
100 error is returned without
104 Other than the use of the
106 field, the caller should treat the
108 structure as an opaque data type: the
112 fields are needed only by a subsequent call to
113 .BR open_by_handle_at ().
117 argument is a bit mask constructed by ORing together zero or more of
120 .BR AT_SYMLINK_FOLLOW ,
127 arguments identify the file for which a handle is to be obtained.
128 There are four distinct cases:
132 is a nonempty string containing an absolute pathname,
133 then a handle is returned for the file referred to by that pathname.
140 is a nonempty string containing a relative pathname and
142 has the special value
146 is interpreted relative to the current working directory of the caller,
147 and a handle is returned for the file to which it refers.
151 is a nonempty string containing a relative pathname and
153 is a file descriptor referring to a directory, then
155 is interpreted relative to the directory referred to by
157 and a handle is returned for the file to which it refers.
160 for an explanation of why "directory file descriptors" are useful.)
164 is an empty string and
170 can be an open file descriptor referring to any type of file,
173 meaning the current working directory,
174 and a handle is returned for the file to which it refers.
178 argument returns an identifier for the filesystem
179 mount that corresponds to
181 This corresponds to the first field in one of the records in
182 .IR /proc/self/mountinfo .
183 Opening the pathname in the fifth field of that record yields a file
184 descriptor for the mount point;
185 that file descriptor can be used in a subsequent call to
186 .BR open_by_handle_at ().
188 is returned both for a successful call and for a call that results
193 .BR name_to_handle_at ()
196 if it is a symbolic link, and thus returns a handle for the link itself.
202 is dereferenced if it is a symbolic link
203 (so that the call returns a handle for the file referred to by the link).
205 .BR name_to_handle_at ()
206 does not trigger a mount when the final component of the pathname is an
208 When a filesystem supports both file handles and
210 .BR name_to_handle_at ()
211 call on an automount point will return with error
213 without having increased
215 This can happen since Linux 4.13
216 .\" commit 20fa19027286983ab2734b5910c4a687436e0c31
217 with NFS when accessing a directory
218 which is on a separate filesystem on the server.
219 In this case, the automount can be triggered by adding a "/" to the end
221 .SS open_by_handle_at()
223 .BR open_by_handle_at ()
224 system call opens the file referred to by
226 a file handle returned by a previous call to
227 .BR name_to_handle_at ().
231 argument is a file descriptor for any object (file, directory, etc.)
232 in the mounted filesystem with respect to which
234 should be interpreted.
237 can be specified, meaning the current working directory of the caller.
246 refers to a symbolic link, the caller must specify the
248 flag, and the symbolic link is not dereferenced; the
250 flag, if specified, is ignored.
252 The caller must have the
253 .B CAP_DAC_READ_SEARCH
255 .BR open_by_handle_at ().
258 .BR name_to_handle_at ()
261 .BR open_by_handle_at ()
262 returns a file descriptor (a nonnegative integer).
264 In the event of an error, both system calls return \-1 and set
266 to indicate the error.
268 .BR name_to_handle_at ()
270 .BR open_by_handle_at ()
271 can fail for the same errors as
273 In addition, they can fail with the errors noted below.
275 .BR name_to_handle_at ()
276 can fail with the following errors:
283 points outside your accessible address space.
287 includes an invalid bit value.
290 .I handle\->handle_bytes
296 is an empty string, but
302 The file descriptor supplied in
304 does not refer to a directory,
305 and it is not the case that both
314 The filesystem does not support decoding of a pathname to a file handle.
318 .I handle\->handle_bytes
319 value passed into the call was too small.
320 When this error occurs,
321 .I handle\->handle_bytes
322 is updated to indicate the required size for the handle.
326 .BR open_by_handle_at ()
327 can fail with the following errors:
331 is not an open file descriptor.
339 nor a valid file descriptor.
343 points outside your accessible address space.
346 .I handle\->handle_bytes
353 refers to a symbolic link, but
359 The caller does not have the
360 .B CAP_DAC_READ_SEARCH
367 This error will occur if, for example, the file has been deleted.
369 These system calls first appeared in Linux 2.6.39.
370 Library support is provided in glibc since version 2.14.
372 These system calls are nonstandard Linux extensions.
374 FreeBSD has a broadly similar pair of system calls in the form of
379 A file handle can be generated in one process using
380 .BR name_to_handle_at ()
381 and later used in a different process that calls
382 .BR open_by_handle_at ().
384 Some filesystem don't support the translation of pathnames to
385 file handles, for example,
388 and various network filesystems.
390 A file handle may become invalid ("stale") if a file is deleted,
391 or for other filesystem-specific reasons.
392 Invalid handles are notified by an
395 .BR open_by_handle_at ().
397 These system calls are designed for use by user-space file servers.
398 For example, a user-space NFS server might generate a file handle
399 and pass it to an NFS client.
400 Later, when the client wants to open the file,
401 it could pass the handle back to the server.
402 .\" https://lwn.net/Articles/375888/
403 .\" "Open by handle" - Jonathan Corbet, 2010-02-23
404 This sort of functionality allows a user-space file server to operate in
405 a stateless fashion with respect to the files it serves.
409 refers to a symbolic link and
412 .BR AT_SYMLINK_FOLLOW ,
414 .BR name_to_handle_at ()
415 returns a handle for the link (rather than the file to which it refers).
416 .\" commit bcda76524cd1fa32af748536f27f674a13e56700
417 The process receiving the handle can later perform operations
418 on the symbolic link by converting the handle to a file descriptor using
419 .BR open_by_handle_at ()
422 flag, and then passing the file descriptor as the
424 argument in system calls such as
428 .SS Obtaining a persistent filesystem ID
430 .I /proc/self/mountinfo
431 can be reused as filesystems are unmounted and mounted.
432 Therefore, the mount ID returned by
433 .BR name_to_handle_at ()
436 should not be treated as a persistent identifier
437 for the corresponding mounted filesystem.
438 However, an application can use the information in the
440 record that corresponds to the mount ID
441 to derive a persistent identifier.
443 For example, one can use the device name in the fifth field of the
445 record to search for the corresponding device UUID via the symbolic links in
446 .IR /dev/disks/by\-uuid .
447 (A more comfortable way of obtaining the UUID is to use the
448 .\" e.g., http://stackoverflow.com/questions/6748429/using-libblkid-to-find-uuid-of-a-partition
451 That process can then be reversed,
452 using the UUID to look up the device name,
453 and then obtaining the corresponding mount point,
454 in order to produce the
457 .BR open_by_handle_at ().
459 The two programs below demonstrate the use of
460 .BR name_to_handle_at ()
462 .BR open_by_handle_at ().
464 .RI ( t_name_to_handle_at.c )
466 .BR name_to_handle_at ()
467 to obtain the file handle and mount ID
468 for the file specified in its command-line argument;
469 the handle and mount ID are written to standard output.
472 .RI ( t_open_by_handle_at.c )
473 reads a mount ID and file handle from standard input.
474 The program then employs
475 .BR open_by_handle_at ()
476 to open the file using that handle.
477 If an optional command-line argument is supplied, then the
480 .BR open_by_handle_at ()
481 is obtained by opening the directory named in that argument.
484 is obtained by scanning
485 .I /proc/self/mountinfo
486 to find a record whose mount ID matches the mount ID
487 read from standard input,
488 and the mount directory specified in that record is opened.
489 (These programs do not deal with the fact that mount IDs are not persistent.)
491 The following shell session demonstrates the use of these two programs:
495 $ \fBecho \(aqCan you please think about it?\(aq > cecilia.txt\fP
496 $ \fB./t_name_to_handle_at cecilia.txt > fh\fP
497 $ \fB./t_open_by_handle_at < fh\fP
498 open_by_handle_at: Operation not permitted
499 $ \fBsudo ./t_open_by_handle_at < fh\fP # Need CAP_SYS_ADMIN
501 $ \fBrm cecilia.txt\fP
505 Now we delete and (quickly) re-create the file so that
506 it has the same content and (by chance) the same inode.
508 .BR open_by_handle_at ()
509 .\" Christoph Hellwig: That's why the file handles contain a generation
510 .\" counter that gets incremented in this case.
511 recognizes that the original file referred to by the file handle
516 $ \fBstat \-\-printf="%i\en" cecilia.txt\fP # Display inode number
518 $ \fBrm cecilia.txt\fP
519 $ \fBecho \(aqCan you please think about it?\(aq > cecilia.txt\fP
520 $ \fBstat \-\-printf="%i\en" cecilia.txt\fP # Check inode number
522 $ \fBsudo ./t_open_by_handle_at < fh\fP
523 open_by_handle_at: Stale NFS file handle
526 .SS Program source: t_name_to_handle_at.c
528 .\" SRC BEGIN (t_name_to_handle_at.c)
538 main(int argc, char *argv[])
540 int mount_id, fhsize, flags, dirfd;
542 struct file_handle *fhp;
545 fprintf(stderr, "Usage: %s pathname\en", argv[0]);
551 /* Allocate file_handle structure. */
553 fhsize = sizeof(*fhp);
554 fhp = malloc(fhsize);
556 err(EXIT_FAILURE, "malloc");
558 /* Make an initial call to name_to_handle_at() to discover
559 the size required for file handle. */
561 dirfd = AT_FDCWD; /* For name_to_handle_at() calls */
562 flags = 0; /* For name_to_handle_at() calls */
563 fhp\->handle_bytes = 0;
564 if (name_to_handle_at(dirfd, pathname, fhp,
565 &mount_id, flags) != \-1
566 || errno != EOVERFLOW)
568 fprintf(stderr, "Unexpected result from name_to_handle_at()\en");
572 /* Reallocate file_handle structure with correct size. */
574 fhsize = sizeof(*fhp) + fhp\->handle_bytes;
575 fhp = realloc(fhp, fhsize); /* Copies fhp\->handle_bytes */
577 err(EXIT_FAILURE, "realloc");
579 /* Get file handle from pathname supplied on command line. */
581 if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
582 err(EXIT_FAILURE, "name_to_handle_at");
584 /* Write mount ID, file handle size, and file handle to stdout,
585 for later reuse by t_open_by_handle_at.c. */
587 printf("%d\en", mount_id);
588 printf("%u %d ", fhp\->handle_bytes, fhp\->handle_type);
589 for (size_t j = 0; j < fhp\->handle_bytes; j++)
590 printf(" %02x", fhp\->f_handle[j]);
597 .SS Program source: t_open_by_handle_at.c
599 .\" SRC BEGIN (t_open_by_handle_at.c)
610 /* Scan /proc/self/mountinfo to find the line whose mount ID matches
611 \(aqmount_id\(aq. (An easier way to do this is to install and use the
612 \(aqlibmount\(aq library provided by the \(aqutil\-linux\(aq project.)
613 Open the corresponding mount path and return the resulting file
617 open_mount_path_by_id(int mount_id)
619 int mi_mount_id, found;
620 char mount_path[PATH_MAX];
626 fp = fopen("/proc/self/mountinfo", "r");
628 err(EXIT_FAILURE, "fopen");
633 nread = getline(&linep, &lsize, fp);
637 nread = sscanf(linep, "%d %*d %*s %*s %s",
638 &mi_mount_id, mount_path);
640 fprintf(stderr, "Bad sscanf()\en");
644 if (mi_mount_id == mount_id)
652 fprintf(stderr, "Could not find mount point\en");
656 return open(mount_path, O_RDONLY);
660 main(int argc, char *argv[])
662 int mount_id, fd, mount_fd, handle_bytes;
664 #define LINE_SIZE 100
665 char line1[LINE_SIZE], line2[LINE_SIZE];
668 struct file_handle *fhp;
670 if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
671 fprintf(stderr, "Usage: %s [mount\-path]\en", argv[0]);
675 /* Standard input contains mount ID and file handle information:
678 Line 2: <handle_bytes> <handle_type> <bytes of handle in hex>
681 if (fgets(line1, sizeof(line1), stdin) == NULL ||
682 fgets(line2, sizeof(line2), stdin) == NULL)
684 fprintf(stderr, "Missing mount_id / file handle\en");
688 mount_id = atoi(line1);
690 handle_bytes = strtoul(line2, &nextp, 0);
692 /* Given handle_bytes, we can now allocate file_handle structure. */
694 fhp = malloc(sizeof(*fhp) + handle_bytes);
696 err(EXIT_FAILURE, "malloc");
698 fhp\->handle_bytes = handle_bytes;
700 fhp\->handle_type = strtoul(nextp, &nextp, 0);
702 for (size_t j = 0; j < fhp\->handle_bytes; j++)
703 fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
705 /* Obtain file descriptor for mount point, either by opening
706 the pathname specified on the command line, or by scanning
707 /proc/self/mounts to find a mount that matches the \(aqmount_id\(aq
708 that we received from stdin. */
711 mount_fd = open(argv[1], O_RDONLY);
713 mount_fd = open_mount_path_by_id(mount_id);
716 err(EXIT_FAILURE, "opening mount fd");
718 /* Open file using handle and mount point. */
720 fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
722 err(EXIT_FAILURE, "open_by_handle_at");
724 /* Try reading a few bytes from the file. */
726 nread = read(fd, buf, sizeof(buf));
728 err(EXIT_FAILURE, "read");
730 printf("Read %zd bytes\en", nread);
747 documentation in the latest
750 .UR https://www.kernel.org/pub/linux/utils/util\-linux/