source: MondoRescue/branches/3.0/mindi/analyze-my-lvm@ 3029

Last change on this file since 3029 was 3029, checked in by Bruno Cornec, 12 years ago
  • Fix an issue in analyzing dm devices, when habing more than 10 LVs, the sort wasn't respecting the numerical order, and at restore time, the LVs were not created back correctly (11 coming before 2) (Martin Kitka/Didier Diaz)
  • Property svn:keywords set to Id
File size: 11.3 KB
Line 
1#!/bin/bash
2#
3# $Id: analyze-my-lvm 3029 2012-08-21 13:11:04Z bruno $
4#
5
6Die() {
7 echo "$1" >> /dev/stderr
8 exit -1
9}
10
11
12
13GetValueFromField() {
14 local res
15 grep -i "$2" "$1" | perl -pi -e 's/\s*(.*)\s\s\s+(.+)$/$2/;s/\sT[i]*B/t/;s/\sG[i]*B/g/;s/\sM[i]*B/m/;s/\sK[i]*B/k/'
16}
17
18
19GetLastBit() {
20 local i res
21 i=20
22 res=""
23 while [ ! "$res" ] ; do
24 i=$(($i-1))
25 res=`echo "$1" | cut -d'/' -f$i`
26 done
27 echo "$res"
28}
29
30
31ProcessLogicalVolume() {
32 local LV_full_string fname logical_volume volume_group device
33 LV_full_string=$1
34 if [ ! -e "$1" ]; then
35 echo "WARNING - cannot find LV file $1" | tee -a /dev/stderr
36 return
37 fi
38 volume_group=`echo "$LV_full_string" | cut -d'/' -f3`
39 logical_volume=`echo "$LV_full_string" | cut -d'/' -f4`
40 if [ $lvmversion = 2 ]; then
41 device=$LV_full_string
42 params=`GenerateLvcreateParameters $device`
43 else
44 fname=/proc/lvm/VGs/$volume_group/LVs/$logical_volume
45 if [ ! -e "$fname" ] ; then
46 echo "WARNING - cannot find $volume_group's $logical_volume LV file" | tee -a /dev/stderr
47 return
48 else
49 device=`GetValueFromField $fname "name:"`
50 params=`GenerateLvcreateParameters $device`
51 fi
52 fi
53
54 # Exclude LVs member of that env var
55 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
56 list_of_devices="`mindi --nolog --readalllink $LV_full_string 2> /dev/null`"
57 l=""
58 for d in $list_of_devices; do
59 l="$l `GiveMapperOfdm $d`"
60 done
61 list_of_devices="`echo $l | sort -u`"
62 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
63 if [ "`echo " $list_of_devices" | grep " $ed"`" != "" ]; then
64 echo "Not including device $LV_full_string as it was excluded"
65 return
66 fi
67 done
68 fi
69 # Do not process LV whose VG are excluded
70 if [ -f $MINDI_TMP/excludedvgs ]; then
71 if [ "`grep -x $volume_group $MINDI_TMP/excludedvgs`" != "" ]; then
72 echo "Not including LV $logical_volume as VG $volume_group was excluded"
73 return
74 fi
75 fi
76
77 echo "# $LVMCMD lvcreate$params -n $logical_volume $volume_group"
78}
79
80
81GenerateLvcreateParameters() {
82 local device stripes stripesize device fname allocation output readahead
83 fname=$MINDI_TMP/PLF.$$.txt
84 device=$1
85 output=""
86 $LVMCMD lvdisplay $device | cat > $fname
87 stripes=`GetValueFromField $fname "Stripes"`
88 stripesize=`GetValueFromField $fname "Stripe size (MByte)"`m
89 [ "$stripesize" = "m" ] && stripesize=`GetValueFromField $fname "Stripe size (KByte)"`k
90 [ "$stripesize" = "k" ] && stripesize=""
91 allocation=`GetValueFromField $fname "LV Size"`
92 [ ! "`echo "$allocation" | grep "[k,m,g,t]"`" ] && allocation="$allocation"m
93 if echo "$allocation" | grep -E '^.*g$' > /dev/null 2> /dev/null ; then
94 val=`echo "$allocation" | sed s/g//`
95 allocation=`echo "$val" | awk '{c=$1; printf "%d", c*1024;}'`m
96 fi
97 readahead=`GetValueFromField $fname "Read ahead sectors"`
98 rm -f $fname
99 [ "$stripes" ] && output="$output -i $stripes"
100 [ "$stripesize" ] && output="$output -I $stripesize"
101 [ "$allocation" ] && output="$output -L $allocation"
102 [ "$readahead" ] && output="$output -r $readahead"
103 echo "$output"
104}
105
106
107
108GenerateVgcreateParameters() {
109 local current_VG device fname incoming VG_info_file max_logical_volumes max_physical_volumes physical_extent_size output blanklines
110 current_VG=$1
111 VG_info_file=$MINDI_TMP/$$.vg-info.txt
112 # We use cat here as a way to avoid SElinux to prevent us from writing in $VG_info_file
113 $LVMCMD vgdisplay $current_VG | cat > $VG_info_file
114 max_logical_volumes=`GetValueFromField "$VG_info_file" "MAX LV"`
115 [ $max_logical_volumes -ge 256 ] && max_logical_volumes=255
116 max_physical_volumes=`GetValueFromField "$VG_info_file" "MAX PV"`
117 [ $max_physical_volumes -ge 256 ] && max_physical_volumes=255
118 physical_extent_size=`GetValueFromField "$VG_info_file" "PE Size"`
119 output=""
120 [ "$max_logical_volumes" ] && output="$output -l $max_logical_volumes"
121 [ "$max_physical_volumes" ] && output="$output -p $max_physical_volumes"
122 [ "$physical_extent_size" ] && output="$output -s $physical_extent_size"
123 echo "$output"
124 rm -f $VG_info_file
125}
126
127
128
129ProcessVolumeGroup() {
130 local current_VG physical_volumes i list_of_devices VG_params
131 current_VG=$1
132 if [ $lvmversion = 2 ]; then
133 VG_params=`GenerateVgcreateParameters $current_VG`
134 current_PVs=`$LVMCMD pvscan | grep " $current_VG " | awk '{print $2}' | tr '\n' ' '`
135 list_of_devices=$current_PVs
136 else
137 info_file=/proc/lvm/VGs/$current_VG/group
138 physical_volumes=`ls /proc/lvm/VGs/$current_VG/PVs`
139 VG_params=`GenerateVgcreateParameters $current_VG`
140 list_of_devices=""
141 for i in $physical_volumes ; do
142 fname=/proc/lvm/VGs/$current_VG/PVs/$i
143 device=`GetValueFromField $fname "name:"`
144 list_of_devices="$list_of_devices $device"
145 done
146 current_PVs=$list_of_devices
147 fi
148 l=""
149 if [ -f /etc/multipath.conf ]; then
150 # If multipath check which type of devide are given, mpath prefered
151 for d in $list_of_devices; do
152 l="$l `mindi --nolog --readalllink $d 2> /dev/null`"
153 l="$l `GiveMapperOfdm $d`"
154 done
155 list_of_devices="`echo $l | sort -u`"
156 fi
157
158 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
159 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
160 if [ "`echo " $list_of_devices" | grep " $ed"`" != "" ]; then
161 echo $current_VG >> $MINDI_TMP/excludedvgs
162 return
163 fi
164 done
165 fi
166 echo "# $LVMCMD vgcreate $current_VG$VG_params $current_PVs"
167 echo "# $LVMCMD vgchange -a y $current_VG"
168}
169
170
171
172ListAllPhysicalVolumes() {
173 if [ $lvmversion = 2 ]; then
174 $LVMCMD pvscan 2> /dev/null | grep 'PV' | grep -v unknown | awk '{print $2}' > $MINDI_TMP/pv.tmp
175 else
176 pvscan 2> /dev/null | grep '"' | cut -d'"' -f2 > $MINDI_TMP/pv.tmp
177 fi
178
179 rm -f $MINDI_TMP/pv.tmp2
180 for d in `cat $MINDI_TMP/pv.tmp`; do
181 # Skip devices excluded, coming from mondoarchive
182 skip=0
183 l=""
184 l="$l `mindi --nolog --readalllink $d 2> /dev/null`"
185 l="$l `GiveMapperOfdm $d`"
186 list_of_devices="`echo $l | sort -u`"
187 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
188 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
189 if [ "`echo " $list_of_devices " | grep " $ed"`" != "" ]; then
190 skip=1
191 continue
192 fi
193 done
194 fi
195 if [ $skip -eq 1 ]; then
196 continue
197 fi
198 echo $d >> $MINDI_TMP/pv.tmp2
199 done
200
201 if [ -f /etc/multipath.conf ]; then
202 # If multipath check which type of devide are given, mpath prefered
203 if [ -f $MINDI_TMP/pv.tmp2 ]; then
204 l=""
205 for d in `cat $MINDI_TMP/pv.tmp2`; do
206 skip=0
207 l="$l `mindi --nolog --readalllink $d 2> /dev/null`"
208 l="$l `GiveMapperOfdm $d`"
209 list_of_devices="`echo $l | sort -u`"
210 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
211 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
212 if [ "`echo " $list_of_devices " | grep " $ed"`" != "" ]; then
213 skip=1
214 continue
215 fi
216 done
217 fi
218 if [ $skip -eq 1 ]; then
219 continue
220 fi
221 GiveMapperOfdm $d
222 done
223 fi
224 else
225 if [ -f $MINDI_TMP/pv.tmp2 ]; then
226 cat $MINDI_TMP/pv.tmp2
227 fi
228 fi
229 rm -f $MINDI_TMP/pv.tmp $MINDI_TMP/pv.tmp2
230}
231
232
233ListAllVolumeGroups() {
234 $LVMCMD vgdisplay 2> /dev/null | awk '/^ *VG Name/ {print $3;}'
235}
236
237GiveMapperOfdm () {
238
239major=`stat -L -c "%t" $1 2> /dev/null`
240minor=`stat -L -c "%T" $1 2> /dev/null`
241
242for i in `ls /dev/mapper/*`; do
243 mj=`stat -L -c "%t" $i`
244 mn=`stat -L -c "%T" $i`
245 if [ "$mj" = "$major" ] && [ "$mn" = "$minor" ]; then
246 echo "$i"
247 return
248 fi
249done
250echo $1
251}
252
253
254ListLvmDrivesAndPartitions() {
255 # We get partitions in this loop not devices
256 for d in `$LVMCMD vgdisplay -v 2> /dev/null | grep "PV Name" | sed 's/(#)//' | awk '{print $3}'`; do
257 # If multipath check which type of devices are given, mpath prefered
258 if [ -f /etc/multipath.conf ]; then
259 i=`GiveMapperOfdm $d`
260 rep=$i
261 else
262 rep=$d
263 fi
264 skip=0
265 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
266 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
267 if [ "`echo " $rep " | grep " $ed"`" != "" ]; then
268 skip=1
269 continue
270 fi
271 done
272 fi
273 if [ $skip -eq 1 ]; then
274 continue
275 fi
276 echo $rep
277 done
278}
279
280
281
282PrettifyList() {
283 local i
284 echo -en "$1"
285 for i in $2 ; do
286 echo -en "$i "
287 done
288 echo ""
289}
290
291ListAllLogicalVolumesSortedBydm() {
292 rm -f $MINDI_TMP/sorteddm
293 for d in `ListAllLogicalVolumes` ; do
294 dm=`mindi --nolog --readalllink $d 2> /dev/null | tail -1`
295 echo "$dm|$d" >> $MINDI_TMP/sorteddm
296 done
297 if [ -f $MINDI_TMP/sorteddm ]; then
298 sort -t'|' -n $MINDI_TMP/sorteddm | cut -d'|' -f2
299 fi
300}
301
302ListAllLogicalVolumes() {
303 if [ $lvmversion = 2 ]; then
304 $LVMCMD lvscan 2> /dev/null | grep "'" | grep -iw "ACTIVE" | cut -d"'" -f2
305 else
306 lvscan 2> /dev/null | grep '"' | grep -iw "ACTIVE" | cut -d'"' -f2
307 fi
308}
309
310
311
312WriteShutdownScript() {
313 local i
314 echo ""
315 echo "Finally, to shut down and delete the volumes, do this:-"
316 for i in `ListAllLogicalVolumes` ; do
317 echo "($LVMCMD lvremove -f $i)"
318 done
319 for i in `ListAllVolumeGroups` ; do
320 echo "($LVMCMD vgchange -a n $i)"
321 done
322 for i in `ListAllVolumeGroups` ; do
323 echo "($LVMCMD vgremove $i)"
324 done
325 if [ $lvmversion = 2 ]; then
326 echo "(rmmod dm-mod & rmmod dm_mod & )"
327 else
328 echo "(rmmod lvm-mod)"
329 fi
330}
331
332
333
334# -------------------------------- main -----------------------------------
335
336if [ "$1" = "--givemapperofdm" ] ; then
337 shift
338 if [ _"$1" != _"" ] ; then
339 GiveMapperOfdm $1
340 fi
341 exit 0
342fi
343
344
345which lvmdiskscan 2>/dev/null 2>&1 || Die "lvmdiskscan not found. Won't handle LVM."
346if [ -e "/proc/lvm/global" ] && [ "`tr -s '\t' ' ' < /proc/lvm/global | grep "0 VGs 0 PVs 0 LVs"`" != "" ]; then
347 exit 1
348fi
349
350if [ _"$MINDI_TMP" = _"" ]; then
351 # Launched stdalone, so create a temp dir
352 STDALONE="true"
353 MINDI_TMP=`mktemp -d $TMPDIR/mindi.XXXXXXXXXX`
354 if [ $? -ne 0 ]; then
355 df $TMPDIR
356 Die "Unable to create a temporary directory ! Check space on $TMPDIR"
357 fi
358 if [ _"$MINDI_TMP" = _"" ]; then
359 Die "MINDI_TMP is empty, aborting"
360 fi
361 if [ _"$MINDI_TMP" = _"/" ]; then
362 Die "MINDI_TMP is /, aborting"
363 fi
364fi
365
366# Older lvmdiskscan use --help, newer --version
367lvmopt="--help"
368lvmdiskscan $lvmopt 2>&1 | grep -q -- "--version"
369if [ $? -eq 0 ]; then
370 lvmopt="--version"
371fi
372
373
374lvmversion=`lvmdiskscan --help 2>&1 |
375 grep -E "Logical Volume Manager|LVM version:" |
376 cut -d: -f2 | cut -d. -f1 |
377 awk '{print $NF}' |
378 sed -e 's/ //g'`
379
380if which lvm 2>/dev/null; then
381 version=`lvm version | grep "LVM version" | awk '{print $3}'`
382 i="`echo "$version" | cut -d'.' -f1`"
383 echo "i=$i"
384 if [ "$i" -ge "2" ] ; then
385 lvmversion=2
386 fi
387fi
388
389if [ $lvmversion = 2 ]; then
390 echo "LVM version >= 2.0 found."
391 LVMCMD="lvm"
392else
393 LVMCMD=""
394fi
395
396rm -f $MINDI_TMP/excludedvgs
397all_lvm_drives_and_partitions=`ListLvmDrivesAndPartitions`
398echo "Just before you extrapolate mountlist to include RAID partitions,"
399echo "extrapolate it to include the following LVM drives and partitions:-"
400PrettifyList ">>>>> " "$all_lvm_drives_and_partitions"
401echo "To get started, type:-"
402if [ $lvmversion = 2 ]; then
403 echo "(insmod dm-mod)"
404 echo "(insmod dm_mod)"
405else
406 echo "(insmod lvm-mod)"
407fi
408echo "# $LVMCMD vgchange -an"
409for i in `ListAllPhysicalVolumes` ; do
410 echo "# echo y | $LVMCMD pvcreate -ff $i"
411done
412echo "# $LVMCMD vgscan"
413echo ""
414echo "Create and activate the VG's (volume groups)."
415all_volume_groups=`ListAllVolumeGroups`
416for current_VG in $all_volume_groups ; do
417 if [ $lvmversion -ne 2 ]; then
418 echo "# rm -Rf /dev/$current_VG"
419 fi
420 ProcessVolumeGroup $current_VG
421done
422echo ""
423echo "Finally, create the LV's (logical volumes)."
424all_logical_volumes=`ListAllLogicalVolumesSortedBydm`
425for current_LV in $all_logical_volumes ; do
426 ProcessLogicalVolume $current_LV
427done
428echo ""
429echo "# $LVMCMD vgscan"
430echo "Now you may format the LV's:-"
431for i in `ListAllLogicalVolumes` ; do
432 echo "(mkfs -t foo $i or something like that)"
433done
434rm -f $MINDI_TMP/excludedvgs
435WriteShutdownScript
436if [ _"$STDALONE" = _"true" ]; then
437 rm -rf $MINDI_TMP
438fi
439exit 0
440
441
442
Note: See TracBrowser for help on using the repository browser.