OSDN Git Service

(split) LDP: Update original to LDP v3.65
[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-03-24 "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 .B #define _GNU_SOURCE
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 (3)
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 .SH NOTES
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 ().
359
360 Some filesystem don't support the translation of pathnames to
361 file handles, for example,
362 .IR /proc ,
363 .IR /sys ,
364 and various network filesystems.
365
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
369 .B ESTALE
370 error from
371 .BR open_by_handle_at ().
372
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.
382
383 If
384 .I pathname
385 refers to a symbolic link and
386 .IR flags
387 does not specify
388 .BR AT_SYMLINK_FOLLOW ,
389 then
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 ()
396 with the
397 .BR O_PATH
398 flag, and then passing the file descriptor as the
399 .IR dirfd
400 argument in system calls such as
401 .BR readlinkat (2)
402 and
403 .BR fchownat (2).
404 .SS Obtaining a persistent filesystem ID
405 The mount IDs in
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 ()
410 (in
411 .IR *mount_id )
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
415 .I mountinfo
416 record that corresponds to the mount ID
417 to derive a persistent identifier.
418
419 For example, one can use the device name in the fifth field of the
420 .I mountinfo
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
425 .BR libblkid (3)
426 library.)
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
431 .IR mount_fd
432 argument used by
433 .BR open_by_handle_at ().
434 .SH EXAMPLE
435 The two programs below demonstrate the use of
436 .BR name_to_handle_at ()
437 and
438 .BR open_by_handle_at ().
439 The first program
440 .RI ( t_name_to_handle_at.c )
441 uses
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.
446
447 The second program
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
454 .IR mount_fd
455 argument for
456 .BR open_by_handle_at ()
457 is obtained by opening the directory named in that argument.
458 Otherwise,
459 .IR mount_fd
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.)
466
467 The following shell session demonstrates the use of these two programs:
468
469 .in +4n
470 .nf
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
476 Read 31 bytes
477 $ \fBrm cecilia.txt\fP
478 .fi
479 .in
480
481 Now we delete and (quickly) re-create the file so that
482 it has the same content and (by chance) the same inode.
483 Nevertheless,
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
488 no longer exists.
489
490 .in +4n
491 .nf
492 $ \fBstat \-\-printf="%i\\n" cecilia.txt\fP     # Display inode number
493 4072121
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
497 4072121
498 $ \fBsudo ./t_open_by_handle_at < fh\fP
499 open_by_handle_at: Stale NFS file handle
500 .fi
501 .in
502 .SS Program source: t_name_to_handle_at.c
503 \&
504 .nf
505 #define _GNU_SOURCE
506 #include <sys/types.h>
507 #include <sys/stat.h>
508 #include <fcntl.h>
509 #include <stdio.h>
510 #include <stdlib.h>
511 #include <unistd.h>
512 #include <errno.h>
513 #include <string.h>
514
515 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \\
516                         } while (0)
517
518 int
519 main(int argc, char *argv[])
520 {
521     struct file_handle *fhp;
522     int mount_id, fhsize, flags, dirfd, j;
523     char *pathname;
524
525     if (argc != 2) {
526         fprintf(stderr, "Usage: %s pathname\\n", argv[0]);
527         exit(EXIT_FAILURE);
528     }
529
530     pathname = argv[1];
531
532     /* Allocate file_handle structure */
533
534     fhsize = sizeof(*fhp);
535     fhp = malloc(fhsize);
536     if (fhp == NULL)
537         errExit("malloc");
538
539     /* Make an initial call to name_to_handle_at() to discover
540        the size required for file handle */
541
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");
548         exit(EXIT_FAILURE);
549     }
550
551     /* Reallocate file_handle structure with correct size */
552
553     fhsize = sizeof(struct file_handle) + fhp\->handle_bytes;
554     fhp = realloc(fhp, fhsize);         /* Copies fhp\->handle_bytes */
555     if (fhp == NULL)
556         errExit("realloc");
557
558     /* Get file handle from pathname supplied on command line */
559
560     if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
561         errExit("name_to_handle_at");
562
563     /* Write mount ID, file handle size, and file handle to stdout,
564        for later reuse by t_open_by_handle_at.c */
565
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]);
570     printf("\\n");
571
572     exit(EXIT_SUCCESS);
573 }
574 .fi
575 .SS Program source: t_open_by_handle_at.c
576 \&
577 .nf
578 #define _GNU_SOURCE
579 #include <sys/types.h>
580 #include <sys/stat.h>
581 #include <fcntl.h>
582 #include <limits.h>
583 #include <stdio.h>
584 #include <stdlib.h>
585 #include <unistd.h>
586 #include <string.h>
587
588 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \\
589                         } while (0)
590
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
595    descriptor. */
596
597 static int
598 open_mount_path_by_id(int mount_id)
599 {
600     char *linep;
601     size_t lsize;
602     char mount_path[PATH_MAX];
603     int mi_mount_id, found;
604     ssize_t nread;
605     FILE *fp;
606
607     fp = fopen("/proc/self/mountinfo", "r");
608     if (fp == NULL)
609         errExit("fopen");
610
611     found = 0;
612     linep = NULL;
613     while (!found) {
614         nread = getline(&linep, &lsize, fp);
615         if (nread == \-1)
616             break;
617
618         nread = sscanf(linep, "%d %*d %*s %*s %s",
619                        &mi_mount_id, mount_path);
620         if (nread != 2) {
621             fprintf(stderr, "Bad sscanf()\\n");
622             exit(EXIT_FAILURE);
623         }
624
625         if (mi_mount_id == mount_id)
626             found = 1;
627     }
628     free(linep);
629
630     fclose(fp);
631
632     if (!found) {
633         fprintf(stderr, "Could not find mount point\\n");
634         exit(EXIT_FAILURE);
635     }
636
637     return open(mount_path, O_RDONLY);
638 }
639
640 int
641 main(int argc, char *argv[])
642 {
643     struct file_handle *fhp;
644     int mount_id, fd, mount_fd, handle_bytes, j;
645     ssize_t nread;
646     char buf[1000];
647 #define LINE_SIZE 100
648     char line1[LINE_SIZE], line2[LINE_SIZE];
649     char *nextp;
650
651     if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
652         fprintf(stderr, "Usage: %s [mount\-path]\\n", argv[0]);
653         exit(EXIT_FAILURE);
654     }
655
656     /* Standard input contains mount ID and file handle information:
657
658          Line 1: <mount_id>
659          Line 2: <handle_bytes> <handle_type>   <bytes of handle in hex>
660     */
661
662     if ((fgets(line1, sizeof(line1), stdin) == NULL) ||
663            (fgets(line2, sizeof(line2), stdin) == NULL)) {
664         fprintf(stderr, "Missing mount_id / file handle\\n");
665         exit(EXIT_FAILURE);
666     }
667
668     mount_id = atoi(line1);
669
670     handle_bytes = strtoul(line2, &nextp, 0);
671
672     /* Given handle_bytes, we can now allocate file_handle structure */
673
674     fhp = malloc(sizeof(struct file_handle) + handle_bytes);
675     if (fhp == NULL)
676         errExit("malloc");
677
678     fhp\->handle_bytes = handle_bytes;
679
680     fhp\->handle_type = strtoul(nextp, &nextp, 0);
681
682     for (j = 0; j < fhp\->handle_bytes; j++)
683         fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
684
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. */
689
690     if (argc > 1)
691         mount_fd = open(argv[1], O_RDONLY);
692     else
693         mount_fd = open_mount_path_by_id(mount_id);
694
695     if (mount_fd == \-1)
696         errExit("opening mount fd");
697
698     /* Open file using handle and mount point */
699
700     fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
701     if (fd == \-1)
702         errExit("open_by_handle_at");
703
704     /* Try reading a few bytes from the file */
705
706     nread = read(fd, buf, sizeof(buf));
707     if (nread == \-1)
708         errExit("read");
709
710     printf("Read %zd bytes\\n", nread);
711
712     exit(EXIT_SUCCESS);
713 }
714 .fi
715 .SH SEE ALSO
716 .BR open (2),
717 .BR libblkid (3),
718 .BR blkid (8),
719 .BR findfs (8),
720 .BR mount (8)
721
722 The
723 .I libblkid
724 and
725 .I libmount
726 documentation in the latest
727 .I util-linux
728 release at
729 .UR https://www.kernel.org/pub/linux/utils/util-linux/
730 .UE
731 .SH COLOPHON
732 This page is part of release 3.65 of the Linux
733 .I man-pages
734 project.
735 A description of the project,
736 and information about reporting bugs,
737 can be found at
738 \%http://www.kernel.org/doc/man\-pages/.