diff options
Diffstat (limited to 'lib/libzfs')
-rw-r--r-- | lib/libzfs/libzfs_import.c | 72 | ||||
-rw-r--r-- | lib/libzfs/libzfs_pool.c | 14 |
2 files changed, 70 insertions, 16 deletions
diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c index 7d2f0e903..d2c7d98f9 100644 --- a/lib/libzfs/libzfs_import.c +++ b/lib/libzfs/libzfs_import.c @@ -146,6 +146,21 @@ zfs_device_get_devid(struct udev_device *dev, char *bufptr, size_t buflen) } /* + * For volumes use the persistent /dev/zvol/dataset identifier + */ + entry = udev_device_get_devlinks_list_entry(dev); + while (entry != NULL) { + const char *name; + + name = udev_list_entry_get_name(entry); + if (strncmp(name, ZVOL_ROOT, strlen(ZVOL_ROOT)) == 0) { + (void) strlcpy(bufptr, name, buflen); + return (0); + } + entry = udev_list_entry_get_next(entry); + } + + /* * NVME 'by-id' symlinks are similar to bus case */ struct udev_device *parent; @@ -187,26 +202,57 @@ int zfs_device_get_physical(struct udev_device *dev, char *bufptr, size_t buflen) { const char *physpath = NULL; + struct udev_list_entry *entry; /* - * Normal disks use ID_PATH for their physical path. Device mapper - * devices are virtual and don't have a physical path. For them we - * use ID_VDEV instead, which is setup via the /etc/vdev_id.conf file. - * ID_VDEV provides a persistent path to a virtual device. If you - * don't have vdev_id.conf setup, you cannot use multipath autoreplace. + * Normal disks use ID_PATH for their physical path. */ - if (!((physpath = udev_device_get_property_value(dev, "ID_PATH")) && - physpath[0])) { - if (!((physpath = - udev_device_get_property_value(dev, "ID_VDEV")) && - physpath[0])) { - return (ENODATA); + physpath = udev_device_get_property_value(dev, "ID_PATH"); + if (physpath != NULL && strlen(physpath) > 0) { + (void) strlcpy(bufptr, physpath, buflen); + return (0); + } + + /* + * Device mapper devices are virtual and don't have a physical + * path. For them we use ID_VDEV instead, which is setup via the + * /etc/vdev_id.conf file. ID_VDEV provides a persistent path + * to a virtual device. If you don't have vdev_id.conf setup, + * you cannot use multipath autoreplace with device mapper. + */ + physpath = udev_device_get_property_value(dev, "ID_VDEV"); + if (physpath != NULL && strlen(physpath) > 0) { + (void) strlcpy(bufptr, physpath, buflen); + return (0); + } + + /* + * For ZFS volumes use the persistent /dev/zvol/dataset identifier + */ + entry = udev_device_get_devlinks_list_entry(dev); + while (entry != NULL) { + physpath = udev_list_entry_get_name(entry); + if (strncmp(physpath, ZVOL_ROOT, strlen(ZVOL_ROOT)) == 0) { + (void) strlcpy(bufptr, physpath, buflen); + return (0); } + entry = udev_list_entry_get_next(entry); } - (void) strlcpy(bufptr, physpath, buflen); + /* + * For all other devices fallback to using the by-uuid name. + */ + entry = udev_device_get_devlinks_list_entry(dev); + while (entry != NULL) { + physpath = udev_list_entry_get_name(entry); + if (strncmp(physpath, "/dev/disk/by-uuid", 17) == 0) { + (void) strlcpy(bufptr, physpath, buflen); + return (0); + } + entry = udev_list_entry_get_next(entry); + } - return (0); + return (ENODATA); } boolean_t diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 8f2eedec8..d19ca7714 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -2283,17 +2283,25 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare, } /* - * Given a physical path (minus the "/devices" prefix), find the - * associated vdev. + * Given a physical path or guid, find the associated vdev. */ nvlist_t * zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath, boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log) { nvlist_t *search, *nvroot, *ret; + uint64_t guid; + char *end; verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0); - verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath) == 0); + + guid = strtoull(ppath, &end, 0); + if (guid != 0 && *end == '\0') { + verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0); + } else { + verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, + ppath) == 0); + } verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); |