diff options
author | Alexander Motin <mav@FreeBSD.org> | 2018-01-22 04:35:17 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2018-01-22 04:35:17 +0000 |
commit | 434e06c6f9363e5781c68c70d81fa717bd578c16 (patch) | |
tree | dd285f227313db29e2247ff75e9851dd19efe9ee /lib | |
parent | ee700ae0c6d039361897acd415a285e9dabe3401 (diff) | |
download | src-434e06c6f9363e5781c68c70d81fa717bd578c16.tar.gz src-434e06c6f9363e5781c68c70d81fa717bd578c16.zip |
8641 "zpool clear" and "zinject" don't work on "spare" or "replacing" vdevs
illumos/illumos-gate@2ba5f978a4f9b02da9db1b8cdd9ea5498eb00ad9
https://www.illumos.org/issues/8641:
"zpool clear" and "zinject -d" can both operate on specific vdevs, either
leaf or interior. However, due to an oversight, neither works on a "spare"
or "replacing" vdev. For example:
sudo zpool create foo raidz1 c1t5000CCA000081D61d0 c1t5000CCA000186235d0 spare c1t5000CCA000094115d0
sudo zpool replace foo c1t5000CCA000186235d0 c1t5000CCA000094115d0
$ zpool status foo pool: foo
state: ONLINE
scan: resilvered 81.5K in 0h0m with 0 errors on Fri Sep 8 10:53:03 2017
config:
NAME STATE READ WRITE CKSUM
foo ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
c1t5000CCA000081D61d0 ONLINE 0 0 0
spare-1 ONLINE 0 0 0
c1t5000CCA000186235d0 ONLINE 0 0 0
c1t5000CCA000094115d0 ONLINE 0 0 0
spares
c1t5000CCA000094115d0 INUSE currently in use
$ sudo zinject -d spare-1 -A degrade foo
cannot find device 'spare-1' in pool 'foo'
$ sudo zpool clear foo spare-1
cannot clear errors for spare-1: no such device in pool
Even though there was nothing to clear, those commands shouldn't have
reported an error. by contrast, trying to clear "raidz1-0" works just fine:
$ sudo zpool clear foo raidz1-0
Notes
Notes:
svn path=/vendor/illumos/dist/; revision=328249
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libzfs/common/libzfs_pool.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/lib/libzfs/common/libzfs_pool.c b/lib/libzfs/common/libzfs_pool.c index db03bd6c0317..578ffcaf1f6e 100644 --- a/lib/libzfs/common/libzfs_pool.c +++ b/lib/libzfs/common/libzfs_pool.c @@ -50,6 +50,7 @@ #include "zfeature_common.h" static int read_efi_label(nvlist_t *, diskaddr_t *, boolean_t *); +static boolean_t zpool_vdev_is_interior(const char *name); #define BACKUP_SLICE "s2" @@ -2072,10 +2073,7 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare, break; } - verify(strncmp(type, VDEV_TYPE_RAIDZ, - strlen(VDEV_TYPE_RAIDZ)) == 0 || - strncmp(type, VDEV_TYPE_MIRROR, - strlen(VDEV_TYPE_MIRROR)) == 0); + verify(zpool_vdev_is_interior(type)); verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID, &id) == 0); @@ -2182,10 +2180,13 @@ zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath, /* * Determine if we have an "interior" top-level vdev (i.e mirror/raidz). */ -boolean_t +static boolean_t zpool_vdev_is_interior(const char *name) { if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 || + strncmp(name, VDEV_TYPE_SPARE, strlen(VDEV_TYPE_SPARE)) == 0 || + strncmp(name, + VDEV_TYPE_REPLACING, strlen(VDEV_TYPE_REPLACING)) == 0 || strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0) return (B_TRUE); return (B_FALSE); |