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-03-24 "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 A file handle can be generated in one process using
356 .BR name_to_handle_at ()
357 and later used in a different process that calls
358 .BR open_by_handle_at ().
360 Some filesystem don't support the translation of pathnames to
361 file handles, for example,
364 and various network filesystems.
366 A file handle may become invalid ("stale") if a file is deleted,
367 or for other filesystem-specific reasons.
368 Invalid handles are notified by an
371 .BR open_by_handle_at ().
373 These system calls are designed for use by user-space file servers.
374 For example, a user-space NFS server might generate a file handle
375 and pass it to an NFS client.
376 Later, when the client wants to open the file,
377 it could pass the handle back to the server.
378 .\" https://lwn.net/Articles/375888/
379 .\" "Open by handle" - Jonathan Corbet, 2010-02-23
380 This sort of functionality allows a user-space file server to operate in
381 a stateless fashion with respect to the files it serves.
385 refers to a symbolic link and
388 .BR AT_SYMLINK_FOLLOW ,
390 .BR name_to_handle_at ()
391 returns a handle for the link (rather than the file to which it refers).
392 .\" commit bcda76524cd1fa32af748536f27f674a13e56700
393 The process receiving the handle can later perform operations
394 on the symbolic link by converting the handle to a file descriptor using
395 .BR open_by_handle_at ()
398 flag, and then passing the file descriptor as the
400 argument in system calls such as
404 .SS Obtaining a persistent filesystem ID
406 .IR /proc/self/mountinfo
407 can be reused as filesystems are unmounted and mounted.
408 Therefore, the mount ID returned by
409 .BR name_to_handle_at ()
412 should not be treated as a persistent identifier
413 for the corresponding mounted filesystem.
414 However, an application can use the information in the
416 record that corresponds to the mount ID
417 to derive a persistent identifier.
419 For example, one can use the device name in the fifth field of the
421 record to search for the corresponding device UUID via the symbolic links in
422 .IR /dev/disks/by-uuid .
423 (A more comfortable way of obtaining the UUID is to use the
424 .\" e.g., http://stackoverflow.com/questions/6748429/using-libblkid-to-find-uuid-of-a-partition
427 That process can then be reversed,
428 using the UUID to look up the device name,
429 and then obtaining the corresponding mount point,
430 in order to produce the
433 .BR open_by_handle_at ().
435 The two programs below demonstrate the use of
436 .BR name_to_handle_at ()
438 .BR open_by_handle_at ().
440 .RI ( t_name_to_handle_at.c )
442 .BR name_to_handle_at ()
443 to obtain the file handle and mount ID
444 for the file specified in its command-line argument;
445 the handle and mount ID are written to standard output.
448 .RI ( t_open_by_handle_at.c )
449 reads a mount ID and file handle from standard input.
450 The program then employs
451 .BR open_by_handle_at ()
452 to open the file using that handle.
453 If an optional command-line argument is supplied, then the
456 .BR open_by_handle_at ()
457 is obtained by opening the directory named in that argument.
460 is obtained by scanning
461 .IR /proc/self/mountinfo
462 to find a record whose mount ID matches the mount ID
463 read from standard input,
464 and the mount directory specified in that record is opened.
465 (These programs do not deal with the fact that mount IDs are not persistent.)
467 The following shell session demonstrates the use of these two programs:
471 $ \fBecho 'Can you please think about it?' > cecilia.txt\fP
472 $ \fB./t_name_to_handle_at cecilia.txt > fh\fP
473 $ \fB./t_open_by_handle_at < fh\fP
474 open_by_handle_at: Operation not permitted
475 $ \fBsudo ./t_open_by_handle_at < fh\fP # Need CAP_SYS_ADMIN
477 $ \fBrm cecilia.txt\fP
481 Now we delete and (quickly) re-create the file so that
482 it has the same content and (by chance) the same inode.
484 .BR open_by_handle_at ()
485 .\" Christoph Hellwig: That's why the file handles contain a generation
486 .\" counter that gets incremented in this case.
487 recognizes that the original file referred to by the file handle
492 $ \fBstat \-\-printf="%i\\n" cecilia.txt\fP # Display inode number
494 $ \fBrm cecilia.txt\fP
495 $ \fBecho 'Can you please think about it?' > cecilia.txt\fP
496 $ \fBstat \-\-printf="%i\\n" cecilia.txt\fP # Check inode number
498 $ \fBsudo ./t_open_by_handle_at < fh\fP
499 open_by_handle_at: Stale NFS file handle
502 .SS Program source: t_name_to_handle_at.c
506 #include <sys/types.h>
507 #include <sys/stat.h>
515 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
519 main(int argc, char *argv[])
521 struct file_handle *fhp;
522 int mount_id, fhsize, flags, dirfd, j;
526 fprintf(stderr, "Usage: %s pathname\\n", argv[0]);
532 /* Allocate file_handle structure */
534 fhsize = sizeof(*fhp);
535 fhp = malloc(fhsize);
539 /* Make an initial call to name_to_handle_at() to discover
540 the size required for file handle */
542 dirfd = AT_FDCWD; /* For name_to_handle_at() calls */
543 flags = 0; /* For name_to_handle_at() calls */
544 fhp\->handle_bytes = 0;
545 if (name_to_handle_at(dirfd, pathname, fhp,
546 &mount_id, flags) != \-1 || errno != EOVERFLOW) {
547 fprintf(stderr, "Unexpected result from name_to_handle_at()\\n");
551 /* Reallocate file_handle structure with correct size */
553 fhsize = sizeof(struct file_handle) + fhp\->handle_bytes;
554 fhp = realloc(fhp, fhsize); /* Copies fhp\->handle_bytes */
558 /* Get file handle from pathname supplied on command line */
560 if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
561 errExit("name_to_handle_at");
563 /* Write mount ID, file handle size, and file handle to stdout,
564 for later reuse by t_open_by_handle_at.c */
566 printf("%d\\n", mount_id);
567 printf("%d %d ", fhp\->handle_bytes, fhp\->handle_type);
568 for (j = 0; j < fhp\->handle_bytes; j++)
569 printf(" %02x", fhp\->f_handle[j]);
575 .SS Program source: t_open_by_handle_at.c
579 #include <sys/types.h>
580 #include <sys/stat.h>
588 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
591 /* Scan /proc/self/mountinfo to find the line whose mount ID matches
592 \(aqmount_id\(aq. (An easier way to do this is to install and use the
593 \(aqlibmount\(aq library provided by the \(aqutil\-linux\(aq project.)
594 Open the corresponding mount path and return the resulting file
598 open_mount_path_by_id(int mount_id)
602 char mount_path[PATH_MAX];
603 int mi_mount_id, found;
607 fp = fopen("/proc/self/mountinfo", "r");
614 nread = getline(&linep, &lsize, fp);
618 nread = sscanf(linep, "%d %*d %*s %*s %s",
619 &mi_mount_id, mount_path);
621 fprintf(stderr, "Bad sscanf()\\n");
625 if (mi_mount_id == mount_id)
633 fprintf(stderr, "Could not find mount point\\n");
637 return open(mount_path, O_RDONLY);
641 main(int argc, char *argv[])
643 struct file_handle *fhp;
644 int mount_id, fd, mount_fd, handle_bytes, j;
647 #define LINE_SIZE 100
648 char line1[LINE_SIZE], line2[LINE_SIZE];
651 if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
652 fprintf(stderr, "Usage: %s [mount\-path]\\n", argv[0]);
656 /* Standard input contains mount ID and file handle information:
659 Line 2: <handle_bytes> <handle_type> <bytes of handle in hex>
662 if ((fgets(line1, sizeof(line1), stdin) == NULL) ||
663 (fgets(line2, sizeof(line2), stdin) == NULL)) {
664 fprintf(stderr, "Missing mount_id / file handle\\n");
668 mount_id = atoi(line1);
670 handle_bytes = strtoul(line2, &nextp, 0);
672 /* Given handle_bytes, we can now allocate file_handle structure */
674 fhp = malloc(sizeof(struct file_handle) + handle_bytes);
678 fhp\->handle_bytes = handle_bytes;
680 fhp\->handle_type = strtoul(nextp, &nextp, 0);
682 for (j = 0; j < fhp\->handle_bytes; j++)
683 fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
685 /* Obtain file descriptor for mount point, either by opening
686 the pathname specified on the command line, or by scanning
687 /proc/self/mounts to find a mount that matches the \(aqmount_id\(aq
688 that we received from stdin. */
691 mount_fd = open(argv[1], O_RDONLY);
693 mount_fd = open_mount_path_by_id(mount_id);
696 errExit("opening mount fd");
698 /* Open file using handle and mount point */
700 fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
702 errExit("open_by_handle_at");
704 /* Try reading a few bytes from the file */
706 nread = read(fd, buf, sizeof(buf));
710 printf("Read %zd bytes\\n", nread);
726 documentation in the latest
729 .UR https://www.kernel.org/pub/linux/utils/util-linux/
732 This page is part of release 3.65 of the Linux
735 A description of the project,
736 and information about reporting bugs,
738 \%http://www.kernel.org/doc/man\-pages/.