OpenZFS 9102 - zfs should be able to initialize storage devices

PROBLEM
========

The first access to a block incurs a performance penalty on some platforms
(e.g. AWS's EBS, VMware VMDKs). Therefore we recommend that volumes are
"thick provisioned", where supported by the platform (VMware). This can
create a large delay in getting a new virtual machines up and running (or
adding storage to an existing Engine). If the thick provision step is
omitted, write performance will be suboptimal until all blocks on the LUN
have been written.

SOLUTION
=========

This feature introduces a way to 'initialize' the disks at install or in the
background to make sure we don't incur this first read penalty.

When an entire LUN is added to ZFS, we make all space available immediately,
and allow ZFS to find unallocated space and zero it out. This works with
concurrent writes to arbitrary offsets, ensuring that we don't zero out
something that has been (or is in the middle of being) written. This scheme
can also be applied to existing pools (affecting only free regions on the
vdev). Detailed design:
        - new subcommand:zpool initialize [-cs] <pool> [<vdev> ...]
                - start, suspend, or cancel initialization
        - Creates new open-context thread for each vdev
        - Thread iterates through all metaslabs in this vdev
        - Each metaslab:
                - select a metaslab
                - load the metaslab
                - mark the metaslab as being zeroed
                - walk all free ranges within that metaslab and translate
                  them to ranges on the leaf vdev
                - issue a "zeroing" I/O on the leaf vdev that corresponds to
                  a free range on the metaslab we're working on
                - continue until all free ranges for this metaslab have been
                  "zeroed"
                - reset/unmark the metaslab being zeroed
                - if more metaslabs exist, then repeat above tasks.
                - if no more metaslabs, then we're done.

        - progress for the initialization is stored on-disk in the vdev’s
          leaf zap object. The following information is stored:
                - the last offset that has been initialized
                - the state of the initialization process (i.e. active,
                  suspended, or canceled)
                - the start time for the initialization

        - progress is reported via the zpool status command and shows
          information for each of the vdevs that are initializing

Porting notes:
- Added zfs_initialize_value module parameter to set the pattern
  written by "zpool initialize".
- Added zfs_vdev_{initializing,removal}_{min,max}_active module options.

Authored by: George Wilson <george.wilson@delphix.com>
Reviewed by: John Wren Kennedy <john.kennedy@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: loli10K <ezomori.nozomu@gmail.com>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Approved by: Richard Lowe <richlowe@richlowe.net>
Signed-off-by: Tim Chase <tim@chase2k.com>
Ported-by: Tim Chase <tim@chase2k.com>

OpenZFS-issue: https://www.illumos.org/issues/9102
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/c3963210eb
Closes #8230
This commit is contained in:
George Wilson
2018-12-19 07:54:59 -07:00
committed by Brian Behlendorf
parent c87db59196
commit 619f097693
54 changed files with 2743 additions and 30 deletions
+15
View File
@@ -397,6 +397,21 @@ pre =
post =
tags = ['functional', 'cli_root', 'zpool_labelclear']
[tests/functional/cli_root/zpool_initialize]
tests = ['zpool_initialize_attach_detach_add_remove',
'zpool_initialize_import_export',
'zpool_initialize_offline_export_import_online',
'zpool_initialize_online_offline',
'zpool_initialize_split',
'zpool_initialize_start_and_cancel_neg',
'zpool_initialize_start_and_cancel_pos',
'zpool_initialize_suspend_resume',
'zpool_initialize_unsupported_vdevs',
'zpool_initialize_verify_checksums',
'zpool_initialize_verify_initialized']
pre =
tags = ['functional', 'cli_root', 'zpool_initialize']
[tests/functional/cli_root/zpool_offline]
tests = ['zpool_offline_001_pos', 'zpool_offline_002_neg',
'zpool_offline_003_pos']
@@ -642,6 +642,22 @@ test_unload_key(const char *dataset)
IOC_INPUT_TEST(ZFS_IOC_UNLOAD_KEY, dataset, NULL, NULL, EACCES);
}
static void
test_vdev_initialize(const char *pool)
{
nvlist_t *required = fnvlist_alloc();
nvlist_t *vdev_guids = fnvlist_alloc();
fnvlist_add_uint64(vdev_guids, "path", 0xdeadbeefdeadbeef);
fnvlist_add_uint64(required, ZPOOL_INITIALIZE_COMMAND,
POOL_INITIALIZE_DO);
fnvlist_add_nvlist(required, ZPOOL_INITIALIZE_VDEVS, vdev_guids);
IOC_INPUT_TEST(ZFS_IOC_POOL_INITIALIZE, pool, required, NULL, EINVAL);
nvlist_free(vdev_guids);
nvlist_free(required);
}
static int
zfs_destroy(const char *dataset)
{
@@ -732,6 +748,8 @@ zfs_ioc_input_tests(const char *pool)
test_change_key(dataset);
test_unload_key(dataset);
test_vdev_initialize(pool);
/*
* cleanup
*/
@@ -869,6 +887,7 @@ validate_ioc_values(void)
ZFS_IOC_BASE + 76 == ZFS_IOC_REMAP &&
ZFS_IOC_BASE + 77 == ZFS_IOC_POOL_CHECKPOINT &&
ZFS_IOC_BASE + 78 == ZFS_IOC_POOL_DISCARD_CHECKPOINT &&
ZFS_IOC_BASE + 79 == ZFS_IOC_POOL_INITIALIZE &&
LINUX_IOC_BASE + 1 == ZFS_IOC_EVENTS_NEXT &&
LINUX_IOC_BASE + 2 == ZFS_IOC_EVENTS_CLEAR &&
LINUX_IOC_BASE + 3 == ZFS_IOC_EVENTS_SEEK);
+1
View File
@@ -82,6 +82,7 @@ export SYSTEM_FILES='arp
mv
net
nproc
od
openssl
parted
pax
@@ -46,6 +46,7 @@ SUBDIRS = \
zpool_get \
zpool_history \
zpool_import \
zpool_initialize \
zpool_labelclear \
zpool_offline \
zpool_online \
@@ -150,7 +150,7 @@ function do_testing #<clear type> <vdevs>
#
# Make errors to the testing pool by overwrite the vdev device with
# /usr/bin/dd command. We do not want to have a full overwrite. That
# dd command. We do not want to have a full overwrite. That
# may cause the system panic. So, we should skip the vdev label space.
#
(( i = $RANDOM % 3 ))
@@ -0,0 +1,18 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zpool_initialize
dist_pkgdata_SCRIPTS = \
cleanup.ksh \
zpool_initialize_attach_detach_add_remove.ksh \
zpool_initialize_import_export.ksh \
zpool_initialize.kshlib \
zpool_initialize_offline_export_import_online.ksh \
zpool_initialize_online_offline.ksh \
zpool_initialize_split.ksh \
zpool_initialize_start_and_cancel_neg.ksh \
zpool_initialize_start_and_cancel_pos.ksh \
zpool_initialize_suspend_resume.ksh \
zpool_initialize_unsupported_vdevs.ksh \
zpool_initialize_verify_checksums.ksh \
zpool_initialize_verify_initialized.ksh
dist_pkgdata_DATA = \
zpool_initialize.kshlib
@@ -0,0 +1,31 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
verify_runnable "global"
default_cleanup
@@ -0,0 +1,43 @@
#
# 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) 2016 by Delphix. All rights reserved.
#
function initialize_prog_line # pool disk
{
typeset pool="$1"
typeset disk="$2"
zpool status "$pool" | grep "$disk" | grep "initialized"
}
function initialize_progress # pool disk
{
initialize_prog_line "$1" "$2" | \
sed 's/.*(\([0-9]\{1,\}\)% initialized.*/\1/g'
}
function cleanup
{
if poolexists $TESTPOOL; then
log_must zpool destroy -f $TESTPOOL
fi
if poolexists $TESTPOOL1; then
log_must zpool destroy -f $TESTPOOL1
fi
}
log_onexit cleanup
@@ -0,0 +1,68 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Detaching/attaching, adding/removing data devices works with initializing.
#
# STRATEGY:
# 1. Create a single-disk pool.
# 2. Start initializing.
# 3. Attach a second disk, ensure initializing continues.
# 4. Detach the second disk, ensure initializing continues.
# 5. Add a second disk, ensure initializing continues.
# 6. Remove the first disk, ensure initializing stops.
#
DISK1="$(echo $DISKS | cut -d' ' -f1)"
DISK2="$(echo $DISKS | cut -d' ' -f2)"
log_must zpool create -f $TESTPOOL $DISK1
log_must zpool initialize $TESTPOOL $DISK1
progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ -z "$progress" ]] && log_fail "Initializing did not start"
log_must zpool attach $TESTPOOL $DISK1 $DISK2
new_progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ "$progress" -le "$new_progress" ]] || \
log_fail "Lost initializing progress on demotion to child vdev"
progress="$new_progress"
log_must zpool detach $TESTPOOL $DISK2
new_progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ "$progress" -le "$new_progress" ]] || \
log_fail "Lost initializing progress on promotion to top vdev"
progress="$new_progress"
log_must zpool add $TESTPOOL $DISK2
log_must zpool remove $TESTPOOL $DISK1
[[ -z "$(initialize_prog_line $TESTPOOL $DISK1)" ]] || \
log_fail "Initializing continued after initiating removal"
log_pass "Initializing worked as expected across attach/detach and add/remove"
@@ -0,0 +1,78 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Initializing automatically resumes across import/export.
#
# STRATEGY:
# 1. Create a one-disk pool.
# 2. Start initializing and verify that initializing is active.
# 3. Export the pool.
# 4. Import the pool.
# 5. Verify that initializing resumes and progress does not regress.
# 6. Suspend initializing.
# 7. Repeat steps 3-4.
# 8. Verify that progress does not regress but initializing is still suspended.
#
DISK1=${DISKS%% *}
log_must zpool create -f $TESTPOOL $DISK1
log_must zpool initialize $TESTPOOL
sleep 2
progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ -z "$progress" ]] && log_fail "Initializing did not start"
log_must zpool export $TESTPOOL
log_must zpool import $TESTPOOL
new_progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ -z "$new_progress" ]] && log_fail "Initializing did not restart after import"
[[ "$progress" -le "$new_progress" ]] || \
log_fail "Initializing lost progress after import"
log_mustnot eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
log_must zpool initialize -s $TESTPOOL $DISK1
action_date="$(initialize_prog_line $TESTPOOL $DISK1 | \
sed 's/.*ed at \(.*\)).*/\1/g')"
log_must zpool export $TESTPOOL
log_must zpool import $TESTPOOL
new_action_date=$(initialize_prog_line $TESTPOOL $DISK1 | \
sed 's/.*ed at \(.*\)).*/\1/g')
[[ "$action_date" != "$new_action_date" ]] && \
log_fail "Initializing action date did not persist across export/import"
[[ "$new_progress" -le "$(initialize_progress $TESTPOOL $DISK1)" ]] || \
log_fail "Initializing lost progress after import"
log_must eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
log_pass "Initializing retains state as expected across export/import"
@@ -0,0 +1,66 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Miscellaneous complex sequences of operations function as expected.
#
# STRATEGY:
# 1. Create a pool with a two-way mirror.
# 2. Start initializing, offline, export, import, online and verify that
# initializing state is preserved / initializing behaves as expected
# at each step.
#
DISK1="$(echo $DISKS | cut -d' ' -f1)"
DISK2="$(echo $DISKS | cut -d' ' -f2)"
log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
log_must zpool initialize $TESTPOOL $DISK1
log_must zpool offline $TESTPOOL $DISK1
progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ -z "$progress" ]] && log_fail "Initializing did not start"
log_mustnot eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
log_must zpool export $TESTPOOL
log_must zpool import $TESTPOOL
new_progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ -z "$new_progress" ]] && log_fail "Initializing did not start after import"
[[ "$new_progress" -ge "$progress" ]] || \
log_fail "Initializing lost progress after import"
log_mustnot eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
log_must zpool online $TESTPOOL $DISK1
new_progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ "$new_progress" -ge "$progress" ]] || \
log_fail "Initializing lost progress after online"
log_pass "Initializing behaves as expected at each step of:" \
"initialize + offline + export + import + online"
@@ -0,0 +1,74 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Initializing automatically resumes across offline/online.
#
# STRATEGY:
# 1. Create a pool with a two-way mirror.
# 2. Start initializing one of the disks and verify that initializing is active.
# 3. Offline the disk.
# 4. Online the disk.
# 5. Verify that initializing resumes and progress does not regress.
# 6. Suspend initializing.
# 7. Repeat steps 3-4 and verify that initializing does not resume.
#
DISK1=${DISKS%% *}
DISK2="$(echo $DISKS | cut -d' ' -f2)"
log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
log_must zpool initialize $TESTPOOL $DISK1
log_must zpool offline $TESTPOOL $DISK1
progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ -z "$progress" ]] && log_fail "Initializing did not start"
log_must zpool online $TESTPOOL $DISK1
new_progress="$(initialize_progress $TESTPOOL $DISK1)"
[[ -z "$new_progress" ]] && \
log_fail "Initializing did not restart after onlining"
[[ "$progress" -le "$new_progress" ]] || \
log_fail "Initializing lost progress after onlining"
log_mustnot eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
log_must zpool initialize -s $TESTPOOL $DISK1
action_date="$(initialize_prog_line $TESTPOOL $DISK1 | \
sed 's/.*ed at \(.*\)).*/\1/g')"
log_must zpool offline $TESTPOOL $DISK1
log_must zpool online $TESTPOOL $DISK1
new_action_date=$(initialize_prog_line $TESTPOOL $DISK1 | \
sed 's/.*ed at \(.*\)).*/\1/g')
[[ "$action_date" != "$new_action_date" ]] && \
log_fail "Initializing action date did not persist across offline/online"
log_must eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
log_pass "Initializing performs as expected across offline/online"
@@ -0,0 +1,64 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Initializing state is preserved across zpool split.
#
# STRATEGY:
# 1. Create a pool with a two-way mirror.
# 2. Start initializing both devices.
# 3. Split the pool. Ensure initializing continues on the original.
# 4. Import the new pool. Ensure initializing resumes on it.
#
DISK1="$(echo $DISKS | cut -d' ' -f1)"
DISK2="$(echo $DISKS | cut -d' ' -f2)"
POOL2="${TESTPOOL}_split"
log_must zpool create -f $TESTPOOL mirror $DISK1 $DISK2
log_must zpool initialize $TESTPOOL $DISK1 $DISK2
orig_prog1="$(initialize_progress $TESTPOOL $DISK1)"
orig_prog2="$(initialize_progress $TESTPOOL $DISK2)"
[[ -z "$orig_prog1" ]] && log_fail "Initializing did not start"
log_must zpool split $TESTPOOL $TESTPOOL1 $DISK2
# Ensure initializing continued as expected on the original pool.
[[ "$(initialize_progress $TESTPOOL $DISK1)" -ge "$orig_prog1" ]] || \
log_fail "Initializing lost progress on original pool"
log_mustnot eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
log_must zpool import $TESTPOOL1
[[ "$(initialize_progress $TESTPOOL1 $DISK2)" -ge "$orig_prog2" ]] || \
log_fail "Initializing lost progress on split pool"
log_mustnot eval "initialize_prog_line $TESTPOOL1 $DISK1 | grep suspended"
log_pass "Initializing behaves as expected on zpool split"
@@ -0,0 +1,60 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Cancelling and suspending initialize doesn't work if not all specified vdevs
# are being initialized.
#
# STRATEGY:
# 1. Create a three-disk pool.
# 2. Start initializing and verify that initializing is active.
# 3. Try to cancel and suspend initializing on the non-initializing disks.
# 4. Try to re-initialize the currently initializing disk.
#
DISK1=${DISKS%% *}
DISK2="$(echo $DISKS | cut -d' ' -f2)"
DISK3="$(echo $DISKS | cut -d' ' -f3)"
log_must zpool list -v
log_must zpool create -f $TESTPOOL $DISK1 $DISK2 $DISK3
log_must zpool initialize $TESTPOOL $DISK1
[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] && \
log_fail "Initialize did not start"
log_mustnot zpool initialize -c $TESTPOOL $DISK2
log_mustnot zpool initialize -c $TESTPOOL $DISK2 $DISK3
log_mustnot zpool initialize -s $TESTPOOL $DISK2
log_mustnot zpool initialize -s $TESTPOOL $DISK2 $DISK3
log_mustnot zpool initialize $TESTPOOL $DISK1
log_pass "Nonsensical initialize operations fail"
@@ -0,0 +1,52 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Starting and stopping an initialize works.
#
# STRATEGY:
# 1. Create a one-disk pool.
# 2. Start initializing and verify that initializing is active.
# 3. Cancel initializing and verify that initializing is not active.
#
DISK1=${DISKS%% *}
log_must zpool create -f $TESTPOOL $DISK1
log_must zpool initialize $TESTPOOL
[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] && \
log_fail "Initialize did not start"
log_must zpool initialize -c $TESTPOOL
[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] || \
log_fail "Initialize did not stop"
log_pass "Initialize start + cancel works"
@@ -0,0 +1,63 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Suspending and resuming initializing works.
#
# STRATEGY:
# 1. Create a one-disk pool.
# 2. Start initializing and verify that initializing is active.
# 3. Wait 3 seconds, then suspend initializing and verify that the progress
# reporting says so.
# 4. Wait 5 seconds and ensure initializing progress doesn't advance.
# 5. Restart initializing and verify that the progress doesn't regress.
#
DISK1=${DISKS%% *}
log_must zpool create -f $TESTPOOL $DISK1
log_must zpool initialize $TESTPOOL
[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] && \
log_fail "Initializing did not start"
sleep 5
log_must zpool initialize -s $TESTPOOL
log_must eval "initialize_prog_line $TESTPOOL $DISK1 | grep suspended"
progress="$(initialize_progress $TESTPOOL $DISK1)"
sleep 3
[[ "$progress" -eq "$(initialize_progress $TESTPOOL $DISK1)" ]] || \
log_fail "Initializing progress advanced while suspended"
log_must zpool initialize $TESTPOOL $DISK1
[[ "$progress" -le "$(initialize_progress $TESTPOOL $DISK1)" ]] ||
log_fail "Initializing progress regressed after resuming"
log_pass "Suspend + resume initializing works as expected"
@@ -0,0 +1,74 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Attempting to initialize unsupported vdevs should fail.
#
# STRATEGY:
# 1. Create a pool with the following configuration:
# root
# mirror
# vdev0
# vdev1 (offline)
# cache
# vdev2
# spare
# vdev3
# 2. Try to initialize vdev1, vdev2, and vdev3. Ensure that all 3 fail.
#
function cleanup
{
if datasetexists $TESTPOOL; then
log_must zpool destroy -f $TESTPOOL
fi
if [[ -d $TESTDIR ]]; then
log_must rm -rf $TESTDIR
fi
}
log_onexit cleanup
log_must mkdir $TESTDIR
set -A FDISKS
for n in {0..2}; do
log_must mkfile $MINVDEVSIZE $TESTDIR/vdev$n
FDISKS+=("$TESTDIR/vdev$n")
done
FDISKS+=("${DISKS%% *}")
log_must zpool create $TESTPOOL mirror ${FDISKS[0]} ${FDISKS[1]} \
spare ${FDISKS[2]} cache ${FDISKS[3]}
log_must zpool offline $TESTPOOL ${FDISKS[1]}
log_mustnot zpool initialize $TESTPOOL mirror-0
for n in {1..3}; do
log_mustnot zpool initialize $TESTPOOL ${FDISKS[$n]}
done
log_pass "Attempting to initialize failed on unsupported devices"
@@ -0,0 +1,59 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# Initializing does not cause file corruption.
#
# STRATEGY:
# 1. Create a one-disk pool.
# 2. Write data to the pool.
# 3. Start initializing and verify that initializing is active.
# 4. Write more data to the pool.
# 5. Run zdb to validate checksums.
#
DISK1=${DISKS%% *}
log_must zpool create -f $TESTPOOL $DISK1
log_must dd if=/dev/urandom of=/$TESTPOOL/file1 bs=1M count=30
log_must sync
log_must zpool initialize $TESTPOOL
log_must zdb -cc $TESTPOOL
[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] && \
log_fail "Initializing did not start"
log_must dd if=/dev/urandom of=/$TESTPOOL/file2 bs=1M count=30
log_must sync
log_must zdb -cc $TESTPOOL
log_pass "Initializing does not corrupt existing or new data"
@@ -0,0 +1,89 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2016 by Delphix. All rights reserved.
#
. $STF_SUITE/include/libtest.shlib
. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
#
# DESCRIPTION:
# After initializing, the disk is actually initialized.
#
# STRATEGY:
# 1. Create a one-disk pool.
# 2. Initialize the disk to completion.
# 3. Load all metaslabs that don't have a spacemap, and make sure the entire
# metaslab has been filled with the initializing pattern (deadbeef).
#
function cleanup
{
set_tunable64 zfs_initialize_value $ORIG_PATTERN
zpool import -d $TESTDIR $TESTPOOL
if datasetexists $TESTPOOL ; then
zpool destroy -f $TESTPOOL
fi
if [[ -d "$TESTDIR" ]]; then
rm -rf "$TESTDIR"
fi
}
log_onexit cleanup
PATTERN="deadbeefdeadbeef"
SMALLFILE="$TESTDIR/smallfile"
ORIG_PATTERN=$(get_tunable zfs_initialize_value)
log_must set_tunable64 zfs_initialize_value $(printf %llu 0x$PATTERN)
log_must mkdir "$TESTDIR"
log_must mkfile $MINVDEVSIZE "$SMALLFILE"
log_must zpool create $TESTPOOL "$SMALLFILE"
log_must zpool initialize $TESTPOOL
while [[ "$(initialize_progress $TESTPOOL $SMALLFILE)" -lt "100" ]]; do
sleep 0.5
done
log_must zpool export $TESTPOOL
spacemaps=0
bs=512
while read -r sm; do
typeset offset="$(echo $sm | cut -d ' ' -f1)"
typeset size="$(echo $sm | cut -d ' ' -f2)"
spacemaps=$((spacemaps + 1))
offset=$(((4 * 1024 * 1024) + 16#$offset))
out=$(dd if=$SMALLFILE skip=$(($offset / $bs)) \
count=$(($size / $bs)) bs=$bs 2>/dev/null | od -t x8 -Ad)
echo "$out" | log_must egrep "$PATTERN|\*|$size"
done <<< "$(zdb -p $TESTDIR -Pme $TESTPOOL | egrep 'spacemap[ ]+0 ' | \
awk '{print $4, $8}')"
if [[ $spacemaps -eq 0 ]];then
log_fail "Did not find any empty space maps to check"
else
log_pass "Initializing wrote appropriate amount to disk"
fi