]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libzutil/os/freebsd/zutil_device_path_os.c
Vendor import of openzfs master @ 184df27eef0abdc7ab2105b21257f753834b936b
[FreeBSD/FreeBSD.git] / lib / libzutil / os / freebsd / zutil_device_path_os.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 #include <ctype.h>
23 #include <fcntl.h>
24 #include <paths.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include <sys/stat.h>
30
31 #include <libgeom.h>
32
33 #include <libzutil.h>
34
35 /*
36  * We don't strip/append partitions on FreeBSD.
37  */
38
39 /*
40  * Note: The caller must free the returned string.
41  */
42 char *
43 zfs_strip_partition(char *dev)
44 {
45         return (strdup(dev));
46 }
47
48 int
49 zfs_append_partition(char *path, size_t max_len)
50 {
51         return (strnlen(path, max_len));
52 }
53
54 /*
55  * Strip the path from a device name.
56  * On FreeBSD we only want to remove "/dev/" from the beginning of
57  * paths if present.
58  */
59 char *
60 zfs_strip_path(char *path)
61 {
62         if (strncmp(path, _PATH_DEV, sizeof (_PATH_DEV) - 1) == 0)
63                 return (path + sizeof (_PATH_DEV) - 1);
64         else
65                 return (path);
66 }
67
68 char *
69 zfs_get_underlying_path(const char *dev_name)
70 {
71
72         if (dev_name == NULL)
73                 return (NULL);
74
75         return (realpath(dev_name, NULL));
76 }
77
78 boolean_t
79 zfs_dev_is_whole_disk(const char *dev_name)
80 {
81         int fd;
82
83         fd = g_open(dev_name, 0);
84         if (fd >= 0) {
85                 g_close(fd);
86                 return (B_TRUE);
87         }
88         return (B_FALSE);
89 }
90
91 /*
92  * Wait up to timeout_ms for udev to set up the device node.  The device is
93  * considered ready when libudev determines it has been initialized, all of
94  * the device links have been verified to exist, and it has been allowed to
95  * settle.  At this point the device the device can be accessed reliably.
96  * Depending on the complexity of the udev rules this process could take
97  * several seconds.
98  */
99 int
100 zpool_label_disk_wait(const char *path, int timeout_ms)
101 {
102         int settle_ms = 50;
103         long sleep_ms = 10;
104         hrtime_t start, settle;
105         struct stat64 statbuf;
106
107         start = gethrtime();
108         settle = 0;
109
110         do {
111                 errno = 0;
112                 if ((stat64(path, &statbuf) == 0) && (errno == 0)) {
113                         if (settle == 0)
114                                 settle = gethrtime();
115                         else if (NSEC2MSEC(gethrtime() - settle) >= settle_ms)
116                                 return (0);
117                 } else if (errno != ENOENT) {
118                         return (errno);
119                 }
120
121                 usleep(sleep_ms * MILLISEC);
122         } while (NSEC2MSEC(gethrtime() - start) < timeout_ms);
123
124         return (ENODEV);
125 }
126
127 /* ARGSUSED */
128 boolean_t
129 is_mpath_whole_disk(const char *path)
130 {
131         return (B_FALSE);
132 }