From 7d6cab3f0d6a4cea17d062d3a93e223b15de705c Mon Sep 17 00:00:00 2001 From: "Joshua M. Clulow" Date: Mon, 28 Mar 2022 16:44:42 -0700 Subject: 14593 zpool online -e hangs forever after 14022 Reviewed by: Andy Fiddaman Reviewed by: Toomas Soome Approved by: Dan McDonald --- usr/src/lib/libzfs/common/libzfs_pool.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'usr/src') diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index 844582b3c2..6e634a81cb 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #include @@ -2799,9 +2801,11 @@ static int zpool_relabel_disk(libzfs_handle_t *hdl, const char *name, const char *msg) { char path[MAXPATHLEN]; - enum dkio_state st; int fd, error; int (*_efi_use_whole_disk)(int); + char drv[MODMAXNAMELEN]; + major_t maj; + struct stat st; if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT, "efi_use_whole_disk")) == NULL) @@ -2834,9 +2838,18 @@ zpool_relabel_disk(libzfs_handle_t *hdl, const char *name, const char *msg) * it to be checked by querying the device state, otherwise the * subsequent vdev_reopen() will very likely fail to read the device * size, faulting the pool. + * + * The dkio(4I) ioctls are implemented by the disk driver rather than + * some generic framework, so we limit its use here to drivers with + * which it has been tested. */ - st = DKIO_NONE; - (void) ioctl(fd, DKIOCSTATE, (caddr_t)&st); + if (fstat(fd, &st) == 0 && + (maj = major(st.st_rdev)) != (major_t)NODEV && + modctl(MODGETNAME, drv, sizeof (drv), &maj) == 0 && + (strcmp(drv, "blkdev") == 0 || strcmp(drv, "sd") == 0)) { + enum dkio_state dkst = DKIO_NONE; + (void) ioctl(fd, DKIOCSTATE, &dkst); + } (void) close(fd); -- cgit v1.2.3