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