Skip to content

Commit

Permalink
ZED should handle spares using configured ashift
Browse files Browse the repository at this point in the history
If the zpool 'ashift' property is set then ZED should use its value
when kicking in a hotspare; with this change 512e disks can be used
as spares for VDEVs that were created with ashift=9, even if ZFS
natively detects them as 4K block devices.

Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Requires-builders: style test
  • Loading branch information
loli10K committed Nov 13, 2017
1 parent 5277f20 commit f7a56d1
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 7 deletions.
11 changes: 6 additions & 5 deletions TEST
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
#TEST_PREPARE_SHARES="yes"

### SPLAT
#TEST_SPLAT_SKIP="yes"
TEST_SPLAT_SKIP="yes"
#TEST_SPLAT_OPTIONS="-acvx"

### ztest
#TEST_ZTEST_SKIP="yes"
TEST_ZTEST_SKIP="yes"
#TEST_ZTEST_TIMEOUT=1800
#TEST_ZTEST_DIR="/var/tmp/"
#TEST_ZTEST_OPTIONS="-V"
#TEST_ZTEST_CORE_DIR="/mnt/zloop"

### zimport
#TEST_ZIMPORT_SKIP="yes"
TEST_ZIMPORT_SKIP="yes"
#TEST_ZIMPORT_DIR="/var/tmp/zimport"
#TEST_ZIMPORT_VERSIONS="master installed"
#TEST_ZIMPORT_POOLS="zol-0.6.1 zol-0.6.2 master installed"
#TEST_ZIMPORT_OPTIONS="-c"

### xfstests
#TEST_XFSTESTS_SKIP="yes"
TEST_XFSTESTS_SKIP="yes"
#TEST_XFSTESTS_URL="https://github.com/behlendorf/xfstests/archive/"
#TEST_XFSTESTS_VER="zfs.tar.gz"
#TEST_XFSTESTS_POOL="tank"
Expand All @@ -39,10 +39,11 @@
#TEST_ZFSTESTS_ITERS="1"
#TEST_ZFSTESTS_OPTIONS="-vx"
#TEST_ZFSTESTS_RUNFILE="linux.run"
TEST_ZFSTESTS_RUNFILE="issue-2562.run"
#TEST_ZFSTESTS_TAGS="functional"

### zfsstress
#TEST_ZFSSTRESS_SKIP="yes"
TEST_ZFSSTRESS_SKIP="yes"
#TEST_ZFSSTRESS_URL="https://github.com/nedbass/zfsstress/archive/"
#TEST_ZFSSTRESS_VER="master.tar.gz"
#TEST_ZFSSTRESS_RUNTIME=300
Expand Down
12 changes: 12 additions & 0 deletions cmd/zed/agents/zfs_retire.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
nvlist_t **spares;
uint_t s, nspares;
char *dev_name;
zprop_source_t source;
int ashift;

config = zpool_get_config(zhp, NULL);
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
Expand All @@ -189,6 +191,11 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
&spares, &nspares) != 0)
return;

/*
* lookup "ashift" pool property, we may need it for the replacement
*/
ashift = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &source);

replacement = fmd_nvl_alloc(hdl, FMD_SLEEP);

(void) nvlist_add_string(replacement, ZPOOL_CONFIG_TYPE,
Expand All @@ -207,6 +214,11 @@ replace_with_spare(fmd_hdl_t *hdl, zpool_handle_t *zhp, nvlist_t *vdev)
&spare_name) != 0)
continue;

/* if set, add the "ashift" pool property to the spare nvlist */
if (source != ZPROP_SRC_DEFAULT)
(void) nvlist_add_uint64(spares[s],
ZPOOL_CONFIG_ASHIFT, ashift);

(void) nvlist_add_nvlist_array(replacement,
ZPOOL_CONFIG_CHILDREN, &spares[s], 1);

Expand Down
37 changes: 37 additions & 0 deletions tests/runfiles/issue-2562.run
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#
# 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.
#

[DEFAULT]
pre = setup
quiet = False
pre_user = root
user = root
timeout = 600
post_user = root
post = cleanup
outputdir = /var/tmp/test_results

[tests/functional/fault]
tests = ['auto_online_001_pos', 'auto_replace_001_pos', 'auto_spare_001_pos',
'auto_spare_002_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos',
'auto_spare_003_pos', 'auto_spare_003_pos', 'auto_spare_003_pos']
tags = ['functional', 'fault']

2 changes: 1 addition & 1 deletion tests/runfiles/linux.run
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ tags = ['functional', 'exec']

[tests/functional/fault]
tests = ['auto_online_001_pos', 'auto_replace_001_pos', 'auto_spare_001_pos',
'auto_spare_002_pos.ksh']
'auto_spare_002_pos', 'auto_spare_003_pos']
tags = ['functional', 'fault']

[tests/functional/features/async_destroy]
Expand Down
3 changes: 2 additions & 1 deletion tests/zfs-tests/tests/functional/fault/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ dist_pkgdata_SCRIPTS = \
auto_online_001_pos.ksh \
auto_replace_001_pos.ksh \
auto_spare_001_pos.ksh \
auto_spare_002_pos.ksh
auto_spare_002_pos.ksh \
auto_spare_003_pos.ksh
99 changes: 99 additions & 0 deletions tests/zfs-tests/tests/functional/fault/auto_spare_003_pos.ksh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/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) 2017 by Intel Corporation. All rights reserved.
#

. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/include/math.shlib
. $STF_SUITE/tests/functional/fault/fault.cfg

#
# DESCRIPTION:
# Testing Fault Management Agent ZED Logic - Automated Auto-Spare Test when
# drive is faulted and a custom ashift value needs to be provided to replace it.
#
# STRATEGY:
# 1. Create a pool from 512b devices and set "ashift" pool property accordingly
# 2. Add one 512e spare device (4Kn would generate IO errors on replace)
# 3. Inject IO errors with a zinject error handler
# 4. Start a scrub
# 5. Verify the ZED kicks in the hot spare and expected pool/device status
# 6. Clear the fault
# 7. Verify the hot spare is available and expected pool/device status
#

verify_runnable "both"

function cleanup
{
log_must zinject -c all
destroy_pool $TESTPOOL
rm -f $SAFE_DEVICE $FAIL_DEVICE
}

log_assert "ZED should replace a device using the configured ashift property"
log_onexit cleanup

SAFE_DEVICE="$TEST_BASE_DIR/safe-dev"
FAIL_DEVICE="$TEST_BASE_DIR/fail-dev"

# 1. Create a pool from 512b devices and set "ashift" pool property accordingly
for vdev in $SAFE_DEVICE $FAIL_DEVICE; do
truncate -s $SPA_MINDEVSIZE $vdev
done
log_must zpool create -f $TESTPOOL mirror $SAFE_DEVICE $FAIL_DEVICE
# NOTE: file VDEVs should be added as 512b devices, verify this "just in case"
#for vdev in $SAFE_DEVICE $FAIL_DEVICE; do
# XXX: math.shlib verify_eq "9" "$(zdb -e -l $vdev | awk '/ashift: /{print $2}')" "ashift"
#done
log_must zpool set ashift=9 $TESTPOOL

# 2. Add one 512e spare device (4Kn would generate IO errors on replace)
# NOTE: must be larger than the existing 512b devices, add 32m of fudge
# XXX: update load_scsi_debug (blkdev.shlib) to handle sector_size/physblk_exp params
modprobe -r scsi_debug
log_must modprobe scsi_debug dev_size_mb=$(($SPA_MINDEVSIZE/1024/1024+32)) add_host=1 num_tgts=1 max_luns=1 sector_size=512 physblk_exp=3
block_device_wait
SPARE_DEVICE=$(get_debug_device)
log_must zpool add $TESTPOOL spare $SPARE_DEVICE

# 3. Inject IO errors with a zinject error handler
log_must zinject -d $FAIL_DEVICE -e io -T all -f 100 $TESTPOOL

# 4. Start a scrub
log_must zpool scrub $TESTPOOL

# 5. Verify the ZED kicks in a hot spare and expected pool/device status
log_note "Wait for ZED to auto-spare"
log_must wait_vdev_state $TESTPOOL $FAIL_DEVICE "FAULTED" 60
log_must wait_vdev_state $TESTPOOL $SPARE_DEVICE "ONLINE" 60
log_must wait_hotspare_state $TESTPOOL $SPARE_DEVICE "INUSE"
log_must check_state $TESTPOOL "" "DEGRADED"

# 6. Clear the fault
log_must zinject -c all
log_must zpool clear $TESTPOOL $FAIL_DEVICE

# 7. Verify the hot spare is available and expected pool/device status
log_must wait_vdev_state $TESTPOOL $FAIL_DEVICE "ONLINE" 60
log_must wait_hotspare_state $TESTPOOL $SPARE_DEVICE "AVAIL"
log_must is_pool_resilvered $TESTPOOL
log_must check_state $TESTPOOL "" "ONLINE"

log_pass "ZED successfully replaces a device using the configured ashift property"

0 comments on commit f7a56d1

Please sign in to comment.