xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/tests/functional/alloc_class/alloc_class_012_pos.ksh (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1#!/bin/ksh -p
2# SPDX-License-Identifier: CDDL-1.0
3
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
15#
16# Copyright (c) 2018 by Delphix. All rights reserved.
17#
18
19. $STF_SUITE/tests/functional/alloc_class/alloc_class.kshlib
20
21#
22# DESCRIPTION:
23#	Removing a special device from a pool succeeds.
24#
25
26verify_runnable "global"
27
28#
29# Verify the file identified by the input <inode> is written on a special vdev
30# According to the pool layout used in this test vdev_id 3 and 4 are special
31# XXX: move this function to libtest.shlib once we get "Vdev Properties"
32#
33function file_in_special_vdev # <dataset> <inode>
34{
35	typeset dataset="$1"
36	typeset inum="$2"
37	typeset num_normal=$(echo $ZPOOL_DISKS | wc -w)
38	num_normal=${num_normal##* }
39
40	zdb -dddddd $dataset $inum | awk -v d=$num_normal '{
41# find DVAs from string "offset level dva" only for L0 (data) blocks
42if (match($0,"L0 [0-9]+")) {
43   dvas[0]=$3
44   dvas[1]=$4
45   dvas[2]=$5
46   for (i = 0; i < 3; ++i) {
47      if (match(dvas[i],"([^:]+):.*")) {
48         dva = substr(dvas[i], RSTART, RLENGTH);
49         # parse DVA from string "vdev:offset:asize"
50         if (split(dva,arr,":") != 3) {
51            print "Error parsing DVA: <" dva ">";
52            exit 1;
53         }
54         # verify vdev is "special"
55         if (arr[1] < d) {
56            exit 1;
57         }
58      }
59   }
60}}'
61}
62
63#
64# Check that device removal works for special class vdevs
65#
66function check_removal
67{
68	#
69	# Create a non-raidz pool so we can remove top-level vdevs
70	#
71	log_must disk_setup
72	log_must zpool create $TESTPOOL $ZPOOL_DISKS \
73	    special $CLASS_DISK0 special $CLASS_DISK1
74	log_must display_status "$TESTPOOL"
75
76	#
77	# Generate some metadata and small blocks in the special class vdev
78	# before removal
79	#
80	typeset -l i=1
81	typeset -l blocks=25
82
83	log_must zfs create -o special_small_blocks=32K -o recordsize=32K \
84	    $TESTPOOL/$TESTFS
85	for i in 1 2 3 4; do
86		log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/testfile.$i \
87		    bs=1M count=$blocks
88		((blocks = blocks + 25))
89	done
90	sync_pool $TESTPOOL
91	log_must zpool list -v $TESTPOOL
92
93	# Verify the files were written in the special class vdevs
94	for i in 1 2 3 4; do
95		dataset="$TESTPOOL/$TESTFS"
96		inum="$(get_objnum /$TESTPOOL/$TESTFS/testfile.$i)"
97		log_must file_in_special_vdev $dataset $inum
98	done
99
100	log_must zpool remove $TESTPOOL $CLASS_DISK0
101
102	sleep 5
103	sync_pool $TESTPOOL
104	sleep 1
105
106	log_must zdb -bbcc $TESTPOOL
107	log_must zpool list -v $TESTPOOL
108	log_must zpool destroy -f "$TESTPOOL"
109	log_must disk_cleanup
110}
111
112claim="Removing a special device from a pool succeeds."
113
114log_assert $claim
115log_onexit cleanup
116
117typeset CLASS_DEVSIZE=$CLASS_DEVSIZE
118for CLASS_DEVSIZE in $CLASS_DEVSIZE $ZPOOL_DEVSIZE; do
119	typeset ZPOOL_DISKS=$ZPOOL_DISKS
120	for ZPOOL_DISKS in "$ZPOOL_DISKS" $ZPOOL_DISK0; do
121		check_removal
122	done
123done
124
125log_pass $claim
126