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
RevLine 
[673]1#!/bin/bash
[275]2#
3# $Id: analyze-my-lvm 3029 2012-08-21 13:11:04Z bruno $
4#
[1]5
6Die() {
[298]7 echo "$1" >> /dev/stderr
[963]8 exit -1
[1]9}
10
11
12
13GetValueFromField() {
[298]14 local res
[3016]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/'
[1]16}
17
18
19GetLastBit() {
[298]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"
[1]28}
29
30
31ProcessLogicalVolume() {
[298]32 local LV_full_string fname logical_volume volume_group device
33 LV_full_string=$1
[2244]34 if [ ! -e "$1" ]; then
35 echo "WARNING - cannot find LV file $1" | tee -a /dev/stderr
36 return
37 fi
[298]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`
[1]43 else
[298]44 fname=/proc/lvm/VGs/$volume_group/LVs/$logical_volume
45 if [ ! -e "$fname" ] ; then
[2244]46 echo "WARNING - cannot find $volume_group's $logical_volume LV file" | tee -a /dev/stderr
47 return
[298]48 else
49 device=`GetValueFromField $fname "name:"`
50 params=`GenerateLvcreateParameters $device`
51 fi
[1]52 fi
[2566]53
54 # Exclude LVs member of that env var
55 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
[2995]56 list_of_devices="`mindi --nolog --readalllink $LV_full_string 2> /dev/null`"
[2567]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`"
[2852]62 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
[2566]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
[2534]69 # Do not process LV whose VG are excluded
[2537]70 if [ -f $MINDI_TMP/excludedvgs ]; then
[2684]71 if [ "`grep -x $volume_group $MINDI_TMP/excludedvgs`" != "" ]; then
[2565]72 echo "Not including LV $logical_volume as VG $volume_group was excluded"
[2566]73 return
[2537]74 fi
[2534]75 fi
[2566]76
77 echo "# $LVMCMD lvcreate$params -n $logical_volume $volume_group"
[1]78}
79
80
81GenerateLvcreateParameters() {
[298]82 local device stripes stripesize device fname allocation output readahead
[1487]83 fname=$MINDI_TMP/PLF.$$.txt
[298]84 device=$1
85 output=""
[3016]86 $LVMCMD lvdisplay $device | cat > $fname
[298]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"`
[3016]92 [ ! "`echo "$allocation" | grep "[k,m,g,t]"`" ] && allocation="$allocation"m
[911]93 if echo "$allocation" | grep -E '^.*g$' > /dev/null 2> /dev/null ; then
[298]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"
[1]104}
105
106
107
108GenerateVgcreateParameters() {
[298]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
[1487]111 VG_info_file=$MINDI_TMP/$$.vg-info.txt
[2342]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
[298]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
[1]125}
126
127
128
129ProcessVolumeGroup() {
[298]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`
[2702]134 current_PVs=`$LVMCMD pvscan | grep " $current_VG " | awk '{print $2}' | tr '\n' ' '`
[2571]135 list_of_devices=$current_PVs
[298]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
[2700]142 fname=/proc/lvm/VGs/$current_VG/PVs/$i
143 device=`GetValueFromField $fname "name:"`
144 list_of_devices="$list_of_devices $device"
[298]145 done
[2571]146 current_PVs=$list_of_devices
[298]147 fi
[2072]148 l=""
149 if [ -f /etc/multipath.conf ]; then
[2567]150 # If multipath check which type of devide are given, mpath prefered
[2072]151 for d in $list_of_devices; do
[2995]152 l="$l `mindi --nolog --readalllink $d 2> /dev/null`"
[2072]153 l="$l `GiveMapperOfdm $d`"
154 done
[2567]155 list_of_devices="`echo $l | sort -u`"
[2072]156 fi
157
[2564]158 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
[2852]159 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
[2532]160 if [ "`echo " $list_of_devices" | grep " $ed"`" != "" ]; then
[2534]161 echo $current_VG >> $MINDI_TMP/excludedvgs
[2532]162 return
163 fi
164 done
165 fi
[2571]166 echo "# $LVMCMD vgcreate $current_VG$VG_params $current_PVs"
[298]167 echo "# $LVMCMD vgchange -a y $current_VG"
[1]168}
169
170
171
172ListAllPhysicalVolumes() {
[298]173 if [ $lvmversion = 2 ]; then
[2620]174 $LVMCMD pvscan 2> /dev/null | grep 'PV' | grep -v unknown | awk '{print $2}' > $MINDI_TMP/pv.tmp
[298]175 else
[2072]176 pvscan 2> /dev/null | grep '"' | cut -d'"' -f2 > $MINDI_TMP/pv.tmp
[298]177 fi
[2532]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
[2616]183 l=""
[2995]184 l="$l `mindi --nolog --readalllink $d 2> /dev/null`"
[2567]185 l="$l `GiveMapperOfdm $d`"
186 list_of_devices="`echo $l | sort -u`"
[2564]187 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
[2852]188 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
[2567]189 if [ "`echo " $list_of_devices " | grep " $ed"`" != "" ]; then
[2532]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
[2072]201 if [ -f /etc/multipath.conf ]; then
[2567]202 # If multipath check which type of devide are given, mpath prefered
[2554]203 if [ -f $MINDI_TMP/pv.tmp2 ]; then
[2567]204 l=""
[2554]205 for d in `cat $MINDI_TMP/pv.tmp2`; do
206 skip=0
[2995]207 l="$l `mindi --nolog --readalllink $d 2> /dev/null`"
[2567]208 l="$l `GiveMapperOfdm $d`"
209 list_of_devices="`echo $l | sort -u`"
[2564]210 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
[2852]211 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
[2567]212 if [ "`echo " $list_of_devices " | grep " $ed"`" != "" ]; then
[2554]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
[2072]224 else
[2554]225 if [ -f $MINDI_TMP/pv.tmp2 ]; then
226 cat $MINDI_TMP/pv.tmp2
227 fi
[2072]228 fi
[2532]229 rm -f $MINDI_TMP/pv.tmp $MINDI_TMP/pv.tmp2
[1]230}
231
232
233ListAllVolumeGroups() {
[298]234 $LVMCMD vgdisplay 2> /dev/null | awk '/^ *VG Name/ {print $3;}'
[1]235}
236
[2072]237GiveMapperOfdm () {
[1]238
[3001]239major=`stat -L -c "%t" $1 2> /dev/null`
240minor=`stat -L -c "%T" $1 2> /dev/null`
[2072]241
242for i in `ls /dev/mapper/*`; do
[3001]243 mj=`stat -L -c "%t" $i`
244 mn=`stat -L -c "%T" $i`
[2072]245 if [ "$mj" = "$major" ] && [ "$mn" = "$minor" ]; then
246 echo "$i"
247 return
248 fi
249done
250echo $1
251}
252
253
[1]254ListLvmDrivesAndPartitions() {
[2531]255 # We get partitions in this loop not devices
[2424]256 for d in `$LVMCMD vgdisplay -v 2> /dev/null | grep "PV Name" | sed 's/(#)//' | awk '{print $3}'`; do
[2526]257 # If multipath check which type of devices are given, mpath prefered
[2424]258 if [ -f /etc/multipath.conf ]; then
[2526]259 i=`GiveMapperOfdm $d`
[2536]260 rep=$i
[2424]261 else
[2536]262 rep=$d
[2424]263 fi
[2536]264 skip=0
[2564]265 if [ "$MINDI_EXCLUDE_DEVS" ] ; then
[2852]266 for ed in `echo $MINDI_EXCLUDE_DEVS | sed 's/|/ /g'`; do
[2536]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
[2424]277 done
[1]278}
279
280
281
282PrettifyList() {
[298]283 local i
284 echo -en "$1"
285 for i in $2 ; do
286 echo -en "$i "
287 done
288 echo ""
[1]289}
290
[2925]291ListAllLogicalVolumesSortedBydm() {
[3029]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
[2925]300}
[1]301
302ListAllLogicalVolumes() {
[298]303 if [ $lvmversion = 2 ]; then
[2244]304 $LVMCMD lvscan 2> /dev/null | grep "'" | grep -iw "ACTIVE" | cut -d"'" -f2
[298]305 else
[2244]306 lvscan 2> /dev/null | grep '"' | grep -iw "ACTIVE" | cut -d'"' -f2
[298]307 fi
[1]308}
309
310
311
312WriteShutdownScript() {
[298]313 local i
314 echo ""
315 echo "Finally, to shut down and delete the volumes, do this:-"
[1]316 for i in `ListAllLogicalVolumes` ; do
[298]317 echo "($LVMCMD lvremove -f $i)"
[1]318 done
319 for i in `ListAllVolumeGroups` ; do
[298]320 echo "($LVMCMD vgchange -a n $i)"
[1]321 done
322 for i in `ListAllVolumeGroups` ; do
[298]323 echo "($LVMCMD vgremove $i)"
[1]324 done
[298]325 if [ $lvmversion = 2 ]; then
326 echo "(rmmod dm-mod & rmmod dm_mod & )"
327 else
328 echo "(rmmod lvm-mod)"
329 fi
[1]330}
331
332
333
334# -------------------------------- main -----------------------------------
[2579]335
336if [ "$1" = "--givemapperofdm" ] ; then
337 shift
338 if [ _"$1" != _"" ] ; then
339 GiveMapperOfdm $1
340 fi
341 exit 0
342fi
343
344
[963]345which lvmdiskscan 2>/dev/null 2>&1 || Die "lvmdiskscan not found. Won't handle LVM."
[2044]346if [ -e "/proc/lvm/global" ] && [ "`tr -s '\t' ' ' < /proc/lvm/global | grep "0 VGs 0 PVs 0 LVs"`" != "" ]; then
347 exit 1
[1]348fi
349
[2565]350if [ _"$MINDI_TMP" = _"" ]; then
351 # Launched stdalone, so create a temp dir
[2719]352 STDALONE="true"
[2565]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
[2170]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
[299]374lvmversion=`lvmdiskscan --help 2>&1 |
[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
[97]380if which lvm 2>/dev/null; then
[298]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
[1]387fi
388
389if [ $lvmversion = 2 ]; then
[298]390 echo "LVM version >= 2.0 found."
391 LVMCMD="lvm"
392else
393 LVMCMD=""
[1]394fi
395
[2565]396rm -f $MINDI_TMP/excludedvgs
[1]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
[298]403 echo "(insmod dm-mod)"
404 echo "(insmod dm_mod)"
[1]405else
[298]406 echo "(insmod lvm-mod)"
[1]407fi
[298]408echo "# $LVMCMD vgchange -an"
[1]409for i in `ListAllPhysicalVolumes` ; do
[298]410 echo "# echo y | $LVMCMD pvcreate -ff $i"
[1]411done
[706]412echo "# $LVMCMD vgscan"
[1]413echo ""
414echo "Create and activate the VG's (volume groups)."
415all_volume_groups=`ListAllVolumeGroups`
416for current_VG in $all_volume_groups ; do
[298]417 if [ $lvmversion -ne 2 ]; then
418 echo "# rm -Rf /dev/$current_VG"
419 fi
420 ProcessVolumeGroup $current_VG
[1]421done
422echo ""
423echo "Finally, create the LV's (logical volumes)."
[2925]424all_logical_volumes=`ListAllLogicalVolumesSortedBydm`
[1]425for current_LV in $all_logical_volumes ; do
[298]426 ProcessLogicalVolume $current_LV
[1]427done
428echo ""
[298]429echo "# $LVMCMD vgscan"
[1]430echo "Now you may format the LV's:-"
431for i in `ListAllLogicalVolumes` ; do
[298]432 echo "(mkfs -t foo $i or something like that)"
[1]433done
[2565]434rm -f $MINDI_TMP/excludedvgs
[1]435WriteShutdownScript
[2719]436if [ _"$STDALONE" = _"true" ]; then
437 rm -rf $MINDI_TMP
438fi
[1]439exit 0
440
441
442
Note: See TracBrowser for help on using the repository browser.