1 .\" Copyright (c) 2014 by Michael Kerrisk <mtk.manpages@gmail.com>
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
25 .TH OPEN_BY_HANDLE_AT 2 2014-05-08 "Linux" "Linux Programmer's Manual"
27 name_to_handle_at, open_by_handle_at \- obtain handle
28 for a pathname and open file via a handle
31 .B #define _GNU_SOURCE
32 .B #include <sys/types.h>
33 .B #include <sys/stat.h>
36 .BI "int name_to_handle_at(int " dirfd ", const char *" pathname ,
37 .BI " struct file_handle *" handle ,
38 .BI " int *" mount_id ", int " flags );
40 .BI "int open_by_handle_at(int " mount_fd ", struct file_handle *" handle ,
45 .BR name_to_handle_at ()
47 .BR open_by_handle_at ()
48 system calls split the functionality of
51 .BR name_to_handle_at ()
52 returns an opaque handle that corresponds to a specified file;
53 .BR open_by_handle_at ()
54 opens the file corresponding to a handle returned by a previous call to
55 .BR name_to_handle_at ()
56 and returns an open file descriptor.
59 .SS name_to_handle_at()
61 .BR name_to_handle_at ()
62 system call returns a file handle and a mount ID corresponding to
63 the file specified by the
68 The file handle is returned via the argument
70 which is a pointer to a structure of the following form:
75 unsigned int handle_bytes; /* Size of f_handle [in, out] */
76 int handle_type; /* Handle type [out] */
77 unsigned char f_handle[0]; /* File identifier (sized by
83 It is the caller's responsibility to allocate the structure
84 with a size large enough to hold the handle returned in
88 field should be initialized to contain the allocated size for
94 specifies the maximum possible size for a file handle.)
95 Upon successful return, the
97 field is updated to contain the number of bytes actually written to
100 The caller can discover the required size for the
102 structure by making a call in which
103 .IR handle->handle_bytes
105 in this case, the call fails with the error
108 .IR handle->handle_bytes
109 is set to indicate the required size;
110 the caller can then use this information to allocate a structure
111 of the correct size (see EXAMPLE below).
113 Other than the use of the
115 field, the caller should treat the
117 structure as an opaque data type: the
121 fields are needed only by a subsequent call to
122 .BR open_by_handle_at ().
126 argument is a bit mask constructed by ORing together zero or more of
129 .BR AT_SYMLINK_FOLLOW ,
136 arguments identify the file for which a handle is to be obtained.
137 There are four distinct cases:
141 is a nonempty string containing an absolute pathname,
142 then a handle is returned for the file referred to by that pathname.
149 is a nonempty string containing a relative pathname and
151 has the special value
155 is interpreted relative to the current working directory of the caller,
156 and a handle is returned for the file to which it refers.
160 is a nonempty string containing a relative pathname and
162 is a file descriptor referring to a directory, then
164 is interpreted relative to the directory referred to by
166 and a handle is returned for the file to which it refers.
169 for an explanation of why "directory file descriptors" are useful.)
173 is an empty string and
179 can be an open file descriptor referring to any type of file,
182 meaning the current working directory,
183 and a handle is returned for the file to which it refers.
187 argument returns an identifier for the filesystem
188 mount that corresponds to
190 This corresponds to the first field in one of the records in
191 .IR /proc/self/mountinfo .
192 Opening the pathname in the fifth field of that record yields a file
193 descriptor for the mount point;
194 that file descriptor can be used in a subsequent call to
195 .BR open_by_handle_at ().
198 .BR name_to_handle_at ()
201 if it is a symbolic link, and thus returns a handle for the link itself.
207 is dereferenced if it is a symbolic link
208 (so that the call returns a handle for the file referred to by the link).
209 .SS open_by_handle_at()
211 .BR open_by_handle_at ()
212 system call opens the file referred to by
214 a file handle returned by a previous call to
215 .BR name_to_handle_at ().
219 argument is a file descriptor for any object (file, directory, etc.)
220 in the mounted filesystem with respect to which
222 should be interpreted.
225 can be specified, meaning the current working directory of the caller.
234 refers to a symbolic link, the caller must specify the
236 flag, and the symbolic link is not dereferenced; the
238 flag, if specified, is ignored.
241 The caller must have the
242 .B CAP_DAC_READ_SEARCH
244 .BR open_by_handle_at ().
247 .BR name_to_handle_at ()
250 .BR open_by_handle_at ()
251 returns a nonnegative file descriptor.
253 In the event of an error, both system calls return \-1 and set
255 to indicate the cause of the error.
257 .BR name_to_handle_at ()
259 .BR open_by_handle_at ()
260 can fail for the same errors as
262 In addition, they can fail with the errors noted below.
264 .BR name_to_handle_at ()
265 can fail with the following errors:
272 points outside your accessible address space.
276 includes an invalid bit value.
279 .IR handle\->handle_bytes
285 is an empty string, but
291 The file descriptor supplied in
293 does not refer to a directory,
294 and it is not the case that both
303 The filesystem does not support decoding of a pathname to a file handle.
307 .I handle->handle_bytes
308 value passed into the call was too small.
309 When this error occurs,
310 .I handle->handle_bytes
311 is updated to indicate the required size for the handle.
315 .BR open_by_handle_at ()
316 can fail with the following errors:
320 is not an open file descriptor.
324 points outside your accessible address space.
327 .I handle->handle_bytes
334 refers to a symbolic link, but
340 The caller does not have the
341 .BR CAP_DAC_READ_SEARCH
348 This error will occur if, for example, the file has been deleted.
350 These system calls first appeared in Linux 2.6.39.
351 Library support is provided in glibc since version 2.14.
353 These system calls are nonstandard Linux extensions.
355 FreeBSD has a broadly similar pair of system calls in the form of
360 A file handle can be generated in one process using
361 .BR name_to_handle_at ()
362 and later used in a different process that calls
363 .BR open_by_handle_at ().
365 Some filesystem don't support the translation of pathnames to
366 file handles, for example,
369 and various network filesystems.
371 A file handle may become invalid ("stale") if a file is deleted,
372 or for other filesystem-specific reasons.
373 Invalid handles are notified by an
376 .BR open_by_handle_at ().
378 These system calls are designed for use by user-space file servers.
379 For example, a user-space NFS server might generate a file handle
380 and pass it to an NFS client.
381 Later, when the client wants to open the file,
382 it could pass the handle back to the server.
383 .\" https://lwn.net/Articles/375888/
384 .\" "Open by handle" - Jonathan Corbet, 2010-02-23
385 This sort of functionality allows a user-space file server to operate in
386 a stateless fashion with respect to the files it serves.
390 refers to a symbolic link and
393 .BR AT_SYMLINK_FOLLOW ,
395 .BR name_to_handle_at ()
396 returns a handle for the link (rather than the file to which it refers).
397 .\" commit bcda76524cd1fa32af748536f27f674a13e56700
398 The process receiving the handle can later perform operations
399 on the symbolic link by converting the handle to a file descriptor using
400 .BR open_by_handle_at ()
403 flag, and then passing the file descriptor as the
405 argument in system calls such as
409 .SS Obtaining a persistent filesystem ID
411 .IR /proc/self/mountinfo
412 can be reused as filesystems are unmounted and mounted.
413 Therefore, the mount ID returned by
414 .BR name_to_handle_at ()
417 should not be treated as a persistent identifier
418 for the corresponding mounted filesystem.
419 However, an application can use the information in the
421 record that corresponds to the mount ID
422 to derive a persistent identifier.
424 For example, one can use the device name in the fifth field of the
426 record to search for the corresponding device UUID via the symbolic links in
427 .IR /dev/disks/by-uuid .
428 (A more comfortable way of obtaining the UUID is to use the
429 .\" e.g., http://stackoverflow.com/questions/6748429/using-libblkid-to-find-uuid-of-a-partition
432 That process can then be reversed,
433 using the UUID to look up the device name,
434 and then obtaining the corresponding mount point,
435 in order to produce the
438 .BR open_by_handle_at ().
440 The two programs below demonstrate the use of
441 .BR name_to_handle_at ()
443 .BR open_by_handle_at ().
445 .RI ( t_name_to_handle_at.c )
447 .BR name_to_handle_at ()
448 to obtain the file handle and mount ID
449 for the file specified in its command-line argument;
450 the handle and mount ID are written to standard output.
453 .RI ( t_open_by_handle_at.c )
454 reads a mount ID and file handle from standard input.
455 The program then employs
456 .BR open_by_handle_at ()
457 to open the file using that handle.
458 If an optional command-line argument is supplied, then the
461 .BR open_by_handle_at ()
462 is obtained by opening the directory named in that argument.
465 is obtained by scanning
466 .IR /proc/self/mountinfo
467 to find a record whose mount ID matches the mount ID
468 read from standard input,
469 and the mount directory specified in that record is opened.
470 (These programs do not deal with the fact that mount IDs are not persistent.)
472 The following shell session demonstrates the use of these two programs:
476 $ \fBecho 'Can you please think about it?' > cecilia.txt\fP
477 $ \fB./t_name_to_handle_at cecilia.txt > fh\fP
478 $ \fB./t_open_by_handle_at < fh\fP
479 open_by_handle_at: Operation not permitted
480 $ \fBsudo ./t_open_by_handle_at < fh\fP # Need CAP_SYS_ADMIN
482 $ \fBrm cecilia.txt\fP
486 Now we delete and (quickly) re-create the file so that
487 it has the same content and (by chance) the same inode.
489 .BR open_by_handle_at ()
490 .\" Christoph Hellwig: That's why the file handles contain a generation
491 .\" counter that gets incremented in this case.
492 recognizes that the original file referred to by the file handle
497 $ \fBstat \-\-printf="%i\\n" cecilia.txt\fP # Display inode number
499 $ \fBrm cecilia.txt\fP
500 $ \fBecho 'Can you please think about it?' > cecilia.txt\fP
501 $ \fBstat \-\-printf="%i\\n" cecilia.txt\fP # Check inode number
503 $ \fBsudo ./t_open_by_handle_at < fh\fP
504 open_by_handle_at: Stale NFS file handle
507 .SS Program source: t_name_to_handle_at.c
511 #include <sys/types.h>
512 #include <sys/stat.h>
520 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
524 main(int argc, char *argv[])
526 struct file_handle *fhp;
527 int mount_id, fhsize, flags, dirfd, j;
531 fprintf(stderr, "Usage: %s pathname\\n", argv[0]);
537 /* Allocate file_handle structure */
539 fhsize = sizeof(*fhp);
540 fhp = malloc(fhsize);
544 /* Make an initial call to name_to_handle_at() to discover
545 the size required for file handle */
547 dirfd = AT_FDCWD; /* For name_to_handle_at() calls */
548 flags = 0; /* For name_to_handle_at() calls */
549 fhp\->handle_bytes = 0;
550 if (name_to_handle_at(dirfd, pathname, fhp,
551 &mount_id, flags) != \-1 || errno != EOVERFLOW) {
552 fprintf(stderr, "Unexpected result from name_to_handle_at()\\n");
556 /* Reallocate file_handle structure with correct size */
558 fhsize = sizeof(struct file_handle) + fhp\->handle_bytes;
559 fhp = realloc(fhp, fhsize); /* Copies fhp\->handle_bytes */
563 /* Get file handle from pathname supplied on command line */
565 if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
566 errExit("name_to_handle_at");
568 /* Write mount ID, file handle size, and file handle to stdout,
569 for later reuse by t_open_by_handle_at.c */
571 printf("%d\\n", mount_id);
572 printf("%d %d ", fhp\->handle_bytes, fhp\->handle_type);
573 for (j = 0; j < fhp\->handle_bytes; j++)
574 printf(" %02x", fhp\->f_handle[j]);
580 .SS Program source: t_open_by_handle_at.c
584 #include <sys/types.h>
585 #include <sys/stat.h>
593 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
596 /* Scan /proc/self/mountinfo to find the line whose mount ID matches
597 \(aqmount_id\(aq. (An easier way to do this is to install and use the
598 \(aqlibmount\(aq library provided by the \(aqutil\-linux\(aq project.)
599 Open the corresponding mount path and return the resulting file
603 open_mount_path_by_id(int mount_id)
607 char mount_path[PATH_MAX];
608 int mi_mount_id, found;
612 fp = fopen("/proc/self/mountinfo", "r");
619 nread = getline(&linep, &lsize, fp);
623 nread = sscanf(linep, "%d %*d %*s %*s %s",
624 &mi_mount_id, mount_path);
626 fprintf(stderr, "Bad sscanf()\\n");
630 if (mi_mount_id == mount_id)
638 fprintf(stderr, "Could not find mount point\\n");
642 return open(mount_path, O_RDONLY);
646 main(int argc, char *argv[])
648 struct file_handle *fhp;
649 int mount_id, fd, mount_fd, handle_bytes, j;
652 #define LINE_SIZE 100
653 char line1[LINE_SIZE], line2[LINE_SIZE];
656 if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
657 fprintf(stderr, "Usage: %s [mount\-path]\\n", argv[0]);
661 /* Standard input contains mount ID and file handle information:
664 Line 2: <handle_bytes> <handle_type> <bytes of handle in hex>
667 if ((fgets(line1, sizeof(line1), stdin) == NULL) ||
668 (fgets(line2, sizeof(line2), stdin) == NULL)) {
669 fprintf(stderr, "Missing mount_id / file handle\\n");
673 mount_id = atoi(line1);
675 handle_bytes = strtoul(line2, &nextp, 0);
677 /* Given handle_bytes, we can now allocate file_handle structure */
679 fhp = malloc(sizeof(struct file_handle) + handle_bytes);
683 fhp\->handle_bytes = handle_bytes;
685 fhp\->handle_type = strtoul(nextp, &nextp, 0);
687 for (j = 0; j < fhp\->handle_bytes; j++)
688 fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
690 /* Obtain file descriptor for mount point, either by opening
691 the pathname specified on the command line, or by scanning
692 /proc/self/mounts to find a mount that matches the \(aqmount_id\(aq
693 that we received from stdin. */
696 mount_fd = open(argv[1], O_RDONLY);
698 mount_fd = open_mount_path_by_id(mount_id);
701 errExit("opening mount fd");
703 /* Open file using handle and mount point */
705 fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
707 errExit("open_by_handle_at");
709 /* Try reading a few bytes from the file */
711 nread = read(fd, buf, sizeof(buf));
715 printf("Read %zd bytes\\n", nread);
731 documentation in the latest
734 .UR https://www.kernel.org/pub/linux/utils/util-linux/
737 This page is part of release 3.68 of the Linux
740 A description of the project,
741 information about reporting bugs,
742 and the latest version of this page,
744 \%http://www.kernel.org/doc/man\-pages/.