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 <behlendorf1@llnl.gov> Co-authored-by: Stuart Maybee <stuart.maybee@comcast.net> Signed-off-by: Matthew Ahrens <mahrens@delphix.com> Closes #11742
This commit is contained in:
parent
2037edbdaa
commit
b85f47efd0
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user