mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Add support for parallel pool exports
Changed spa_export_common() such that it no longer holds the spa_namespace_lock for the entire duration and instead sets spa_export_thread to indicate an import is in progress on the spa. This allows for an export to a diffent pool to proceed in parallel while an export is still processing potentially long operations like spa_unload_log_sm_flush_all(). Calls like spa_lookup() and spa_vdev_enter() that rely on the spa_namespace_lock to serialize them against a concurrent export, now wait for any in-progress export thread to complete before proceeding. The 'zpool import -a' sub-command also provides multi-threaded support, using a thread pool to submit the exports in parallel. Sponsored-By: Klara Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: George Wilson <gwilson@delphix.com> Signed-off-by: Don Brady <don.brady@klarasystems.com> Closes #16153
This commit is contained in:
committed by
Brian Behlendorf
parent
abec7dcd30
commit
975a13259b
@@ -430,7 +430,8 @@ tags = ['functional', 'cli_root', 'zpool_events']
|
||||
|
||||
[tests/functional/cli_root/zpool_export]
|
||||
tests = ['zpool_export_001_pos', 'zpool_export_002_pos',
|
||||
'zpool_export_003_neg', 'zpool_export_004_pos']
|
||||
'zpool_export_003_neg', 'zpool_export_004_pos',
|
||||
'zpool_export_parallel_pos', 'zpool_export_parallel_admin']
|
||||
tags = ['functional', 'cli_root', 'zpool_export']
|
||||
|
||||
[tests/functional/cli_root/zpool_get]
|
||||
|
||||
@@ -1084,6 +1084,8 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||
functional/cli_root/zpool_export/zpool_export_002_pos.ksh \
|
||||
functional/cli_root/zpool_export/zpool_export_003_neg.ksh \
|
||||
functional/cli_root/zpool_export/zpool_export_004_pos.ksh \
|
||||
functional/cli_root/zpool_export/zpool_export_parallel_admin.ksh \
|
||||
functional/cli_root/zpool_export/zpool_export_parallel_pos.ksh \
|
||||
functional/cli_root/zpool_get/cleanup.ksh \
|
||||
functional/cli_root/zpool_get/setup.ksh \
|
||||
functional/cli_root/zpool_get/vdev_get_001_pos.ksh \
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
#!/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 https://opensource.org/licenses/CDDL-1.0.
|
||||
# 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 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2024 Klara, Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify that admin commands cannot race a pool export
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create a pool
|
||||
# 2. Import the pool with an injected delay in the background
|
||||
# 3. Execute some admin commands against the pool
|
||||
#
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
DEVICE_DIR=$TEST_BASE_DIR/dev_export-test
|
||||
|
||||
function cleanup
|
||||
{
|
||||
zinject -c all
|
||||
poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1
|
||||
[[ -d $DEVICE_DIR ]] && log_must rm -rf $DEVICE_DIR
|
||||
}
|
||||
|
||||
log_assert "admin commands cannot race a pool export"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
[[ ! -d $DEVICE_DIR ]] && log_must mkdir -p $DEVICE_DIR
|
||||
log_must truncate -s $MINVDEVSIZE ${DEVICE_DIR}/disk0 ${DEVICE_DIR}/disk1
|
||||
|
||||
log_must zpool create -f $TESTPOOL1 mirror ${DEVICE_DIR}/disk0 ${DEVICE_DIR}/disk1
|
||||
|
||||
log_must zinject -P export -s 10 $TESTPOOL1
|
||||
|
||||
log_must zpool export $TESTPOOL1 &
|
||||
|
||||
zpool set comment=hello $TESTPOOL1
|
||||
zpool reguid $TESTPOOL1 &
|
||||
zpool split $TESTPOOL1 &
|
||||
|
||||
log_pass "admin commands cannot race a pool export"
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
#!/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 https://opensource.org/licenses/CDDL-1.0.
|
||||
# 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 2007 Sun Microsystems, Inc. All rights reserved.
|
||||
# Use is subject to license terms.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2024 Klara, Inc.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
|
||||
. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
|
||||
|
||||
# test uses 8 vdevs
|
||||
MAX_NUM=8
|
||||
DEVICE_DIR=$TEST_BASE_DIR/dev_import-test
|
||||
|
||||
|
||||
#
|
||||
# DESCRIPTION:
|
||||
# Verify that pool exports can occur in parallel
|
||||
#
|
||||
# STRATEGY:
|
||||
# 1. Create 8 pools
|
||||
# 2. Inject an export delay using zinject
|
||||
# 3. Export half of the pools synchronously to baseline sequential cost
|
||||
# 4. Export the other half asynchronously to demonstrate parallel savings
|
||||
# 6. Import 4 pools
|
||||
# 7. Test zpool export -a
|
||||
#
|
||||
|
||||
verify_runnable "global"
|
||||
|
||||
#
|
||||
# override the minimum sized vdevs
|
||||
#
|
||||
|
||||
POOLNAME="test_pool"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
zinject -c all
|
||||
|
||||
for i in {0..$(($MAX_NUM - 1))}; do
|
||||
poolexists $POOLNAME-$i && destroy_pool $POOLNAME-$i
|
||||
done
|
||||
|
||||
[[ -d $DEVICE_DIR ]] && log_must rm -rf $DEVICE_DIR
|
||||
}
|
||||
|
||||
log_assert "Pool exports can occur in parallel"
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
[[ ! -d $DEVICE_DIR ]] && log_must mkdir -p $DEVICE_DIR
|
||||
|
||||
#
|
||||
# Create some pools with export delay injectors
|
||||
#
|
||||
for i in {0..$(($MAX_NUM - 1))}; do
|
||||
log_must truncate -s $MINVDEVSIZE ${DEVICE_DIR}/disk$i
|
||||
log_must zpool create $POOLNAME-$i $DEVICE_DIR/disk$i
|
||||
log_must zinject -P export -s 8 $POOLNAME-$i
|
||||
done
|
||||
|
||||
#
|
||||
# Export half of the pools synchronously
|
||||
#
|
||||
SECONDS=0
|
||||
for i in {0..3}; do
|
||||
log_must zpool export $POOLNAME-$i
|
||||
done
|
||||
sequential_time=$SECONDS
|
||||
log_note "sequentially exported 4 pools in $sequential_time seconds"
|
||||
|
||||
#
|
||||
# Export half of the pools in parallel
|
||||
#
|
||||
SECONDS=0
|
||||
for i in {4..7}; do
|
||||
log_must zpool export $POOLNAME-$i &
|
||||
done
|
||||
wait
|
||||
parallel_time=$SECONDS
|
||||
log_note "asyncronously exported 4 pools in $parallel_time seconds"
|
||||
|
||||
log_must test $parallel_time -lt $(($sequential_time / 3))
|
||||
|
||||
#
|
||||
# import 4 pools with export delay injectors
|
||||
#
|
||||
for i in {4..7}; do
|
||||
log_must zpool import -d $DEVICE_DIR/disk$i $POOLNAME-$i
|
||||
log_must zinject -P export -s 8 $POOLNAME-$i
|
||||
done
|
||||
|
||||
#
|
||||
# now test zpool export -a
|
||||
#
|
||||
SECONDS=0
|
||||
log_must zpool export -a
|
||||
parallel_time=$SECONDS
|
||||
log_note "asyncronously exported 4 pools, using '-a', in $parallel_time seconds"
|
||||
|
||||
log_must test $parallel_time -lt $(($sequential_time / 3))
|
||||
|
||||
log_pass "Pool exports occur in parallel"
|
||||
Reference in New Issue
Block a user