OSDN Git Service

LDP: Update original to LDP v3.79
[linuxjm/LDP_man-pages.git] / original / man2 / open_by_handle_at.2
1 .\" Copyright (c) 2014 by Michael Kerrisk <mtk.manpages@gmail.com>
2 .\"
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.
7 .\"
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.
12 .\"
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
19 .\" professionally.
20 .\"
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
23 .\" %%%LICENSE_END
24 .\"
25 .TH OPEN_BY_HANDLE_AT 2 2014-06-13 "Linux" "Linux Programmer's Manual"
26 .SH NAME
27 name_to_handle_at, open_by_handle_at \- obtain handle
28 for a pathname and open file via a handle
29 .SH SYNOPSIS
30 .nf
31 .BR "#define _GNU_SOURCE" "         /* See feature_test_macros(7) */"
32 .B #include <sys/types.h>
33 .B #include <sys/stat.h>
34 .B #include <fcntl.h>
35
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 );
39
40 .BI "int open_by_handle_at(int " mount_fd ", struct file_handle *" handle ,
41 .BI "                      int " flags );
42 .fi
43 .SH DESCRIPTION
44 The
45 .BR name_to_handle_at ()
46 and
47 .BR open_by_handle_at ()
48 system calls split the functionality of
49 .BR openat (2)
50 into two parts:
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.
57 .\"
58 .\"
59 .SS name_to_handle_at()
60 The
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
64 .IR dirfd
65 and
66 .IR pathname
67 arguments.
68 The file handle is returned via the argument
69 .IR handle ,
70 which is a pointer to a structure of the following form:
71
72 .in +4n
73 .nf
74 struct file_handle {
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
78                                      caller) [out] */
79 };
80 .fi
81 .in
82 .PP
83 It is the caller's responsibility to allocate the structure
84 with a size large enough to hold the handle returned in
85 .IR f_handle .
86 Before the call, the
87 .IR handle_bytes
88 field should be initialized to contain the allocated size for
89 .IR f_handle .
90 (The constant
91 .BR MAX_HANDLE_SZ ,
92 defined in
93 .IR <fcntl.h> ,
94 specifies the maximum possible size for a file handle.)
95 Upon successful return, the
96 .IR handle_bytes
97 field is updated to contain the number of bytes actually written to
98 .IR f_handle .
99
100 The caller can discover the required size for the
101 .I file_handle
102 structure by making a call in which
103 .IR handle->handle_bytes
104 is zero;
105 in this case, the call fails with the error
106 .BR EOVERFLOW
107 and
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).
112
113 Other than the use of the
114 .IR handle_bytes
115 field, the caller should treat the
116 .IR file_handle
117 structure as an opaque data type: the
118 .IR handle_type
119 and
120 .IR f_handle
121 fields are needed only by a subsequent call to
122 .BR open_by_handle_at ().
123
124 The
125 .I flags
126 argument is a bit mask constructed by ORing together zero or more of
127 .BR AT_EMPTY_PATH
128 and
129 .BR AT_SYMLINK_FOLLOW ,
130 described below.
131
132 Together, the
133 .I pathname
134 and
135 .I dirfd
136 arguments identify the file for which a handle is to be obtained.
137 There are four distinct cases:
138 .IP * 3
139 If
140 .I pathname
141 is a nonempty string containing an absolute pathname,
142 then a handle is returned for the file referred to by that pathname.
143 In this case,
144 .IR dirfd
145 is ignored.
146 .IP *
147 If
148 .I pathname
149 is a nonempty string containing a relative pathname and
150 .IR dirfd
151 has the special value
152 .BR AT_FDCWD ,
153 then
154 .I pathname
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.
157 .IP *
158 If
159 .I pathname
160 is a nonempty string containing a relative pathname and
161 .IR dirfd
162 is a file descriptor referring to a directory, then
163 .I pathname
164 is interpreted relative to the directory referred to by
165 .IR dirfd ,
166 and a handle is returned for the file to which it refers.
167 (See
168 .BR openat (2)
169 for an explanation of why "directory file descriptors" are useful.)
170 .IP *
171 If
172 .I pathname
173 is an empty string and
174 .I flags
175 specifies the value
176 .BR AT_EMPTY_PATH ,
177 then
178 .IR dirfd
179 can be an open file descriptor referring to any type of file,
180 or
181 .BR AT_FDCWD ,
182 meaning the current working directory,
183 and a handle is returned for the file to which it refers.
184 .PP
185 The
186 .I mount_id
187 argument returns an identifier for the filesystem
188 mount that corresponds to
189 .IR pathname .
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 ().
196
197 By default,
198 .BR name_to_handle_at ()
199 does not dereference
200 .I pathname
201 if it is a symbolic link, and thus returns a handle for the link itself.
202 If
203 .B AT_SYMLINK_FOLLOW
204 is specified in
205 .IR flags ,
206 .I pathname
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()
210 The
211 .BR open_by_handle_at ()
212 system call opens the file referred to by
213 .IR handle ,
214 a file handle returned by a previous call to
215 .BR name_to_handle_at ().
216
217 The
218 .IR mount_fd
219 argument is a file descriptor for any object (file, directory, etc.)
220 in the mounted filesystem with respect to which
221 .IR handle
222 should be interpreted.
223 The special value
224 .B AT_FDCWD
225 can be specified, meaning the current working directory of the caller.
226
227 The
228 .I flags
229 argument
230 is as for
231 .BR open (2).
232 If
233 .I handle
234 refers to a symbolic link, the caller must specify the
235 .B O_PATH
236 flag, and the symbolic link is not dereferenced; the
237 .B O_NOFOLLOW
238 flag, if specified, is ignored.
239
240
241 The caller must have the
242 .B CAP_DAC_READ_SEARCH
243 capability to invoke
244 .BR open_by_handle_at ().
245 .SH RETURN VALUE
246 On success,
247 .BR name_to_handle_at ()
248 returns 0,
249 and
250 .BR open_by_handle_at ()
251 returns a nonnegative file descriptor.
252
253 In the event of an error, both system calls return \-1 and set
254 .I errno
255 to indicate the cause of the error.
256 .SH ERRORS
257 .BR name_to_handle_at ()
258 and
259 .BR open_by_handle_at ()
260 can fail for the same errors as
261 .BR openat (2).
262 In addition, they can fail with the errors noted below.
263
264 .BR name_to_handle_at ()
265 can fail with the following errors:
266 .TP
267 .B EFAULT
268 .IR pathname ,
269 .IR mount_id ,
270 or
271 .IR handle
272 points outside your accessible address space.
273 .TP
274 .B EINVAL
275 .I flags
276 includes an invalid bit value.
277 .TP
278 .B EINVAL
279 .IR handle\->handle_bytes
280 is greater than
281 .BR MAX_HANDLE_SZ .
282 .TP
283 .B ENOENT
284 .I pathname
285 is an empty string, but
286 .BR AT_EMPTY_PATH
287 was not specified in
288 .IR flags .
289 .TP
290 .B ENOTDIR
291 The file descriptor supplied in
292 .I dirfd
293 does not refer to a directory,
294 and it is not the case that both
295 .I flags
296 includes
297 .BR AT_EMPTY_PATH
298 and
299 .I pathname
300 is an empty string.
301 .TP
302 .B EOPNOTSUPP
303 The filesystem does not support decoding of a pathname to a file handle.
304 .TP
305 .B EOVERFLOW
306 The
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.
312 .\"
313 .\"
314 .PP
315 .BR open_by_handle_at ()
316 can fail with the following errors:
317 .TP
318 .B EBADF
319 .IR mount_fd
320 is not an open file descriptor.
321 .TP
322 .B EFAULT
323 .IR handle
324 points outside your accessible address space.
325 .TP
326 .B EINVAL
327 .I handle->handle_bytes
328 is greater than
329 .BR MAX_HANDLE_SZ
330 or is equal to zero.
331 .TP
332 .B ELOOP
333 .I handle
334 refers to a symbolic link, but
335 .B O_PATH
336 was not specified in
337 .IR flags .
338 .TP
339 .B EPERM
340 The caller does not have the
341 .BR CAP_DAC_READ_SEARCH
342 capability.
343 .TP
344 .B ESTALE
345 The specified
346 .I handle
347 is not valid.
348 This error will occur if, for example, the file has been deleted.
349 .SH VERSIONS
350 These system calls first appeared in Linux 2.6.39.
351 Library support is provided in glibc since version 2.14.
352 .SH CONFORMING TO
353 These system calls are nonstandard Linux extensions.
354
355 FreeBSD has a broadly similar pair of system calls in the form of
356 .BR getfh ()
357 and
358 .BR openfh ().
359 .SH NOTES
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 ().
364
365 Some filesystem don't support the translation of pathnames to
366 file handles, for example,
367 .IR /proc ,
368 .IR /sys ,
369 and various network filesystems.
370
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
374 .B ESTALE
375 error from
376 .BR open_by_handle_at ().
377
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.
387
388 If
389 .I pathname
390 refers to a symbolic link and
391 .IR flags
392 does not specify
393 .BR AT_SYMLINK_FOLLOW ,
394 then
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 ()
401 with the
402 .BR O_PATH
403 flag, and then passing the file descriptor as the
404 .IR dirfd
405 argument in system calls such as
406 .BR readlinkat (2)
407 and
408 .BR fchownat (2).
409 .SS Obtaining a persistent filesystem ID
410 The mount IDs in
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 ()
415 (in
416 .IR *mount_id )
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
420 .I mountinfo
421 record that corresponds to the mount ID
422 to derive a persistent identifier.
423
424 For example, one can use the device name in the fifth field of the
425 .I mountinfo
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
430 .BR libblkid (3)
431 library.)
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
436 .IR mount_fd
437 argument used by
438 .BR open_by_handle_at ().
439 .SH EXAMPLE
440 The two programs below demonstrate the use of
441 .BR name_to_handle_at ()
442 and
443 .BR open_by_handle_at ().
444 The first program
445 .RI ( t_name_to_handle_at.c )
446 uses
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.
451
452 The second program
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
459 .IR mount_fd
460 argument for
461 .BR open_by_handle_at ()
462 is obtained by opening the directory named in that argument.
463 Otherwise,
464 .IR mount_fd
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.)
471
472 The following shell session demonstrates the use of these two programs:
473
474 .in +4n
475 .nf
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
481 Read 31 bytes
482 $ \fBrm cecilia.txt\fP
483 .fi
484 .in
485
486 Now we delete and (quickly) re-create the file so that
487 it has the same content and (by chance) the same inode.
488 Nevertheless,
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
493 no longer exists.
494
495 .in +4n
496 .nf
497 $ \fBstat \-\-printf="%i\\n" cecilia.txt\fP     # Display inode number
498 4072121
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
502 4072121
503 $ \fBsudo ./t_open_by_handle_at < fh\fP
504 open_by_handle_at: Stale NFS file handle
505 .fi
506 .in
507 .SS Program source: t_name_to_handle_at.c
508 \&
509 .nf
510 #define _GNU_SOURCE
511 #include <sys/types.h>
512 #include <sys/stat.h>
513 #include <fcntl.h>
514 #include <stdio.h>
515 #include <stdlib.h>
516 #include <unistd.h>
517 #include <errno.h>
518 #include <string.h>
519
520 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \\
521                         } while (0)
522
523 int
524 main(int argc, char *argv[])
525 {
526     struct file_handle *fhp;
527     int mount_id, fhsize, flags, dirfd, j;
528     char *pathname;
529
530     if (argc != 2) {
531         fprintf(stderr, "Usage: %s pathname\\n", argv[0]);
532         exit(EXIT_FAILURE);
533     }
534
535     pathname = argv[1];
536
537     /* Allocate file_handle structure */
538
539     fhsize = sizeof(*fhp);
540     fhp = malloc(fhsize);
541     if (fhp == NULL)
542         errExit("malloc");
543
544     /* Make an initial call to name_to_handle_at() to discover
545        the size required for file handle */
546
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");
553         exit(EXIT_FAILURE);
554     }
555
556     /* Reallocate file_handle structure with correct size */
557
558     fhsize = sizeof(struct file_handle) + fhp\->handle_bytes;
559     fhp = realloc(fhp, fhsize);         /* Copies fhp\->handle_bytes */
560     if (fhp == NULL)
561         errExit("realloc");
562
563     /* Get file handle from pathname supplied on command line */
564
565     if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
566         errExit("name_to_handle_at");
567
568     /* Write mount ID, file handle size, and file handle to stdout,
569        for later reuse by t_open_by_handle_at.c */
570
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]);
575     printf("\\n");
576
577     exit(EXIT_SUCCESS);
578 }
579 .fi
580 .SS Program source: t_open_by_handle_at.c
581 \&
582 .nf
583 #define _GNU_SOURCE
584 #include <sys/types.h>
585 #include <sys/stat.h>
586 #include <fcntl.h>
587 #include <limits.h>
588 #include <stdio.h>
589 #include <stdlib.h>
590 #include <unistd.h>
591 #include <string.h>
592
593 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \\
594                         } while (0)
595
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
600    descriptor. */
601
602 static int
603 open_mount_path_by_id(int mount_id)
604 {
605     char *linep;
606     size_t lsize;
607     char mount_path[PATH_MAX];
608     int mi_mount_id, found;
609     ssize_t nread;
610     FILE *fp;
611
612     fp = fopen("/proc/self/mountinfo", "r");
613     if (fp == NULL)
614         errExit("fopen");
615
616     found = 0;
617     linep = NULL;
618     while (!found) {
619         nread = getline(&linep, &lsize, fp);
620         if (nread == \-1)
621             break;
622
623         nread = sscanf(linep, "%d %*d %*s %*s %s",
624                        &mi_mount_id, mount_path);
625         if (nread != 2) {
626             fprintf(stderr, "Bad sscanf()\\n");
627             exit(EXIT_FAILURE);
628         }
629
630         if (mi_mount_id == mount_id)
631             found = 1;
632     }
633     free(linep);
634
635     fclose(fp);
636
637     if (!found) {
638         fprintf(stderr, "Could not find mount point\\n");
639         exit(EXIT_FAILURE);
640     }
641
642     return open(mount_path, O_RDONLY);
643 }
644
645 int
646 main(int argc, char *argv[])
647 {
648     struct file_handle *fhp;
649     int mount_id, fd, mount_fd, handle_bytes, j;
650     ssize_t nread;
651     char buf[1000];
652 #define LINE_SIZE 100
653     char line1[LINE_SIZE], line2[LINE_SIZE];
654     char *nextp;
655
656     if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
657         fprintf(stderr, "Usage: %s [mount\-path]\\n", argv[0]);
658         exit(EXIT_FAILURE);
659     }
660
661     /* Standard input contains mount ID and file handle information:
662
663          Line 1: <mount_id>
664          Line 2: <handle_bytes> <handle_type>   <bytes of handle in hex>
665     */
666
667     if ((fgets(line1, sizeof(line1), stdin) == NULL) ||
668            (fgets(line2, sizeof(line2), stdin) == NULL)) {
669         fprintf(stderr, "Missing mount_id / file handle\\n");
670         exit(EXIT_FAILURE);
671     }
672
673     mount_id = atoi(line1);
674
675     handle_bytes = strtoul(line2, &nextp, 0);
676
677     /* Given handle_bytes, we can now allocate file_handle structure */
678
679     fhp = malloc(sizeof(struct file_handle) + handle_bytes);
680     if (fhp == NULL)
681         errExit("malloc");
682
683     fhp\->handle_bytes = handle_bytes;
684
685     fhp\->handle_type = strtoul(nextp, &nextp, 0);
686
687     for (j = 0; j < fhp\->handle_bytes; j++)
688         fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
689
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. */
694
695     if (argc > 1)
696         mount_fd = open(argv[1], O_RDONLY);
697     else
698         mount_fd = open_mount_path_by_id(mount_id);
699
700     if (mount_fd == \-1)
701         errExit("opening mount fd");
702
703     /* Open file using handle and mount point */
704
705     fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
706     if (fd == \-1)
707         errExit("open_by_handle_at");
708
709     /* Try reading a few bytes from the file */
710
711     nread = read(fd, buf, sizeof(buf));
712     if (nread == \-1)
713         errExit("read");
714
715     printf("Read %zd bytes\\n", nread);
716
717     exit(EXIT_SUCCESS);
718 }
719 .fi
720 .SH SEE ALSO
721 .BR open (2),
722 .BR libblkid (3),
723 .BR blkid (8),
724 .BR findfs (8),
725 .BR mount (8)
726
727 The
728 .I libblkid
729 and
730 .I libmount
731 documentation in the latest
732 .I util-linux
733 release at
734 .UR https://www.kernel.org/pub/linux/utils/util-linux/
735 .UE
736 .SH COLOPHON
737 This page is part of release 3.79 of the Linux
738 .I man-pages
739 project.
740 A description of the project,
741 information about reporting bugs,
742 and the latest version of this page,
743 can be found at
744 \%http://www.kernel.org/doc/man\-pages/.