1#!/bin/sh
2# Copyright (C) 2008 Red Hat, Inc. All rights reserved.
3# Copyright (C) 2007 NEC Corporation
4#
5# This copyrighted material is made available to anyone wishing to use,
6# modify, copy, or redistribute it subject to the terms and conditions
7# of the GNU General Public License v.2.
8#
9# You should have received a copy of the GNU General Public License
10# along with this program; if not, write to the Free Software Foundation,
11# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
12
13test_description="ensure that pvmove works with basic options"
14
15. ./test-utils.sh
16
17dmsetup_has_dm_devdir_support_ || exit 200
18
19# ---------------------------------------------------------------------
20# Utilities
21
22lvdev_() {
23  echo "$G_dev_/$1/$2"
24}
25
26lv_is_on_() {
27  local lv=$1 #allready vg/lv
28  shift 1
29  lvs -a -odevices --noheadings $lv | sed 's/,/\n/g' > out
30#is on all specified devs
31  for d in $*; do grep "$d(" out; done
32#isn't on any other dev (we are set -e remember)
33  for d in $*; do ! grep -v "$d(" out; done
34  return 0
35}
36
37save_dev_sum_() {
38  mkfs.ext3 $1 > /dev/null &&
39  md5sum $1 > md5.$(basename $1)
40}
41
42check_dev_sum_() {
43  md5sum $1 > md5.tmp && cmp md5.$(basename $1) md5.tmp
44}
45
46# ---------------------------------------------------------------------
47# Initialize PVs and VGs
48
49aux prepare_vg 5 80
50
51# ---------------------------------------------------------------------
52# Common environment setup/cleanup for each sub testcases
53
54prepare_lvs_() {
55  lvcreate -l2 -n $lv1 $vg $dev1
56    lv_is_on_ $vg/$lv1 $dev1
57  lvcreate -l9 -i3 -n $lv2 $vg $dev2 $dev3 $dev4
58    lv_is_on_ $vg/$lv2 $dev2 $dev3 $dev4
59  lvextend -l+2 $vg/$lv1 $dev2
60    lv_is_on_ $vg/$lv1 $dev1 $dev2
61  lvextend -l+2 $vg/$lv1 $dev3
62    lv_is_on_ $vg/$lv1 $dev1 $dev2 $dev3
63  lvextend -l+2 $vg/$lv1 $dev1
64    lv_is_on_ $vg/$lv1 $dev1 $dev2 $dev3 $dev1
65  lvcreate -l1 -n $lv3 $vg $dev2
66    lv_is_on_ $vg/$lv3 $dev2
67  save_dev_sum_ $(lvdev_ $vg $lv1)
68  save_dev_sum_ $(lvdev_ $vg $lv2)
69  save_dev_sum_ $(lvdev_ $vg $lv3)
70  lvs -a -o devices --noheadings $vg/$lv1 > ${lv1}_devs
71  lvs -a -o devices --noheadings $vg/$lv2 > ${lv2}_devs
72  lvs -a -o devices --noheadings $vg/$lv3 > ${lv3}_devs
73}
74
75lv_not_changed_() {
76  lvs -a -o devices --noheadings $1 > out
77  diff $(basename $1)_devs out
78}
79
80check_and_cleanup_lvs_() {
81  lvs -a -o+devices $vg
82  check_dev_sum_ $(lvdev_ $vg $lv1)
83  check_dev_sum_ $(lvdev_ $vg $lv2)
84  check_dev_sum_ $(lvdev_ $vg $lv3)
85  lvs -a -o name $vg > out && ! grep ^pvmove out
86  lvremove -ff $vg
87	if ! dmsetup table|not grep $vg; then
88		echo "ERROR: lvremove did leave some some mappings in DM behind!" &&
89		return 1
90	fi
91	:
92}
93
94#COMM "check environment setup/cleanup"
95prepare_lvs_
96check_and_cleanup_lvs_
97
98# ---------------------------------------------------------------------
99# pvmove tests
100
101# ---
102# filter by LV
103
104#COMM "only specified LV is moved: from pv2 to pv5 only for lv1"
105prepare_lvs_
106pvmove -i1 -n $vg/$lv1 $dev2 $dev5
107lv_is_on_ $vg/$lv1 $dev1 $dev5 $dev3 $dev1
108lv_not_changed_ $vg/$lv2
109lv_not_changed_ $vg/$lv3
110check_and_cleanup_lvs_
111
112# ---
113# segments in a LV
114
115#COMM "the 1st seg of 3-segs LV is moved: from pv1 of lv1 to pv4"
116prepare_lvs_
117pvmove -i1 -n $vg/$lv1 $dev1 $dev4
118lv_is_on_ $vg/$lv1 $dev4 $dev2 $dev3 $dev4
119lv_not_changed_ $vg/$lv2
120lv_not_changed_ $vg/$lv3
121check_and_cleanup_lvs_
122
123#COMM "the 2nd seg of 3-segs LV is moved: from pv2 of lv1 to pv4"
124prepare_lvs_
125pvmove -i1 -n $vg/$lv1 $dev2 $dev4
126lv_is_on_ $vg/$lv1 $dev1 $dev4 $dev3 $dev1
127lv_not_changed_ $vg/$lv2
128lv_not_changed_ $vg/$lv3
129check_and_cleanup_lvs_
130
131#COMM "the 3rd seg of 3-segs LV is moved: from pv3 of lv1 to pv4"
132prepare_lvs_
133pvmove -i1 -n $vg/$lv1 $dev3 $dev4
134lv_is_on_ $vg/$lv1 $dev1 $dev2 $dev4 $dev1
135lv_not_changed_ $vg/$lv2
136lv_not_changed_ $vg/$lv3
137check_and_cleanup_lvs_
138
139# ---
140# multiple LVs matching
141
142#COMM "1 out of 3 LVs is moved: from pv4 to pv5"
143prepare_lvs_
144pvmove -i1 $dev4 $dev5
145lv_not_changed_ $vg/$lv1
146lv_is_on_ $vg/$lv2 $dev2 $dev3 $dev5
147lv_not_changed_ $vg/$lv3
148check_and_cleanup_lvs_
149
150#COMM "2 out of 3 LVs are moved: from pv3 to pv5"
151prepare_lvs_
152pvmove -i1 $dev3 $dev5
153lv_is_on_ $vg/$lv1 $dev1 $dev2 $dev5 $dev1
154lv_is_on_ $vg/$lv2 $dev2 $dev5 $dev4
155lv_not_changed_ $vg/$lv3
156check_and_cleanup_lvs_
157
158#COMM "3 out of 3 LVs are moved: from pv2 to pv5"
159prepare_lvs_
160pvmove -i1 $dev2 $dev5
161lv_is_on_ $vg/$lv1 $dev1 $dev5 $dev3 $dev1
162lv_is_on_ $vg/$lv2 $dev5 $dev3 $dev4
163lv_is_on_ $vg/$lv3 $dev5
164check_and_cleanup_lvs_
165
166# ---
167# areas of striping
168
169#COMM "move the 1st stripe: from pv2 of lv2 to pv1"
170prepare_lvs_
171pvmove -i1 -n $vg/$lv2 $dev2 $dev1
172lv_not_changed_ $vg/$lv1
173lv_is_on_ $vg/$lv2 $dev1 $dev3 $dev4
174lv_not_changed_ $vg/$lv3
175check_and_cleanup_lvs_
176
177#COMM "move the 2nd stripe: from pv3 of lv2 to pv1"
178prepare_lvs_
179pvmove -i1 -n $vg/$lv2 $dev3 $dev1
180lv_not_changed_ $vg/$lv1
181lv_is_on_ $vg/$lv2 $dev2 $dev1 $dev4
182lv_not_changed_ $vg/$lv3
183check_and_cleanup_lvs_
184
185#COMM "move the 3rd stripe: from pv4 of lv2 to pv1"
186prepare_lvs_
187pvmove -i1 -n $vg/$lv2 $dev4 $dev1
188lv_not_changed_ $vg/$lv1
189lv_is_on_ $vg/$lv2 $dev2 $dev3 $dev1
190lv_not_changed_ $vg/$lv3
191check_and_cleanup_lvs_
192
193# ---
194# partial segment match (source segment splitted)
195
196#COMM "match to the start of segment:from pv2:0-0 to pv5"
197prepare_lvs_
198pvmove -i1 $dev2:0-0 $dev5
199lv_not_changed_ $vg/$lv1
200lv_is_on_ $vg/$lv2 $dev5 $dev2 $dev3 $dev4
201lv_not_changed_ $vg/$lv3
202check_and_cleanup_lvs_
203
204#COMM "match to the middle of segment: from pv2:1-1 to pv5"
205prepare_lvs_
206pvmove -i1 $dev2:1-1 $dev5
207lv_not_changed_ $vg/$lv1
208lv_is_on_ $vg/$lv2 $dev2 $dev5 $dev2 $dev3 $dev4
209lv_not_changed_ $vg/$lv3
210check_and_cleanup_lvs_
211
212#COMM "match to the end of segment: from pv2:2-2 to pv5"
213prepare_lvs_
214pvmove -i1 $dev2:2-2 $dev5
215lv_not_changed_ $vg/$lv1
216lv_is_on_ $vg/$lv2 $dev2 $dev5 $dev3 $dev4
217lv_not_changed_ $vg/$lv3
218check_and_cleanup_lvs_
219
220# ---
221# destination segment splitted
222
223#COMM "no destination split: from pv2:0-2 to pv5"
224prepare_lvs_
225pvmove -i1 $dev2:0-2 $dev5
226lv_not_changed_ $vg/$lv1
227lv_is_on_ $vg/$lv2 $dev5 $dev3 $dev4
228lv_not_changed_ $vg/$lv3
229check_and_cleanup_lvs_
230
231#COMM "destination split into 2: from pv2:0-2 to pv5:5-5 and pv4:5-6"
232prepare_lvs_
233pvmove -i1 $dev2:0-2 $dev5:5-5 $dev4:5-6
234lv_not_changed_ $vg/$lv1
235lv_is_on_ $vg/$lv2 $dev5 $dev4 $dev3 $dev4
236lv_not_changed_ $vg/$lv3
237check_and_cleanup_lvs_
238
239#COMM "destination split into 3: from pv2:0-2 to {pv3,4,5}:5-5"
240prepare_lvs_
241pvmove -i1 $dev2:0-2 $dev3:5-5 $dev4:5-5 $dev5:5-5
242lv_not_changed_ $vg/$lv1
243lv_is_on_ $vg/$lv2 $dev3 $dev4 $dev5 $dev3 $dev4
244lv_not_changed_ $vg/$lv3
245check_and_cleanup_lvs_
246
247# ---
248# alloc policy (anywhere, contiguous) with both success and failure cases
249
250#COMM "alloc normal on same PV for source and destination: from pv3:0-2 to pv3:5-7"
251prepare_lvs_
252not pvmove -i1 $dev3:0-2 $dev3:5-7
253# "(cleanup previous test)"
254lv_not_changed_ $vg/$lv1
255lv_not_changed_ $vg/$lv2
256lv_not_changed_ $vg/$lv3
257check_and_cleanup_lvs_
258
259#COMM "alloc anywhere on same PV for source and destination: from pv3:0-2 to pv3:5-7"
260prepare_lvs_
261pvmove -i1 --alloc anywhere $dev3:0-2 $dev3:5-7
262lv_not_changed_ $vg/$lv1
263lv_is_on_ $vg/$lv2 $dev2 $dev3 $dev4
264lv_not_changed_ $vg/$lv3
265check_and_cleanup_lvs_
266
267#COMM "alloc anywhere but better area available: from pv3:0-2 to pv3:5-7 or pv5:5-6,pv4:5-5"
268prepare_lvs_
269pvmove -i1 --alloc anywhere $dev3:0-2 $dev3:5-7 $dev5:5-6 $dev4:5-5
270lv_not_changed_ $vg/$lv1
271lv_is_on_ $vg/$lv2 $dev2 $dev5 $dev4 $dev4
272lv_not_changed_ $vg/$lv3
273check_and_cleanup_lvs_
274
275#COMM "alloc contiguous but area not available: from pv2:0-2 to pv5:5-5 and pv4:5-6"
276prepare_lvs_
277not pvmove -i1 --alloc contiguous $dev2:0-2 $dev5:5-5 $dev4:5-6
278# "(cleanup previous test)"
279lv_not_changed_ $vg/$lv1
280lv_not_changed_ $vg/$lv2
281lv_not_changed_ $vg/$lv3
282check_and_cleanup_lvs_
283
284#COMM "alloc contiguous and contiguous area available: from pv2:0-2 to pv5:0-0,pv5:3-5 and pv4:5-6"
285prepare_lvs_
286pvmove -i1 --alloc contiguous $dev2:0-2 $dev5:0-0 $dev5:3-5 $dev4:5-6
287lv_not_changed_ $vg/$lv1
288lv_is_on_ $vg/$lv2 $dev5 $dev3 $dev4
289lv_not_changed_ $vg/$lv3
290check_and_cleanup_lvs_
291
292# ---
293# multiple segments in a LV
294
295#COMM "multiple source LVs: from pv3 to pv5"
296prepare_lvs_
297pvmove -i1 $dev3 $dev5
298lv_is_on_ $vg/$lv1 $dev1 $dev2 $dev5
299lv_is_on_ $vg/$lv2 $dev2 $dev5 $dev4
300lv_not_changed_ $vg/$lv3
301check_and_cleanup_lvs_
302
303# ---
304# move inactive LV
305
306#COMM "move inactive LV: from pv2 to pv5"
307prepare_lvs_
308lvchange -an $vg/$lv1
309lvchange -an $vg/$lv3
310pvmove -i1 $dev2 $dev5
311lv_is_on_ $vg/$lv1 $dev1 $dev5 $dev3
312lv_is_on_ $vg/$lv2 $dev5 $dev3 $dev4
313lv_is_on_ $vg/$lv3 $dev5
314check_and_cleanup_lvs_
315
316# ---
317# other failure cases
318
319#COMM "no PEs to move: from pv3 to pv1"
320prepare_lvs_
321pvmove -i1 $dev3 $dev1
322not pvmove -i1 $dev3 $dev1
323# "(cleanup previous test)"
324lv_is_on_ $vg/$lv1 $dev1 $dev2 $dev1
325lv_is_on_ $vg/$lv2 $dev2 $dev1 $dev4
326lv_not_changed_ $vg/$lv3
327check_and_cleanup_lvs_
328
329#COMM "no space available: from pv2:0-0 to pv1:0-0"
330prepare_lvs_
331not pvmove -i1 $dev2:0-0 $dev1:0-0
332# "(cleanup previous test)"
333lv_not_changed_ $vg/$lv1
334lv_not_changed_ $vg/$lv2
335lv_not_changed_ $vg/$lv3
336check_and_cleanup_lvs_
337
338#COMM 'same source and destination: from pv1 to pv1'
339prepare_lvs_
340not pvmove -i1 $dev1 $dev1
341#"(cleanup previous test)"
342lv_not_changed_ $vg/$lv1
343lv_not_changed_ $vg/$lv2
344lv_not_changed_ $vg/$lv3
345check_and_cleanup_lvs_
346
347#COMM "sum of specified destination PEs is large enough, but it includes source PEs and the free PEs are not enough"
348prepare_lvs_
349not pvmove --alloc anywhere $dev1:0-2 $dev1:0-2 $dev5:0-0 2> err
350#"(cleanup previous test)"
351grep "Insufficient free space" err
352lv_not_changed_ $vg/$lv1
353lv_not_changed_ $vg/$lv2
354lv_not_changed_ $vg/$lv3
355check_and_cleanup_lvs_
356
357# ---------------------------------------------------------------------
358
359#COMM "pvmove abort"
360prepare_lvs_
361pvmove -i100 -b $dev1 $dev3
362pvmove --abort
363check_and_cleanup_lvs_
364
365#COMM "pvmove out of --metadatacopies 0 PV (bz252150)"
366vgremove -ff $vg
367pvcreate $devs
368pvcreate --metadatacopies 0 $dev1 $dev2
369vgcreate $vg $devs
370lvcreate -l4 -n $lv1 $vg $dev1
371pvmove $dev1
372
373#COMM "pvmove fails activating mirror, properly restores state before pvmove"
374dmsetup create "$vg-pvmove0" --notable
375not pvmove -i 1 $dev2
376test $(dmsetup info --noheadings -c -o suspended "$vg-$lv1") = "Active"
377dmsetup remove "$vg-pvmove0"
378