1#!/bin/ksh -p
2# SPDX-License-Identifier: CDDL-1.0
3#
4# CDDL HEADER START
5#
6# The contents of this file are subject to the terms of the
7# Common Development and Distribution License (the "License").
8# You may not use this file except in compliance with the License.
9#
10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11# or https://opensource.org/licenses/CDDL-1.0.
12# See the License for the specific language governing permissions
13# and limitations under the License.
14#
15# When distributing Covered Code, include this CDDL HEADER in each
16# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17# If applicable, add the following below this CDDL HEADER, with the
18# fields enclosed by brackets "[]" replaced with your own identifying
19# information: Portions Copyright [yyyy] [name of copyright owner]
20#
21# CDDL HEADER END
22#
23
24#
25# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
26# Use is subject to license terms.
27#
28
29#
30# Copyright (c) 2023 Klara, Inc.
31#
32
33. $STF_SUITE/include/libtest.shlib
34. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
35. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
36
37#
38# DESCRIPTION:
39# 	Verify that admin commands to different pool are not blocked by import
40#
41# STRATEGY:
42#	1. Create 2 pools
43#	2. Export one of the pools
44#	4. Import the pool with an injected delay
45#	5. Execute some admin commands against both pools
46#	6. Verify that the admin commands to the non-imported pool don't stall
47#
48
49verify_runnable "global"
50
51function cleanup
52{
53	zinject -c all
54	destroy_pool $TESTPOOL1
55	destroy_pool $TESTPOOL2
56}
57
58function pool_import
59{
60	typeset dir=$1
61	typeset pool=$2
62
63	SECONDS=0
64	errmsg=$(zpool import -d $dir -f $pool 2>&1 > /dev/null)
65	if [[ $? -eq 0 ]]; then
66		echo ${pool}: imported in $SECONDS secs
67		echo $SECONDS > ${DEVICE_DIR}/${pool}-import
68	else
69		echo ${pool}: import failed $errmsg in $SECONDS secs
70	fi
71}
72
73function pool_add_device
74{
75	typeset pool=$1
76	typeset device=$2
77	typeset devtype=$3
78
79	SECONDS=0
80	errmsg=$(zpool add $pool $devtype $device 2>&1 > /dev/null)
81	if [[ $? -eq 0 ]]; then
82		echo ${pool}: added $devtype vdev in $SECONDS secs
83		echo $SECONDS > ${DEVICE_DIR}/${pool}-add
84	else
85		echo ${pool}: add $devtype vdev failed ${errmsg}, in $SECONDS secs
86	fi
87}
88
89function pool_stats
90{
91	typeset stats=$1
92	typeset pool=$2
93
94	SECONDS=0
95	errmsg=$(zpool $stats $pool 2>&1 > /dev/null)
96	if [[ $? -eq 0 ]]; then
97		echo ${pool}: $stats in $SECONDS secs
98		echo $SECONDS > ${DEVICE_DIR}/${pool}-${stats}
99	else
100		echo ${pool}: $stats failed ${errmsg}, in $SECONDS secs
101	fi
102}
103
104function pool_create
105{
106	typeset pool=$1
107	typeset device=$2
108
109	SECONDS=0
110	errmsg=$(zpool create $pool $device 2>&1 > /dev/null)
111	if [[ $? -eq 0 ]]; then
112		echo ${pool}: created in $SECONDS secs
113		echo $SECONDS > ${DEVICE_DIR}/${pool}-create
114	else
115		echo ${pool}: create failed ${errmsg}, in $SECONDS secs
116	fi
117}
118
119log_assert "Simple admin commands to different pool not blocked by import"
120
121log_onexit cleanup
122
123#
124# create two pools and export one
125#
126log_must zpool create $TESTPOOL1 $VDEV0
127log_must zpool export $TESTPOOL1
128log_must zpool create $TESTPOOL2 $VDEV1
129
130#
131# import pool asyncronously with an injected 10 second delay
132#
133log_must zinject -P import -s 10 $TESTPOOL1
134pool_import $DEVICE_DIR $TESTPOOL1 &
135
136sleep 2
137
138#
139# run some admin commands on the pools while the import is in progress
140#
141
142pool_add_device $TESTPOOL1 $VDEV2 "log" &
143pool_add_device $TESTPOOL2 $VDEV3 "cache" &
144pool_stats "status" $TESTPOOL1 &
145pool_stats "status" $TESTPOOL2 &
146pool_stats "list" $TESTPOOL1 &
147pool_stats "list" $TESTPOOL2 &
148pool_create $TESTPOOL1 $VDEV4 &
149wait
150
151log_must zpool sync $TESTPOOL1 $TESTPOOL2
152
153zpool history $TESTPOOL1
154zpool history $TESTPOOL2
155
156log_must test "5" -lt $(<${DEVICE_DIR}/${TESTPOOL1}-import)
157
158#
159# verify that commands to second pool did not wait for import to finish
160#
161log_must test "2" -gt $(<${DEVICE_DIR}/${TESTPOOL2}-status)
162log_must test "2" -gt $(<${DEVICE_DIR}/${TESTPOOL2}-list)
163log_must test "2" -gt $(<${DEVICE_DIR}/${TESTPOOL2}-add)
164[[ -e ${DEVICE_DIR}/${TESTPOOL1}-create ]] && log_fail "unexpected pool create"
165
166log_pass "Simple admin commands to different pool not blocked by import"
167