summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2021-03-26 11:12:22 -0700
committerGitHub <[email protected]>2021-03-26 11:12:22 -0700
commitb85f47efd094dc9ebe210c364e235c6ef99f8417 (patch)
treee679ab81256ba2d9f373c1742735948f95280034 /lib
parent2037edbdaa80f49dd83c82d283d269c6fa3f95d7 (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')
-rw-r--r--lib/libzfs/libzfs_pool.c30
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);