forked from kdave/xfstests
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdmthin
241 lines (198 loc) · 7.92 KB
/
dmthin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/bin/bash
#
# Copyright (c) 2015 Red Hat, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
#
# common functions for setting up and tearing down a dmthin device
# SOOO many devices!
# Create the 2 pool devices on lvs so we can build the whole thing
# from a single scratch device
# Backing data dev
DMTHIN_DATA_NAME="thin-data"
DMTHIN_DATA_DEV="/dev/mapper/$DMTHIN_DATA_NAME"
# Backing metadata dev
DMTHIN_META_NAME="thin-meta"
DMTHIN_META_DEV="/dev/mapper/$DMTHIN_META_NAME"
# Backing pool dev (combination of above)
DMTHIN_POOL_NAME="thin-pool"
DMTHIN_POOL_DEV="/dev/mapper/$DMTHIN_POOL_NAME"
# Thin volume
DMTHIN_VOL_NAME="thin-vol"
DMTHIN_VOL_DEV="/dev/mapper/$DMTHIN_VOL_NAME"
_dmthin_cleanup()
{
$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
$DMSETUP_PROG remove $DMTHIN_VOL_NAME> /dev/null 2>&1
$DMSETUP_PROG remove $DMTHIN_POOL_NAME> /dev/null 2>&1
$DMSETUP_PROG remove $DMTHIN_META_NAME> /dev/null 2>&1
$DMSETUP_PROG remove $DMTHIN_DATA_NAME> /dev/null 2>&1
}
_dmthin_check_fs()
{
$UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
_check_scratch_fs $DMTHIN_VOL_DEV
}
# Set up a dm-thin device on $SCRATCH_DEV
#
# All arguments are optional, and in this order; defaults follows:
# data_dev_size: half of $SCRATCH_DEV
# virtual_size: 10x $data_dev_size
# cluster_size: 512k
# low_water: 100M
#
# You may specify 0 to 4 of these arguments, but they
# must be in the above order.
_dmthin_init()
{
local data_dev_size=$1 # Backing pool data size in sectors
local virtual_size=$2 # Virtual size in sectors
local cluster_size=$3 # cluster/alloc size, sectors
local low_water=$4 # low water mark, sectors
local dm_backing_dev=$SCRATCH_DEV
local blk_dev_size=`blockdev --getsz $dm_backing_dev`
local pool_id=$RANDOM
# Default to something small-ish
if [ -z "$data_dev_size" ]; then
data_dev_size=$(($blk_dev_size / 2))
fi
# Default to something big-is; 10x backing
if [ -z "$virtual_size" ]; then
virtual_size=$(($data_dev_size * 10))
fi
# Default to 512k
if [ -z "$cluster_size" ]; then
cluster_size=1024 # 512k in sectors
fi
# Default to 100M
if [ -z "$low_water" ]; then
low_water=204800 # 100M, in sectors
fi
# low_water is expressed in blocks of size $cluster_size
low_water=$((low_water / cluster_size))
# Need to make linear metadata and data devs. From kernel docs:
# As a guide, we suggest you calculate the number of bytes to use in the
# metadata device as 48 * $data_dev_size / $data_block_size but round it up
# to 2MB (4096 sectors) if the answer is smaller.
# So do that:
local meta_dev_size=$((48 * $data_dev_size / $cluster_size))
if [ "$meta_dev_size" -lt "4096" ]; then
meta_dev_size=4096 # 2MB
fi
# scratch dev gets a metadata vol & data vol, start at this offset
local meta_dev_offset=10240
local total_data_dev_size=$(($meta_dev_offset + $meta_dev_size + $data_dev_size))
if [ "$total_data_dev_size" -gt "$blk_dev_size" ]; then
_notrun "$SCRATCH_DEV too small"
fi
# Unmount & tear down old stuff
_dmthin_cleanup
# Metadata device
DMTHIN_META_TABLE="0 $meta_dev_size linear $dm_backing_dev $meta_dev_offset"
$DMSETUP_PROG create $DMTHIN_META_NAME --table "$DMTHIN_META_TABLE" || \
_fatal "failed to create dm thin meta device"
# Data device
local data_dev_offset=$((meta_dev_offset + $meta_dev_size))
DMTHIN_DATA_TABLE="0 $data_dev_size linear $dm_backing_dev $data_dev_offset"
$DMSETUP_PROG create $DMTHIN_DATA_NAME --table "$DMTHIN_DATA_TABLE" || \
_fatal "failed to create dm thin data device"
# Zap the pool metadata dev
dd if=/dev/zero of=$DMTHIN_META_DEV bs=4096 count=1 &>/dev/null
# Thin pool
# "start length thin-pool metadata_dev data_dev data_block_size low_water_mark"
DMTHIN_POOL_TABLE="0 $data_dev_size thin-pool $DMTHIN_META_DEV $DMTHIN_DATA_DEV $cluster_size $low_water"
$DMSETUP_PROG create $DMTHIN_POOL_NAME --table "$DMTHIN_POOL_TABLE" || \
_fatal "failed to create dm thin pool device"
# Thin volume
$DMSETUP_PROG message $DMTHIN_POOL_DEV 0 "create_thin $pool_id" || \
_fatal "failed to message pool device"
# start length thin pool_dev dev_id [external_origin_dev]
DMTHIN_VOL_TABLE="0 $virtual_size thin $DMTHIN_POOL_DEV $pool_id"
$DMSETUP_PROG create $DMTHIN_VOL_NAME --table "$DMTHIN_VOL_TABLE" || \
_fatal "failed to create dm thin volume device"
}
# for internal use
_dmthin_reload_table()
{
local dev_name=$1
local table="$2"
$DMSETUP_PROG suspend $dev_name || \
_fail "dmsetup suspend of $dev_name failed"
$DMSETUP_PROG load $dev_name --table "$table" || \
_fail "dmsetup failed to reload $dev_name table"
$DMSETUP_PROG resume $dev_name || \
_fail "dmsetup resume of $dev_name failed"
}
# Grow the dm-thin device by the given amount
# Argument is number of sectors to add, if not specified
# defaults to 1/4 of the $SCRATCH_DEV size
_dmthin_grow()
{
local add_sectors=$1 # Number of sectors to add
local dm_backing_dev=$SCRATCH_DEV
local blk_dev_size=`blockdev --getsz $dm_backing_dev`
# Get current sizes & values
local meta_dev_size=`$DMSETUP_PROG table | grep $DMTHIN_META_NAME | awk '{print $3}'`
local meta_dev_offset=`$DMSETUP_PROG table | grep $DMTHIN_META_NAME | awk '{print $6}'`
local data_dev_size=`$DMSETUP_PROG table | grep $DMTHIN_DATA_NAME | awk '{print $3}'`
local pool_dev_size=`$DMSETUP_PROG table | grep $DMTHIN_POOL_NAME | awk '{print $3}'`
local cluster_size=`$DMSETUP_PROG table | grep $DMTHIN_POOL_NAME | awk '{print $7}'`
local low_water=`$DMSETUP_PROG table | grep $DMTHIN_POOL_NAME | awk '{print $8}'`
# default to 25% growth
if [ -z "$add_sectors" ]; then
add_sectors=$(($data_dev_size / 4))
fi
local data_dev_offset=$(($meta_dev_offset + $meta_dev_size))
# Figure new sizes
data_dev_size=$(($data_dev_size + $add_sectors))
pool_dev_size=$(($pool_dev_size + $add_sectors))
# Can we do this?
local total_data_dev_size=$(($meta_dev_offset + $meta_dev_size + $data_dev_size))
if [ "$total_data_dev_size" -gt "$blk_dev_size" ]; then
_fail "$SCRATCH_DEV too small"
fi
# Grow the data device
DMTHIN_DATA_TABLE="0 $data_dev_size linear $dm_backing_dev $data_dev_offset"
_dmthin_reload_table $DMTHIN_DATA_NAME "$DMTHIN_DATA_TABLE"
# Grow the pool
DMTHIN_POOL_TABLE="0 $data_dev_size thin-pool $DMTHIN_META_DEV $DMTHIN_DATA_DEV $cluster_size $low_water"
_dmthin_reload_table $DMTHIN_POOL_NAME "$DMTHIN_POOL_TABLE"
}
# Queue IOs when full
_dmthin_set_queue()
{
local data_dev_size=`$DMSETUP_PROG table | grep $DMTHIN_DATA_NAME | awk '{print $3}'`
local cluster_size=`$DMSETUP_PROG table | grep $DMTHIN_POOL_NAME | awk '{print $7}'`
local low_water=`$DMSETUP_PROG table | grep $DMTHIN_POOL_NAME | awk '{print $8}'`
DMTHIN_POOL_TABLE="0 $data_dev_size thin-pool $DMTHIN_META_DEV $DMTHIN_DATA_DEV $cluster_size $low_water"
_dmthin_reload_table $DMTHIN_POOL_NAME "$DMTHIN_POOL_TABLE"
}
# Fail IOs when full
_dmthin_set_fail()
{
local data_dev_size=`$DMSETUP_PROG table | grep $DMTHIN_DATA_NAME | awk '{print $3}'`
local cluster_size=`$DMSETUP_PROG table | grep $DMTHIN_POOL_NAME | awk '{print $7}'`
local low_water=`$DMSETUP_PROG table | grep $DMTHIN_POOL_NAME | awk '{print $8}'`
DMTHIN_POOL_TABLE="0 $data_dev_size thin-pool $DMTHIN_META_DEV $DMTHIN_DATA_DEV $cluster_size $low_water 1 error_if_no_space"
_dmthin_reload_table $DMTHIN_POOL_NAME "$DMTHIN_POOL_TABLE"
}
_dmthin_mount_options()
{
echo `_common_dev_mount_options $*` $DMTHIN_VOL_DEV $SCRATCH_MNT
}
_dmthin_mount()
{
_mount -t $FSTYP `_dmthin_mount_options $*`
}