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