diff options
author | Matthew Ahrens <[email protected]> | 2021-03-26 11:12:22 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-26 11:12:22 -0700 |
commit | b85f47efd094dc9ebe210c364e235c6ef99f8417 (patch) | |
tree | e679ab81256ba2d9f373c1742735948f95280034 /lib/libzfs/libzfs_pool.c | |
parent | 2037edbdaa80f49dd83c82d283d269c6fa3f95d7 (diff) |
When specifying raidz vdev name, parity count should match
When specifying the name of a RAIDZ vdev on the command line, it can be
specified as raidz-<vdevID> or raidzP-<vdevID>.
e.g. `zpool clear poolname raidz-0` or `zpool clear poolname raidz2-0`
If the parity is specified in the vdev name, it should match the actual
parity of that RAIDZ vdev, otherwise the command should fail. This
commit makes it so.
Reviewed-by: Brian Behlendorf <[email protected]>
Co-authored-by: Stuart Maybee <[email protected]>
Signed-off-by: Matthew Ahrens <[email protected]>
Closes #11742
Diffstat (limited to 'lib/libzfs/libzfs_pool.c')
-rw-r--r-- | lib/libzfs/libzfs_pool.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 0af56ec32..9ef97cd67 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -2669,6 +2669,36 @@ vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare, errno = 0; vdev_id = strtoull(idx, &end, 10); + /* + * If we are looking for a raidz and a parity is + * specified, make sure it matches. + */ + int rzlen = strlen(VDEV_TYPE_RAIDZ); + assert(rzlen == strlen(VDEV_TYPE_DRAID)); + int typlen = strlen(type); + if ((strncmp(type, VDEV_TYPE_RAIDZ, rzlen) == 0 || + strncmp(type, VDEV_TYPE_DRAID, rzlen) == 0) && + typlen != rzlen) { + uint64_t vdev_parity; + int parity = *(type + rzlen) - '0'; + + if (parity <= 0 || parity > 3 || + (typlen - rzlen) != 1) { + /* + * Nonsense parity specified, can + * never match + */ + free(type); + return (NULL); + } + verify(nvlist_lookup_uint64(nv, + ZPOOL_CONFIG_NPARITY, &vdev_parity) == 0); + if ((int)vdev_parity != parity) { + free(type); + break; + } + } + free(type); if (errno != 0) return (NULL); |