]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man2/open_by_handle_at.2
_syscall.2, clock_getres.2, clone.2, copy_file_range.2, create_module.2, delete_modul...
[thirdparty/man-pages.git] / man2 / open_by_handle_at.2
CommitLineData
a827d5c6
MK
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.\"
ad5b45ab 25.TH OPEN_BY_HANDLE_AT 2 2014-06-13 "Linux" "Linux Programmer's Manual"
a827d5c6
MK
26.SH NAME
27name_to_handle_at, open_by_handle_at \- obtain handle
28for a pathname and open file via a handle
29.SH SYNOPSIS
30.nf
237f3803 31.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
a827d5c6
MK
32.B #include <sys/types.h>
33.B #include <sys/stat.h>
34.B #include <fcntl.h>
dbfe9c70 35.PP
a827d5c6
MK
36.BI "int name_to_handle_at(int " dirfd ", const char *" pathname ,
37.BI " struct file_handle *" handle ,
fb968310 38.BI " int *" mount_id ", int " flags );
dbfe9c70 39.PP
fb968310 40.BI "int open_by_handle_at(int " mount_fd ", struct file_handle *" handle ,
a827d5c6
MK
41.BI " int " flags );
42.fi
43.SH DESCRIPTION
44The
45.BR name_to_handle_at ()
46and
47.BR open_by_handle_at ()
48system calls split the functionality of
49.BR openat (2)
50into two parts:
51.BR name_to_handle_at ()
52returns an opaque handle that corresponds to a specified file;
53.BR open_by_handle_at ()
54opens the file corresponding to a handle returned by a previous call to
55.BR name_to_handle_at ()
56and returns an open file descriptor.
fb968310
MK
57.\"
58.\"
a827d5c6
MK
59.SS name_to_handle_at()
60The
61.BR name_to_handle_at ()
62system call returns a file handle and a mount ID corresponding to
fb968310
MK
63the file specified by the
64.IR dirfd
65and
66.IR pathname
67arguments.
a827d5c6
MK
68The file handle is returned via the argument
69.IR handle ,
70which is a pointer to a structure of the following form:
71
72.in +4n
73.nf
74struct 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
83It is the caller's responsibility to allocate the structure
84with a size large enough to hold the handle returned in
85.IR f_handle .
86Before the call, the
87.IR handle_bytes
88field should be initialized to contain the allocated size for
89.IR f_handle .
90(The constant
91.BR MAX_HANDLE_SZ ,
92defined in
93.IR <fcntl.h> ,
94specifies the maximum possible size for a file handle.)
95Upon successful return, the
96.IR handle_bytes
97field is updated to contain the number of bytes actually written to
98.IR f_handle .
99
100The caller can discover the required size for the
101.I file_handle
102structure by making a call in which
103.IR handle->handle_bytes
104is zero;
105in this case, the call fails with the error
106.BR EOVERFLOW
107and
108.IR handle->handle_bytes
109is set to indicate the required size;
110the caller can then use this information to allocate a structure
111of the correct size (see EXAMPLE below).
112
113Other than the use of the
114.IR handle_bytes
115field, the caller should treat the
116.IR file_handle
117structure as an opaque data type: the
118.IR handle_type
119and
120.IR f_handle
121fields are needed only by a subsequent call to
122.BR open_by_handle_at ().
123
b2fe7451
MK
124The
125.I flags
126argument is a bit mask constructed by ORing together zero or more of
127.BR AT_EMPTY_PATH
128and
129.BR AT_SYMLINK_FOLLOW ,
130described below.
131
fb968310 132Together, the
a827d5c6 133.I pathname
fb968310 134and
a827d5c6 135.I dirfd
e2199ccb 136arguments identify the file for which a handle is to be obtained.
fb968310
MK
137There are four distinct cases:
138.IP * 3
139If
140.I pathname
141is a nonempty string containing an absolute pathname,
142then a handle is returned for the file referred to by that pathname.
143In this case,
144.IR dirfd
145is ignored.
146.IP *
147If
148.I pathname
149is a nonempty string containing a relative pathname and
150.IR dirfd
a827d5c6
MK
151has the special value
152.BR AT_FDCWD ,
153then
154.I pathname
fb968310
MK
155is interpreted relative to the current working directory of the caller,
156and a handle is returned for the file to which it refers.
157.IP *
158If
159.I pathname
160is a nonempty string containing a relative pathname and
a827d5c6 161.IR dirfd
fb968310 162is a file descriptor referring to a directory, then
a827d5c6 163.I pathname
fb968310
MK
164is interpreted relative to the directory referred to by
165.IR dirfd ,
166and a handle is returned for the file to which it refers.
167(See
f29d0171 168.BR openat (2)
fb968310
MK
169for an explanation of why "directory file descriptors" are useful.)
170.IP *
a827d5c6
MK
171If
172.I pathname
fb968310
MK
173is an empty string and
174.I flags
175specifies the value
176.BR AT_EMPTY_PATH ,
177then
178.IR dirfd
179can be an open file descriptor referring to any type of file,
180or
181.BR AT_FDCWD ,
182meaning the current working directory,
183and a handle is returned for the file to which it refers.
184.PP
a827d5c6 185The
fb968310 186.I mount_id
a827d5c6
MK
187argument returns an identifier for the filesystem
188mount that corresponds to
189.IR pathname .
190This corresponds to the first field in one of the records in
191.IR /proc/self/mountinfo .
192Opening the pathname in the fifth field of that record yields a file
193descriptor for the mount point;
194that file descriptor can be used in a subsequent call to
195.BR open_by_handle_at ().
196
a827d5c6
MK
197By default,
198.BR name_to_handle_at ()
199does not dereference
200.I pathname
b2fe7451
MK
201if it is a symbolic link, and thus returns a handle for the link itself.
202If
a827d5c6 203.B AT_SYMLINK_FOLLOW
b2fe7451
MK
204is specified in
205.IR flags ,
a827d5c6 206.I pathname
b2fe7451
MK
207is dereferenced if it is a symbolic link
208(so that the call returns a handle for the file referred to by the link).
a827d5c6
MK
209.SS open_by_handle_at()
210The
211.BR open_by_handle_at ()
212system call opens the file referred to by
213.IR handle ,
214a file handle returned by a previous call to
215.BR name_to_handle_at ().
216
217The
fb968310
MK
218.IR mount_fd
219argument is a file descriptor for any object (file, directory, etc.)
220in the mounted filesystem with respect to which
a827d5c6
MK
221.IR handle
222should be interpreted.
223The special value
224.B AT_FDCWD
225can be specified, meaning the current working directory of the caller.
226
227The
228.I flags
229argument
230is as for
231.BR open (2).
fb968310
MK
232If
233.I handle
234refers to a symbolic link, the caller must specify the
235.B O_PATH
97236fae 236flag, and the symbolic link is not dereferenced; the
fb968310 237.B O_NOFOLLOW
97236fae
MK
238flag, if specified, is ignored.
239
a827d5c6
MK
240The caller must have the
241.B CAP_DAC_READ_SEARCH
242capability to invoke
243.BR open_by_handle_at ().
244.SH RETURN VALUE
245On success,
246.BR name_to_handle_at ()
247returns 0,
248and
249.BR open_by_handle_at ()
250returns a nonnegative file descriptor.
251
252In the event of an error, both system calls return \-1 and set
253.I errno
254to indicate the cause of the error.
255.SH ERRORS
256.BR name_to_handle_at ()
257and
258.BR open_by_handle_at ()
259can fail for the same errors as
3be5b709 260.BR openat (2).
a827d5c6
MK
261In addition, they can fail with the errors noted below.
262
263.BR name_to_handle_at ()
264can fail with the following errors:
265.TP
e2199ccb
MK
266.B EFAULT
267.IR pathname ,
268.IR mount_id ,
269or
270.IR handle
271points outside your accessible address space.
272.TP
a827d5c6
MK
273.B EINVAL
274.I flags
275includes an invalid bit value.
276.TP
277.B EINVAL
85ad779b 278.IR handle\->handle_bytes
a827d5c6
MK
279is greater than
280.BR MAX_HANDLE_SZ .
281.TP
fb968310
MK
282.B ENOENT
283.I pathname
284is an empty string, but
285.BR AT_EMPTY_PATH
286was not specified in
287.IR flags .
288.TP
a827d5c6
MK
289.B ENOTDIR
290The file descriptor supplied in
291.I dirfd
292does not refer to a directory,
b2fe7451 293and it is not the case that both
a827d5c6
MK
294.I flags
295includes
296.BR AT_EMPTY_PATH
297and
298.I pathname
299is an empty string.
300.TP
301.B EOPNOTSUPP
302The filesystem does not support decoding of a pathname to a file handle.
303.TP
304.B EOVERFLOW
305The
306.I handle->handle_bytes
307value passed into the call was too small.
308When this error occurs,
309.I handle->handle_bytes
310is updated to indicate the required size for the handle.
311.\"
312.\"
313.PP
314.BR open_by_handle_at ()
315can fail with the following errors:
316.TP
317.B EBADF
fb968310 318.IR mount_fd
a827d5c6
MK
319is not an open file descriptor.
320.TP
e2199ccb
MK
321.B EFAULT
322.IR handle
323points outside your accessible address space.
324.TP
a827d5c6
MK
325.B EINVAL
326.I handle->handle_bytes
327is greater than
328.BR MAX_HANDLE_SZ
329or is equal to zero.
330.TP
fb968310 331.B ELOOP
fb968310
MK
332.I handle
333refers to a symbolic link, but
334.B O_PATH
335was not specified in
336.IR flags .
337.TP
a827d5c6
MK
338.B EPERM
339The caller does not have the
340.BR CAP_DAC_READ_SEARCH
341capability.
342.TP
343.B ESTALE
344The specified
345.I handle
e2199ccb
MK
346is not valid.
347This error will occur if, for example, the file has been deleted.
a827d5c6
MK
348.SH VERSIONS
349These system calls first appeared in Linux 2.6.39.
39c98c7d 350Library support is provided in glibc since version 2.14.
a827d5c6
MK
351.SH CONFORMING TO
352These system calls are nonstandard Linux extensions.
22956293
MK
353
354FreeBSD has a broadly similar pair of system calls in the form of
355.BR getfh ()
356and
357.BR openfh ().
a827d5c6
MK
358.SH NOTES
359A file handle can be generated in one process using
360.BR name_to_handle_at ()
361and later used in a different process that calls
362.BR open_by_handle_at ().
363
e2199ccb 364Some filesystem don't support the translation of pathnames to
3ad5d1b9 365file handles, for example,
e2199ccb
MK
366.IR /proc ,
367.IR /sys ,
368and various network filesystems.
fb968310
MK
369
370A file handle may become invalid ("stale") if a file is deleted,
371or for other filesystem-specific reasons.
372Invalid handles are notified by an
373.B ESTALE
374error from
e2199ccb 375.BR open_by_handle_at ().
fb968310 376
a827d5c6
MK
377These system calls are designed for use by user-space file servers.
378For example, a user-space NFS server might generate a file handle
379and pass it to an NFS client.
380Later, when the client wants to open the file,
381it could pass the handle back to the server.
382.\" https://lwn.net/Articles/375888/
383.\" "Open by handle" - Jonathan Corbet, 2010-02-23
384This sort of functionality allows a user-space file server to operate in
385a stateless fashion with respect to the files it serves.
386
fb968310
MK
387If
388.I pathname
389refers to a symbolic link and
390.IR flags
391does not specify
392.BR AT_SYMLINK_FOLLOW ,
393then
a827d5c6 394.BR name_to_handle_at ()
fb968310 395returns a handle for the link (rather than the file to which it refers).
a827d5c6
MK
396.\" commit bcda76524cd1fa32af748536f27f674a13e56700
397The process receiving the handle can later perform operations
398on the symbolic link by converting the handle to a file descriptor using
399.BR open_by_handle_at ()
fb968310
MK
400with the
401.BR O_PATH
402flag, and then passing the file descriptor as the
a827d5c6
MK
403.IR dirfd
404argument in system calls such as
405.BR readlinkat (2)
406and
407.BR fchownat (2).
408.SS Obtaining a persistent filesystem ID
409The mount IDs in
410.IR /proc/self/mountinfo
411can be reused as filesystems are unmounted and mounted.
412Therefore, the mount ID returned by
b2fe7451 413.BR name_to_handle_at ()
a827d5c6 414(in
fb968310 415.IR *mount_id )
a827d5c6
MK
416should not be treated as a persistent identifier
417for the corresponding mounted filesystem.
418However, an application can use the information in the
419.I mountinfo
420record that corresponds to the mount ID
421to derive a persistent identifier.
422
423For example, one can use the device name in the fifth field of the
424.I mountinfo
425record to search for the corresponding device UUID via the symbolic links in
426.IR /dev/disks/by-uuid .
427(A more comfortable way of obtaining the UUID is to use the
428.\" e.g., http://stackoverflow.com/questions/6748429/using-libblkid-to-find-uuid-of-a-partition
429.BR libblkid (3)
fb968310 430library.)
a827d5c6
MK
431That process can then be reversed,
432using the UUID to look up the device name,
433and then obtaining the corresponding mount point,
434in order to produce the
fb968310 435.IR mount_fd
a827d5c6 436argument used by
e2199ccb 437.BR open_by_handle_at ().
a827d5c6
MK
438.SH EXAMPLE
439The two programs below demonstrate the use of
440.BR name_to_handle_at ()
441and
442.BR open_by_handle_at ().
443The first program
444.RI ( t_name_to_handle_at.c )
445uses
446.BR name_to_handle_at ()
447to obtain the file handle and mount ID
448for the file specified in its command-line argument;
e2199ccb 449the handle and mount ID are written to standard output.
a827d5c6
MK
450
451The second program
452.RI ( t_open_by_handle_at.c )
453reads a mount ID and file handle from standard input.
454The program then employs
455.BR open_by_handle_at ()
456to open the file using that handle.
457If an optional command-line argument is supplied, then the
fb968310 458.IR mount_fd
a827d5c6
MK
459argument for
460.BR open_by_handle_at ()
461is obtained by opening the directory named in that argument.
462Otherwise,
fb968310 463.IR mount_fd
a827d5c6
MK
464is obtained by scanning
465.IR /proc/self/mountinfo
466to find a record whose mount ID matches the mount ID
467read from standard input,
468and the mount directory specified in that record is opened.
469(These programs do not deal with the fact that mount IDs are not persistent.)
470
471The following shell session demonstrates the use of these two programs:
472
473.in +4n
474.nf
b2fe7451 475$ \fBecho 'Can you please think about it?' > cecilia.txt\fP
a827d5c6
MK
476$ \fB./t_name_to_handle_at cecilia.txt > fh\fP
477$ \fB./t_open_by_handle_at < fh\fP
478open_by_handle_at: Operation not permitted
479$ \fBsudo ./t_open_by_handle_at < fh\fP # Need CAP_SYS_ADMIN
b2fe7451 480Read 31 bytes
a827d5c6
MK
481$ \fBrm cecilia.txt\fP
482.fi
483.in
484
fb968310
MK
485Now we delete and (quickly) re-create the file so that
486it has the same content and (by chance) the same inode.
487Nevertheless,
a827d5c6 488.BR open_by_handle_at ()
269ad843
MK
489.\" Christoph Hellwig: That's why the file handles contain a generation
490.\" counter that gets incremented in this case.
fb968310
MK
491recognizes that the original file referred to by the file handle
492no longer exists.
a827d5c6
MK
493
494.in +4n
495.nf
3ad5d1b9 496$ \fBstat \-\-printf="%i\\n" cecilia.txt\fP # Display inode number
a827d5c6 4974072121
fb968310 498$ \fBrm cecilia.txt\fP
b2fe7451 499$ \fBecho 'Can you please think about it?' > cecilia.txt\fP
886f35af 500$ \fBstat \-\-printf="%i\\n" cecilia.txt\fP # Check inode number
a827d5c6
MK
5014072121
502$ \fBsudo ./t_open_by_handle_at < fh\fP
503open_by_handle_at: Stale NFS file handle
504.fi
505.in
506.SS Program source: t_name_to_handle_at.c
507\&
508.nf
509#define _GNU_SOURCE
510#include <sys/types.h>
511#include <sys/stat.h>
512#include <fcntl.h>
513#include <stdio.h>
514#include <stdlib.h>
515#include <unistd.h>
516#include <errno.h>
517#include <string.h>
518
519#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
520 } while (0)
521
522int
523main(int argc, char *argv[])
524{
525 struct file_handle *fhp;
3ad5d1b9
MK
526 int mount_id, fhsize, flags, dirfd, j;
527 char *pathname;
a827d5c6 528
3ad5d1b9 529 if (argc != 2) {
a827d5c6
MK
530 fprintf(stderr, "Usage: %s pathname\\n", argv[0]);
531 exit(EXIT_FAILURE);
532 }
533
3ad5d1b9
MK
534 pathname = argv[1];
535
a827d5c6
MK
536 /* Allocate file_handle structure */
537
3ad5d1b9 538 fhsize = sizeof(*fhp);
a827d5c6
MK
539 fhp = malloc(fhsize);
540 if (fhp == NULL)
541 errExit("malloc");
542
543 /* Make an initial call to name_to_handle_at() to discover
544 the size required for file handle */
545
3ad5d1b9
MK
546 dirfd = AT_FDCWD; /* For name_to_handle_at() calls */
547 flags = 0; /* For name_to_handle_at() calls */
a827d5c6 548 fhp\->handle_bytes = 0;
3ad5d1b9
MK
549 if (name_to_handle_at(dirfd, pathname, fhp,
550 &mount_id, flags) != \-1 || errno != EOVERFLOW) {
a827d5c6
MK
551 fprintf(stderr, "Unexpected result from name_to_handle_at()\\n");
552 exit(EXIT_FAILURE);
553 }
554
555 /* Reallocate file_handle structure with correct size */
556
557 fhsize = sizeof(struct file_handle) + fhp\->handle_bytes;
558 fhp = realloc(fhp, fhsize); /* Copies fhp\->handle_bytes */
559 if (fhp == NULL)
560 errExit("realloc");
561
562 /* Get file handle from pathname supplied on command line */
563
3ad5d1b9 564 if (name_to_handle_at(dirfd, pathname, fhp, &mount_id, flags) == \-1)
a827d5c6
MK
565 errExit("name_to_handle_at");
566
567 /* Write mount ID, file handle size, and file handle to stdout,
568 for later reuse by t_open_by_handle_at.c */
569
3ad5d1b9
MK
570 printf("%d\\n", mount_id);
571 printf("%d %d ", fhp\->handle_bytes, fhp\->handle_type);
572 for (j = 0; j < fhp\->handle_bytes; j++)
573 printf(" %02x", fhp\->f_handle[j]);
574 printf("\\n");
a827d5c6
MK
575
576 exit(EXIT_SUCCESS);
577}
578.fi
579.SS Program source: t_open_by_handle_at.c
580\&
581.nf
582#define _GNU_SOURCE
583#include <sys/types.h>
584#include <sys/stat.h>
585#include <fcntl.h>
586#include <limits.h>
587#include <stdio.h>
588#include <stdlib.h>
589#include <unistd.h>
590#include <string.h>
591
592#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
593 } while (0)
594
595/* Scan /proc/self/mountinfo to find the line whose mount ID matches
596 \(aqmount_id\(aq. (An easier way to do this is to install and use the
597 \(aqlibmount\(aq library provided by the \(aqutil\-linux\(aq project.)
598 Open the corresponding mount path and return the resulting file
599 descriptor. */
600
601static int
602open_mount_path_by_id(int mount_id)
603{
604 char *linep;
605 size_t lsize;
606 char mount_path[PATH_MAX];
3ad5d1b9
MK
607 int mi_mount_id, found;
608 ssize_t nread;
a827d5c6
MK
609 FILE *fp;
610
3ad5d1b9 611 fp = fopen("/proc/self/mountinfo", "r");
a827d5c6
MK
612 if (fp == NULL)
613 errExit("fopen");
614
3ad5d1b9
MK
615 found = 0;
616 linep = NULL;
617 while (!found) {
a827d5c6
MK
618 nread = getline(&linep, &lsize, fp);
619 if (nread == \-1)
620 break;
621
3ad5d1b9
MK
622 nread = sscanf(linep, "%d %*d %*s %*s %s",
623 &mi_mount_id, mount_path);
a827d5c6
MK
624 if (nread != 2) {
625 fprintf(stderr, "Bad sscanf()\\n");
626 exit(EXIT_FAILURE);
627 }
628
3ad5d1b9
MK
629 if (mi_mount_id == mount_id)
630 found = 1;
a827d5c6 631 }
3ad5d1b9 632 free(linep);
a827d5c6
MK
633
634 fclose(fp);
635
3ad5d1b9 636 if (!found) {
a827d5c6
MK
637 fprintf(stderr, "Could not find mount point\\n");
638 exit(EXIT_FAILURE);
639 }
640
3ad5d1b9 641 return open(mount_path, O_RDONLY);
a827d5c6
MK
642}
643
644int
645main(int argc, char *argv[])
646{
647 struct file_handle *fhp;
3ad5d1b9 648 int mount_id, fd, mount_fd, handle_bytes, j;
a827d5c6 649 ssize_t nread;
3ad5d1b9
MK
650 char buf[1000];
651#define LINE_SIZE 100
652 char line1[LINE_SIZE], line2[LINE_SIZE];
653 char *nextp;
a827d5c6 654
3ad5d1b9
MK
655 if ((argc > 1 && strcmp(argv[1], "\-\-help") == 0) || argc > 2) {
656 fprintf(stderr, "Usage: %s [mount\-path]\\n", argv[0]);
a827d5c6
MK
657 exit(EXIT_FAILURE);
658 }
659
3ad5d1b9 660 /* Standard input contains mount ID and file handle information:
a827d5c6 661
3ad5d1b9
MK
662 Line 1: <mount_id>
663 Line 2: <handle_bytes> <handle_type> <bytes of handle in hex>
664 */
a827d5c6 665
3ad5d1b9
MK
666 if ((fgets(line1, sizeof(line1), stdin) == NULL) ||
667 (fgets(line2, sizeof(line2), stdin) == NULL)) {
668 fprintf(stderr, "Missing mount_id / file handle\\n");
669 exit(EXIT_FAILURE);
670 }
a827d5c6 671
3ad5d1b9
MK
672 mount_id = atoi(line1);
673
674 handle_bytes = strtoul(line2, &nextp, 0);
675
676 /* Given handle_bytes, we can now allocate file_handle structure */
677
678 fhp = malloc(sizeof(struct file_handle) + handle_bytes);
a827d5c6
MK
679 if (fhp == NULL)
680 errExit("malloc");
681
3ad5d1b9
MK
682 fhp\->handle_bytes = handle_bytes;
683
684 fhp\->handle_type = strtoul(nextp, &nextp, 0);
685
686 for (j = 0; j < fhp\->handle_bytes; j++)
687 fhp\->f_handle[j] = strtoul(nextp, &nextp, 16);
a827d5c6
MK
688
689 /* Obtain file descriptor for mount point, either by opening
690 the pathname specified on the command line, or by scanning
691 /proc/self/mounts to find a mount that matches the \(aqmount_id\(aq
3ad5d1b9 692 that we received from stdin. */
a827d5c6
MK
693
694 if (argc > 1)
3ad5d1b9 695 mount_fd = open(argv[1], O_RDONLY);
a827d5c6
MK
696 else
697 mount_fd = open_mount_path_by_id(mount_id);
698
699 if (mount_fd == \-1)
700 errExit("opening mount fd");
701
3ad5d1b9 702 /* Open file using handle and mount point */
a827d5c6
MK
703
704 fd = open_by_handle_at(mount_fd, fhp, O_RDONLY);
705 if (fd == \-1)
706 errExit("open_by_handle_at");
707
708 /* Try reading a few bytes from the file */
709
3ad5d1b9 710 nread = read(fd, buf, sizeof(buf));
a827d5c6
MK
711 if (nread == \-1)
712 errExit("read");
3ad5d1b9
MK
713
714 printf("Read %zd bytes\\n", nread);
a827d5c6
MK
715
716 exit(EXIT_SUCCESS);
717}
718.fi
719.SH SEE ALSO
a827d5c6
MK
720.BR open (2),
721.BR libblkid (3),
b2fe7451
MK
722.BR blkid (8),
723.BR findfs (8),
a827d5c6
MK
724.BR mount (8)
725
726The
727.I libblkid
728and
729.I libmount
e2199ccb 730documentation in the latest
a827d5c6
MK
731.I util-linux
732release at
5465ae95 733.UR https://www.kernel.org/pub/linux/utils/util\-linux/
a827d5c6 734.UE