zpool: fix redundancy check after vdev removal

The presence of indirect vdevs was confusing get_redundancy(), which
considered a pool with e.g. only mirror top-level vdevs and at least
one indirect vdev (due to the removal of a previous vdev) as already
having a broken redundancy, which is not the case. This lead to the
possibility of compromising the redundancy of a pool by adding
mismatched vdevs without requiring the use of `-f`, and with no
visible notice or warning.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Stéphane Lesimple <speed47_github@speed47.net>
Closes #13705
Closes #13711
This commit is contained in:
Stéphane Lesimple
2022-08-05 03:02:57 +03:00
committed by GitHub
parent c26045b435
commit 4fc1ea9c6c
3 changed files with 66 additions and 3 deletions
+7 -2
View File
@@ -514,9 +514,14 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
if (is_log)
continue;
/* Ignore holes introduced by removing aux devices */
/*
* Ignore holes introduced by removing aux devices, along
* with indirect vdevs introduced by previously removed
* vdevs.
*/
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
if (strcmp(type, VDEV_TYPE_HOLE) == 0)
if (strcmp(type, VDEV_TYPE_HOLE) == 0 ||
strcmp(type, VDEV_TYPE_INDIRECT) == 0)
continue;
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,