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(const 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 const char * 60 zfs_strip_path(const 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 boolean_t 128 is_mpath_whole_disk(const char *path) 129 { 130 (void) path; 131 return (B_FALSE); 132 } 133