diff options
author | Joshua M. Clulow <josh@sysmgr.org> | 2022-03-28 16:44:42 -0700 |
---|---|---|
committer | Joshua M. Clulow <josh@sysmgr.org> | 2022-03-28 16:44:42 -0700 |
commit | 7d6cab3f0d6a4cea17d062d3a93e223b15de705c (patch) | |
tree | 0f1fbc34678b2098bac3ab2558844c0322989897 | |
parent | fe07c600e1e51d75e87d45aef001e9d6131ecdb8 (diff) | |
download | illumos-joyent-7d6cab3f0d6a4cea17d062d3a93e223b15de705c.tar.gz |
14593 zpool online -e hangs forever after 14022
Reviewed by: Andy Fiddaman <andy@omnios.org>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_pool.c | 19 |
1 files changed, 16 insertions, 3 deletions
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 <sys/efi_partition.h> #include <sys/vtoc.h> #include <sys/zfs_ioctl.h> +#include <sys/modctl.h> +#include <sys/mkdev.h> #include <dlfcn.h> #include <libzutil.h> @@ -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); |