aboutsummaryrefslogtreecommitdiff
path: root/lib/libzutil/os/linux/zutil_import_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libzutil/os/linux/zutil_import_os.c')
-rw-r--r--lib/libzutil/os/linux/zutil_import_os.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/lib/libzutil/os/linux/zutil_import_os.c b/lib/libzutil/os/linux/zutil_import_os.c
index 85f367237996..bb91dec5acff 100644
--- a/lib/libzutil/os/linux/zutil_import_os.c
+++ b/lib/libzutil/os/linux/zutil_import_os.c
@@ -6,7 +6,7 @@
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -168,27 +168,19 @@ zpool_open_func(void *arg)
* Add additional entries for paths described by this label.
*/
if (rn->rn_labelpaths) {
- char *path = NULL;
- char *devid = NULL;
- char *env = NULL;
+ const char *path = NULL;
+ const char *devid = NULL;
rdsk_node_t *slice;
avl_index_t where;
- int timeout;
int error;
if (label_paths(rn->rn_hdl, rn->rn_config, &path, &devid))
return;
- env = getenv("ZPOOL_IMPORT_UDEV_TIMEOUT_MS");
- if ((env == NULL) || sscanf(env, "%d", &timeout) != 1 ||
- timeout < 0) {
- timeout = DISK_LABEL_WAIT;
- }
-
/*
* Allow devlinks to stabilize so all paths are available.
*/
- zpool_label_disk_wait(rn->rn_name, timeout);
+ zpool_disk_wait(rn->rn_name);
if (path != NULL) {
slice = zutil_alloc(hdl, sizeof (rdsk_node_t));
@@ -582,9 +574,8 @@ zfs_device_get_physical(struct udev_device *dev, char *bufptr, size_t buflen)
* Wait up to timeout_ms for udev to set up the device node. The device is
* considered ready when libudev determines it has been initialized, all of
* the device links have been verified to exist, and it has been allowed to
- * settle. At this point the device the device can be accessed reliably.
- * Depending on the complexity of the udev rules this process could take
- * several seconds.
+ * settle. At this point the device can be accessed reliably. Depending on
+ * the complexity of the udev rules this process could take several seconds.
*/
int
zpool_label_disk_wait(const char *path, int timeout_ms)
@@ -684,6 +675,20 @@ zpool_label_disk_wait(const char *path, int timeout_ms)
}
/*
+ * Simplified version of zpool_label_disk_wait() where we wait for a device
+ * to appear using the default timeouts.
+ */
+int
+zpool_disk_wait(const char *path)
+{
+ int timeout;
+ timeout = zpool_getenv_int("ZPOOL_IMPORT_UDEV_TIMEOUT_MS",
+ DISK_LABEL_WAIT);
+
+ return (zpool_label_disk_wait(path, timeout));
+}
+
+/*
* Encode the persistent devices strings
* used for the vdev disk label
*/
@@ -767,20 +772,37 @@ no_dev:
* Rescan the enclosure sysfs path for turning on enclosure LEDs and store it
* in the nvlist * (if applicable). Like:
* vdev_enc_sysfs_path: '/sys/class/enclosure/11:0:1:0/SLOT 4'
+ *
+ * If an old path was in the nvlist, and the rescan can not find a new path,
+ * then keep the old path, since the disk may have been removed.
+ *
+ * path: The vdev path (value from ZPOOL_CONFIG_PATH)
+ * key: The nvlist_t name (like ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH)
*/
-static void
-update_vdev_config_dev_sysfs_path(nvlist_t *nv, char *path)
+void
+update_vdev_config_dev_sysfs_path(nvlist_t *nv, const char *path,
+ const char *key)
{
char *upath, *spath;
+ const char *oldpath = NULL;
+
+ (void) nvlist_lookup_string(nv, key, &oldpath);
/* Add enclosure sysfs path (if disk is in an enclosure). */
upath = zfs_get_underlying_path(path);
spath = zfs_get_enclosure_sysfs_path(upath);
if (spath) {
- nvlist_add_string(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH, spath);
+ (void) nvlist_add_string(nv, key, spath);
} else {
- nvlist_remove_all(nv, ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
+ /*
+ * We couldn't dynamically scan the disk's enclosure sysfs path.
+ * This could be because the disk went away. If there's an old
+ * enclosure sysfs path in the nvlist, then keep using it.
+ */
+ if (!oldpath) {
+ (void) nvlist_remove_all(nv, key);
+ }
}
free(upath);
@@ -795,12 +817,13 @@ sysfs_path_pool_vdev_iter_f(void *hdl_data, nvlist_t *nv, void *data)
{
(void) hdl_data, (void) data;
- char *path = NULL;
+ const char *path = NULL;
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
return (1);
/* Rescan our enclosure sysfs path for this vdev */
- update_vdev_config_dev_sysfs_path(nv, path);
+ update_vdev_config_dev_sysfs_path(nv, path,
+ ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
return (0);
}
@@ -841,7 +864,7 @@ void
update_vdev_config_dev_strs(nvlist_t *nv)
{
vdev_dev_strs_t vds;
- char *env, *type, *path;
+ const char *env, *type, *path;
uint64_t wholedisk = 0;
/*
@@ -889,7 +912,8 @@ update_vdev_config_dev_strs(nvlist_t *nv)
(void) nvlist_add_string(nv, ZPOOL_CONFIG_PHYS_PATH,
vds.vds_devphys);
}
- update_vdev_config_dev_sysfs_path(nv, path);
+ update_vdev_config_dev_sysfs_path(nv, path,
+ ZPOOL_CONFIG_VDEV_ENC_SYSFS_PATH);
} else {
/* Clear out any stale entries. */
(void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);