Skip to content

Commit 4fc1ea9

Browse files
authored
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
1 parent c26045b commit 4fc1ea9

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-3
lines changed

cmd/zpool/zpool_vdev.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,9 +514,14 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
514514
if (is_log)
515515
continue;
516516

517-
/* Ignore holes introduced by removing aux devices */
517+
/*
518+
* Ignore holes introduced by removing aux devices, along
519+
* with indirect vdevs introduced by previously removed
520+
* vdevs.
521+
*/
518522
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
519-
if (strcmp(type, VDEV_TYPE_HOLE) == 0)
523+
if (strcmp(type, VDEV_TYPE_HOLE) == 0 ||
524+
strcmp(type, VDEV_TYPE_INDIRECT) == 0)
520525
continue;
521526

522527
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#! /bin/ksh -p
2+
#
3+
# CDDL HEADER START
4+
#
5+
# This file and its contents are supplied under the terms of the
6+
# Common Development and Distribution License ("CDDL"), version 1.0.
7+
# You may only use this file in accordance with the terms of version
8+
# 1.0 of the CDDL.
9+
#
10+
# A full copy of the text of the CDDL should have accompanied this
11+
# source. A copy of the CDDL is also available via the Internet at
12+
# http://www.illumos.org/license/CDDL.
13+
#
14+
# CDDL HEADER END
15+
#
16+
17+
#
18+
# Copyright (c) 2014, 2018 by Delphix. All rights reserved.
19+
#
20+
21+
. $STF_SUITE/include/libtest.shlib
22+
. $STF_SUITE/tests/functional/removal/removal.kshlib
23+
24+
TMPDIR=${TMPDIR:-$TEST_BASE_DIR}
25+
26+
DISK1="$TMPDIR/dsk1"
27+
DISK2="$TMPDIR/dsk2"
28+
DISK3="$TMPDIR/dsk3"
29+
DISK4="$TMPDIR/dsk4"
30+
DISKS="$DISK1 $DISK2 $DISK3 $DISK4"
31+
32+
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK1
33+
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK2
34+
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK3
35+
log_must mkfile $(($MINVDEVSIZE * 2)) $DISK4
36+
37+
function cleanup
38+
{
39+
default_cleanup_noexit
40+
log_must rm -f $DISKS
41+
}
42+
43+
# Build a zpool with 2 mirror vdevs
44+
log_must default_setup_noexit "mirror $DISK1 $DISK2 mirror $DISK3 $DISK4"
45+
log_onexit cleanup
46+
47+
# Remove one of the mirrors
48+
log_must zpool remove $TESTPOOL mirror-1
49+
log_must wait_for_removal $TESTPOOL
50+
51+
# Attempt to add a single-device vdev, shouldn't work
52+
log_mustnot zpool add $TESTPOOL $DISK3
53+
54+
# Force it, should work
55+
log_must zpool add -f $TESTPOOL $DISK3
56+
57+
log_pass "Prevented from adding a non-mirror vdev on a mirrored zpool w/ indirect vdevs"

tests/zfs-tests/tests/functional/removal/remove_mirror.ksh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ log_mustnot zpool remove $TESTPOOL $DISK2
4949
log_must wait_for_removal $TESTPOOL
5050

5151
# Add back the first disk.
52-
log_must zpool add $TESTPOOL $DISK1
52+
# We use -f as we're adding a single vdev to zpool with only mirrors.
53+
log_must zpool add -f $TESTPOOL $DISK1
5354

5455
# Now attempt to remove the mirror.
5556
log_must zpool remove $TESTPOOL mirror-1

0 commit comments

Comments
 (0)