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 basic operations on mirrored LV works"
14
15. ./test-utils.sh
16
17dmsetup_has_dm_devdir_support_ || exit 200
18
19# ---------------------------------------------------------------------
20# Utilities
21
22lvdev_()
23{
24  echo "$G_dev_/$1/$2"
25}
26
27mimages_are_redundant_ ()
28{
29  local vg=$1
30  local lv=$vg/$2
31  local i
32
33  rm -f out
34  for i in $(lvs -odevices --noheadings $lv | sed 's/([^)]*)//g; s/,/ /g'); do
35    lvs -a -odevices --noheadings $vg/$i | sed 's/([^)]*)//g; s/,/ /g' | \
36      sort | uniq >> out
37  done
38
39  # if any duplication is found, it's not redundant
40  sort out | uniq -d | grep . && return 1
41
42  return 0
43}
44
45lv_is_contiguous_ ()
46{
47  local lv=$1
48
49  # if the lv has multiple segments, it's not contiguous
50  [ $(lvs -a --segments --noheadings $lv | wc -l) -ne 1 ] && return 1
51
52  return 0
53}
54
55lv_is_clung_ ()
56{
57  local lv=$1
58
59  # if any duplication is found, it's not redundant
60  [ $(lvs -a -odevices --noheadings $lv | sed 's/([^)]*)//g' | \
61        sort | uniq | wc -l) -ne 1 ] && return 1
62
63  return 0
64}
65
66mimages_are_contiguous_ ()
67{
68  local vg=$1
69  local lv=$vg/$2
70  local i
71
72  for i in $(lvs -odevices --noheadings $lv | sed 's/([^)]*)//g; s/,/ /g'); do
73    lv_is_contiguous_ $vg/$i || return 1
74  done
75
76  return 0
77}
78
79mimages_are_clung_ ()
80{
81  local vg=$1
82  local lv=$vg/$2
83  local i
84
85  for i in $(lvs -odevices --noheadings $lv | sed 's/([^)]*)//g; s/,/ /g'); do
86    lv_is_clung_ $vg/$i || return 1
87  done
88
89  return 0
90}
91
92mirrorlog_is_on_()
93{
94  local lv="$1"_mlog
95  shift 1
96  lvs -a -odevices --noheadings $lv | sed 's/,/\n/g' > out
97  for d in $*; do grep "$d(" out; done
98  for d in $*; do ! grep -v "$d(" out; done
99  return 0
100}
101
102save_dev_sum_()
103{
104  mkfs.ext3 $1 > /dev/null &&
105  md5sum $1 > md5.$(basename $1)
106}
107
108check_dev_sum_()
109{
110  md5sum $1 > md5.tmp && cmp md5.$(basename $1) md5.tmp
111}
112
113# ---------------------------------------------------------------------
114# Initialize PVs and VGs
115
116aux prepare_vg 5 80
117
118# ---------------------------------------------------------------------
119# Common environment setup/cleanup for each sub testcases
120
121prepare_lvs_()
122{
123  lvremove -ff $vg;
124	if dmsetup table|grep $vg; then
125		echo "ERROR: lvremove did leave some some mappings in DM behind!"
126		return 1
127	fi
128  :
129}
130
131check_and_cleanup_lvs_()
132{
133  lvs -a -o+devices $vg
134  lvremove -ff $vg
135	if dmsetup table|grep $vg; then
136		echo "ERROR: lvremove did leave some some mappings in DM behind!"
137		return 1
138	fi
139}
140
141#COMM "check environment setup/cleanup"
142prepare_lvs_
143check_and_cleanup_lvs_
144
145# ---------------------------------------------------------------------
146# mirrored LV tests
147
148# ---
149# create
150
151#COMM "create 2-way mirror with disklog from 3 PVs"
152prepare_lvs_
153lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
154mimages_are_redundant_ $vg $lv1
155mirrorlog_is_on_ $vg/$lv1 $dev3
156check_and_cleanup_lvs_
157
158#COMM "create 2-way mirror with corelog from 2 PVs"
159prepare_lvs_
160lvcreate -l2 -m1 --mirrorlog core -n $lv1 $vg $dev1 $dev2
161mimages_are_redundant_ $vg $lv1
162check_and_cleanup_lvs_
163
164#COMM "create 3-way mirror with disklog from 4 PVs"
165prepare_lvs_
166lvcreate -l2 -m2 -n $lv1 $vg $dev1 $dev2 $dev4 $dev3:0-1
167mimages_are_redundant_ $vg $lv1
168mirrorlog_is_on_ $vg/$lv1 $dev3
169check_and_cleanup_lvs_
170
171#COMM "lvcreate --nosync is in 100% sync after creation (bz429342)"
172prepare_lvs_
173lvcreate -l2 -m1 --nosync -n $lv1 $vg $dev1 $dev2 $dev3:0-1 2>out
174grep "New mirror won't be synchronised." out
175lvs -o copy_percent --noheadings $vg/$lv1 |grep 100.00
176check_and_cleanup_lvs_
177
178# ---
179# convert
180
181#COMM "convert from linear to 2-way mirror"
182prepare_lvs_
183lvcreate -l2 -n $lv1 $vg $dev1
184lvconvert -m+1 $vg/$lv1 $dev2 $dev3:0-1
185mimages_are_redundant_ $vg $lv1
186mirrorlog_is_on_ $vg/$lv1 $dev3
187check_and_cleanup_lvs_
188
189#COMM "convert from 2-way mirror to linear"
190prepare_lvs_
191lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
192lvconvert -m-1 $vg/$lv1
193mimages_are_redundant_ $vg $lv1
194check_and_cleanup_lvs_
195
196for status in active inactive; do
197# bz192865 lvconvert log of an inactive mirror lv
198#COMM "convert from disklog to corelog"
199prepare_lvs_
200lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
201	test $status = "inactive" && lvchange -an $vg/$lv1
202	yes | lvconvert --mirrorlog core $vg/$lv1
203mimages_are_redundant_ $vg $lv1
204check_and_cleanup_lvs_
205
206#COMM "convert from corelog to disklog"
207prepare_lvs_
208lvcreate -l2 -m1 --mirrorlog core -n $lv1 $vg $dev1 $dev2
209	test $status = "inactive" && lvchange -an $vg/$lv1
210lvconvert --mirrorlog disk $vg/$lv1 $dev3:0-1
211mimages_are_redundant_ $vg $lv1
212mirrorlog_is_on_ $vg/$lv1 $dev3
213check_and_cleanup_lvs_
214done
215
216# ---
217# resize
218
219#COMM "extend 2-way mirror"
220prepare_lvs_
221lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
222lvchange -an $vg/$lv1
223lvextend -l+2 $vg/$lv1
224mimages_are_redundant_ $vg $lv1
225mimages_are_contiguous_ $vg $lv1
226check_and_cleanup_lvs_
227
228#COMM "reduce 2-way mirror"
229prepare_lvs_
230lvcreate -l4 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
231lvchange -an $vg/$lv1
232lvreduce -l-2 $vg/$lv1
233check_and_cleanup_lvs_
234
235#COMM "extend 2-way mirror (cling if not contiguous)"
236prepare_lvs_
237lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
238lvcreate -l1 -n $lv2 $vg $dev1
239lvcreate -l1 -n $lv3 $vg $dev2
240lvchange -an $vg/$lv1
241lvextend -l+2 $vg/$lv1
242mimages_are_redundant_ $vg $lv1
243mimages_are_clung_ $vg $lv1
244check_and_cleanup_lvs_
245
246# ---
247# failure cases
248
249#COMM "create 2-way mirror with disklog from 2 PVs"
250prepare_lvs_
251not lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2
252# "(cleanup previous test)"
253check_and_cleanup_lvs_
254
255#COMM "convert linear to 2-way mirror with 1 PV"
256prepare_lvs_
257lvcreate -l2 -n $lv1 $vg $dev1
258not lvconvert -m+1 --mirrorlog core $vg/$lv1 $dev1
259# "(cleanup previous test)"
260check_and_cleanup_lvs_
261
262# ---
263# resync
264# FIXME: using dm-delay to properly check whether the resync really started
265
266#COMM "force resync 2-way active mirror"
267prepare_lvs_
268lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
269mirrorlog_is_on_ $vg/$lv1 $dev3
270yes | lvchange --resync $vg/$lv1
271mirrorlog_is_on_ $vg/$lv1 $dev3
272check_and_cleanup_lvs_
273
274#COMM "force resync 2-way inactive mirror"
275prepare_lvs_
276lvcreate -l2 -m1 -n $lv1 $vg $dev1 $dev2 $dev3:0-1
277lvchange -an $vg/$lv1
278mirrorlog_is_on_ $vg/$lv1 $dev3
279lvchange --resync $vg/$lv1
280mirrorlog_is_on_ $vg/$lv1 $dev3
281check_and_cleanup_lvs_
282
283# ---------------------------------------------------------------------
284
285