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:
parent
c26045b435
commit
4fc1ea9c6c
|
@ -514,9 +514,14 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
|
||||||
if (is_log)
|
if (is_log)
|
||||||
continue;
|
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);
|
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;
|
continue;
|
||||||
|
|
||||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#! /bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# This file and its contents are supplied under the terms of the
|
||||||
|
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||||
|
# You may only use this file in accordance with the terms of version
|
||||||
|
# 1.0 of the CDDL.
|
||||||
|
#
|
||||||
|
# A full copy of the text of the CDDL should have accompanied this
|
||||||
|
# source. A copy of the CDDL is also available via the Internet at
|
||||||
|
# http://www.illumos.org/license/CDDL.
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014, 2018 by Delphix. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/include/libtest.shlib
|
||||||
|
. $STF_SUITE/tests/functional/removal/removal.kshlib
|
||||||
|
|
||||||
|
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
|
||||||
|
|
||||||
|
DISK1="$TMPDIR/dsk1"
|
||||||
|
DISK2="$TMPDIR/dsk2"
|
||||||
|
DISK3="$TMPDIR/dsk3"
|
||||||
|
DISK4="$TMPDIR/dsk4"
|
||||||
|
DISKS="$DISK1 $DISK2 $DISK3 $DISK4"
|
||||||
|
|
||||||
|
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK1
|
||||||
|
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK2
|
||||||
|
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK3
|
||||||
|
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK4
|
||||||
|
|
||||||
|
function cleanup
|
||||||
|
{
|
||||||
|
default_cleanup_noexit
|
||||||
|
log_must rm -f $DISKS
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build a zpool with 2 mirror vdevs
|
||||||
|
log_must default_setup_noexit "mirror $DISK1 $DISK2 mirror $DISK3 $DISK4"
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
# Remove one of the mirrors
|
||||||
|
log_must zpool remove $TESTPOOL mirror-1
|
||||||
|
log_must wait_for_removal $TESTPOOL
|
||||||
|
|
||||||
|
# Attempt to add a single-device vdev, shouldn't work
|
||||||
|
log_mustnot zpool add $TESTPOOL $DISK3
|
||||||
|
|
||||||
|
# Force it, should work
|
||||||
|
log_must zpool add -f $TESTPOOL $DISK3
|
||||||
|
|
||||||
|
log_pass "Prevented from adding a non-mirror vdev on a mirrored zpool w/ indirect vdevs"
|
|
@ -49,7 +49,8 @@ log_mustnot zpool remove $TESTPOOL $DISK2
|
||||||
log_must wait_for_removal $TESTPOOL
|
log_must wait_for_removal $TESTPOOL
|
||||||
|
|
||||||
# Add back the first disk.
|
# Add back the first disk.
|
||||||
log_must zpool add $TESTPOOL $DISK1
|
# We use -f as we're adding a single vdev to zpool with only mirrors.
|
||||||
|
log_must zpool add -f $TESTPOOL $DISK1
|
||||||
|
|
||||||
# Now attempt to remove the mirror.
|
# Now attempt to remove the mirror.
|
||||||
log_must zpool remove $TESTPOOL mirror-1
|
log_must zpool remove $TESTPOOL mirror-1
|
||||||
|
|
Loading…
Reference in New Issue