source: MondoRescue/devel/mindi/bin/analyze-lvm@ 2076

Last change on this file since 2076 was 2076, checked in by Bruno Cornec, 15 years ago

adds a new analyze-lvm for devel, which is not finished, nor working, not syntacticly correct :-)

  • Property svn:executable set to *
File size: 9.9 KB
Line 
1#!/usr/bin/perl -w
2#
3# Analyze the LVM configuration
4# and stor the configuration for restore time
5#
6# $Id$
7#
8# Copyright B. Cornec 2008
9# Provided under the GPL v2
10
11# Syntax: see below
12
13use strict 'vars';
14use Getopt::Long qw(:config auto_abbrev no_ignore_case);
15use Data::Dumper;
16use English;
17use File::Basename;
18use File::Copy;
19use File::stat;
20use File::Temp qw(tempdir);
21use POSIX qw(strftime);
22use lib qw (lib);
23use ProjectBuilder::Base;
24use ProjectBuilder::Distribution;
25
26=pod
27
28=head1 NAME
29
30Analyze-lvm - A Mindi Tool to analyze the LVM configuration and store it
31
32=head1 DESCRIPTION
33
34B<anlyze-lvm> prints all the information related to the LVM configuration that may be used by a restoration process
35
36=head1 SYNOPSIS
37
38analyze-lvm [-v]|[-q]|[-h]|[--man]
39
40=head1 OPTIONS
41
42=over 4
43
44=item B<-v|--verbose>
45
46Print a brief help message and exits.
47
48
49=item B<-q|--quiet>
50
51Do not print any output.
52
53=item B<-h|--help>
54
55Print a brief help message and exits.
56
57=item B<--man>
58
59Prints the manual page and exits.
60
61=item B<-i|--iso iso_image>
62
63Name of the ISO image you want to created.
64
65=back
66
67=head1 WEB SITES
68
69The main Web site of the project is available at L<http://www.mondorescue.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.mondorescue.org/>.
70
71=head1 USER MAILING LIST
72
73The miling list of the project is available at L<mailto:mondo@lists.sf.net>
74
75=head1 AUTHORS
76
77The Mondorescue.org team L<http://www.mondorescue.org/> lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.
78
79=head1 COPYRIGHT
80
81Analyze-LVM is distributed under the GPL v2.0 license
82described in the file C<COPYING> included with the distribution.
83
84=cut
85
86
87# ---------------------------------------------------------------------------
88
89# Initialize the syntax string
90
91pb_syntax_init("analyze-lvm Version PBVER-rPBREV\n");
92
93# Handle options
94#
95GetOptions("help|?|h" => \$opts{'h'},
96 "man" => \$opts{'man'},
97 "verbose|v+" => \$opts{'v'},
98 "quiet|q" => \$opts{'q'},
99 "log-files|l=s" => \$opts{'l'},
100 "version|V" => \$opts{'V'},
101) || pb_syntax(-1,0);
102
103# easy options
104if (defined $opts{'h'}) {
105 pb_syntax(0,1);
106}
107if (defined $opts{'man'}) {
108 pb_syntax(0,2);
109}
110if (defined $opts{'v'}) {
111 $pbdebug = $opts{'v'};
112}
113if (defined $opts{'q'}) {
114 $pbdebug=-1;
115}
116
117#
118# Global variables
119#
120my $MINDI_VERSION = "PBVER-rPBREV";
121my $MINDI_PREFIX = "PBPREFIX";
122my $MINDI_CONF = "PBCONF";
123my $MINDI_LIB = "PBLIB";
124my $MINDI_SBIN = "$MINDI_PREFIX/sbin";
125#
126# Temp dir
127#
128pb_temp_init();
129
130my $lvmds = "/usr/sbin/lvmdiskscan";
131my $lvmproc = "/proc/lvm/global";
132my $lvmcmd = "/usr/sbi/lvm";
133
134# -------------------------------- main -----------------------------------
135mr_exit(-1,"$lvmds doesn't exist. No LVM handling.") if ((! -x $lvmds) ;
136mr_exit(-1,"$lvmproc doesn't exist. No LVM handling.") if ((! -x $lvmproc) ;
137
138# Check LVM volumes presence
139open(LVM,$lvmproc) || mr_exit(-1,"Unable to open $lvmproc");
140while (<LVM>) {
141 mr_exit(1,"No LVM volumes found in $lvmproc") if (/0 VGs 0 PVs 0 LVs/);
142}
143close(LVM);
144
145# Check LVM version
146my $lvmver=0;
147open(LVM,"$lvmds --help 2>&1 |") || mr_exit(-1,"Unable to execute $lvmds");
148while (<LVM>) {
149 if (/Logical Volume Manager/ || /LVM version:/) {
150 $lvmver = $_;
151 $lvmver =~ s/:([0-9])\..*/$1/;
152 }
153}
154close(LVM);
155#lvmversion=`lvmdiskscan --help 2>&1 |
156#grep -E "Logical Volume Manager|LVM version:" |
157#cut -d: -f2 | cut -d. -f1 |
158#awk '{print $NF}' |
159#sed -e 's/ //g'`
160
161if ($lvmver = 0) {
162 # Still not found
163 if (-x $lvmcmd) {
164 open(LVM,"$lvmcmd version |") || mr_exit(-1,"Unable to execute $lvmcmd");
165 while (<LVM>) {
166 if (/LVM version/) {
167 $lvmver = $_;
168 $lvmver =~ s/LVM version ([0-9])\..*/$1/;
169 }
170 }
171 close(LVM);
172 }
173}
174
175if ($lvmver = 0) {
176 # Still not found
177 mr_exit(-1,"Unable to determine LVM version.\nPlease report to the dev team with the result of the commands\n$lvmds and $lvmvmd version");
178} elsif ($lvmver = 1) {
179 $lvmcmd = "";
180}
181pb_log(0,"Found LVM version $lvmver");
182
183# For the moment on stdout
184OUTPUT = \*STDOUT;
185
186# Generate the startup scrit on the fly needed to restore LVM conf
187print OUTPUT "# Desactivate Volume Groups\n";
188print OUTPUT "$lvmcmd vgchange -an\n";
189print OUTPUT "\n";
190
191# Analyze the existing physical volumes
192my @lvmpvs = ();
193open(LVM,"$lvmcmd pvdisplay |") || mr_exit(-1,"Unable to execute $lvmcmd pvdisplay");
194while (<LVM>) {
195 if (/PV Name/) {
196 my $lvmpv = $_;
197 $lvmpv =~ s/^\s*PV Name ([A-z0-9/])/$1/;
198 }
199 push($lvmpv,@lvmpvs);
200}
201close(LVM);
202
203ListAllPhysicalVolumes() {
204 if [ $lvmversion = 2 ]; then
205 $LVMCMD pvscan 2> /dev/null | grep 'PV' | awk '{print $2}'
206 else
207 pvscan 2> /dev/null | grep '"' | cut -d'"' -f2
208 fi
209}
210print OUTPUT "# Creating Physical Volumes\n";
211foreach my $pv (@lvmpvs) {
212 print OUTPUT "echo y | $lvmcmd pvcreate -ff $pv\n";
213}
214print OUTPUT "\n";
215
216print OUTPUT "# Scanning again Volume Groups\n";
217print OUTPUT "$lvmcmd vgscan\n";
218print OUTPUT "\n";
219
220# Analyze the existing volume groups
221print OUTPUT "# Creating Volume Groups and Activating them\n";
222my @lvmvgs = ();
223open(LVM,"$lvmcmd vgdisplay |") || mr_exit(-1,"Unable to execute $lvmcmd vgdisplay");
224while (<LVM>) {
225 if (/VG Name/) {
226 my $lvmvg = $_;
227 $lvmvg =~ s/^\s*VG Name ([A-z0-9/])/$1/;
228 #$LVMCMD vgdisplay 2> /dev/null | awk '/^ *VG Name/ {print $3;}'
229 }
230 push($lvmvg,@lvmvgs);
231}
232close(LVM);
233
234foreach my $vg (@lvmvgs) {
235 if ($lvmver < 2) {
236 print OUTPUT "# Removing device first as LVM v1 doesn't do it\n";
237 print OUTPUT "rm -Rf /dev/$vg\n";
238 }
239 mr_lvm_create_vg($vg);
240}
241
242sub mr_lvm_create_vg {
243
244my $vg = shift;
245
246$vg_params=`GenerateVgcreateParameters $vg`
247GenerateVgcreateParameters() {
248 local current_VG device fname incoming VG_info_file max_logical_volumes max_physical_volumes physical_extent_size output blanklines
249 current_VG=$1
250 VG_info_file=$MINDI_TMP/$$.vg-info.txt
251 $LVMCMD vgdisplay $current_VG > $VG_info_file
252 max_logical_volumes=`GetValueFromField "$VG_info_file" "MAX LV"`
253 [ $max_logical_volumes -ge 256 ] && max_logical_volumes=255
254 max_physical_volumes=`GetValueFromField "$VG_info_file" "MAX PV"`
255 [ $max_physical_volumes -ge 256 ] && max_physical_volumes=255
256 physical_extent_size=`GetValueFromField "$VG_info_file" "PE Size"`
257 output=""
258 [ "$max_logical_volumes" ] && output="$output -l $max_logical_volumes"
259 [ "$max_physical_volumes" ] && output="$output -p $max_physical_volumes"
260 [ "$physical_extent_size" ] && output="$output -s $physical_extent_size"
261 echo "$output"
262 rm -f $VG_info_file
263}
264
265
266if ($lvmver = 1) {
267 $info_file = "/proc/lvm/VGs/$vg/group";
268 $pvs=`ls /proc/lvm/VGs/$vg/PVs`
269 $list_of_devices=""
270 for i in $pvs ; do
271 fname=/proc/lvm/VGs/$vg/PVs/$i
272 device=`GetValueFromField $fname "name:"`
273 $list_of_devices="$list_of_devices $device"
274 done
275} elsif ($lvmver = 2) {
276 $list_of_devices=`$lvmcmd pvs | grep " $vg " | awk '{print $1}'`
277}
278 print OUTPUT "# Create Volume Group $vg\n";
279 print OUTPUT "$lvmcmd vgcreate $vg $vg_param $list_of_devices\n";
280 print OUTPUT "# Activate Volume Group $vg\n";
281 print OUTPUT "$lvmcmd vgchnge -a y $vg\n";
282}
283
284echo "Finally, create the LV's (logical volumes)."
285all_logical_volumes=`ListAllLogicalVolumes`
286for current_LV in $all_logical_volumes ; do
287 ProcessLogicalVolume $current_LV
288done
289echo ""
290echo "# $LVMCMD vgscan"
291echo "Now you may format the LV's:-"
292for i in `ListAllLogicalVolumes` ; do
293 echo "(mkfs -t foo $i or something like that)"
294done
295WriteShutdownScript
296exit 0
297
298
299GetValueFromField() {
300 local res
301 sed s/' '/~/ "$1" | tr -s ' ' ' ' | sed s/'~ '/'~'/ | grep -i "$2~" | cut -d'~' -f2,3,4,5 | tr '~' ' ' | gawk '{ if ($2=="MB") {printf "%dm",$1;} else if ($2=="KB") {printf "%dk",$1;} else if ($2=="GB") {printf "%fg",$1;} else {print $0;};}'
302}
303
304
305GetLastBit() {
306 local i res
307 i=20
308 res=""
309 while [ ! "$res" ] ; do
310 i=$(($i-1))
311 res=`echo "$1" | cut -d'/' -f$i`
312 done
313 echo "$res"
314}
315
316
317ProcessLogicalVolume() {
318 local LV_full_string fname logical_volume volume_group device
319 LV_full_string=$1
320 [ ! -e "$1" ] && Die "Cannot find LV file $1"
321 volume_group=`echo "$LV_full_string" | cut -d'/' -f3`
322 logical_volume=`echo "$LV_full_string" | cut -d'/' -f4`
323 if [ $lvmversion = 2 ]; then
324 device=$LV_full_string
325 params=`GenerateLvcreateParameters $device`
326 else
327 fname=/proc/lvm/VGs/$volume_group/LVs/$logical_volume
328 if [ ! -e "$fname" ] ; then
329 echo "Warning - cannot find $volume_group's $logical_volume LV file"
330 else
331 device=`GetValueFromField $fname "name:"`
332 params=`GenerateLvcreateParameters $device`
333 fi
334 fi
335 echo "# $LVMCMD lvcreate$params -n $logical_volume $volume_group"
336}
337
338
339GenerateLvcreateParameters() {
340 local device stripes stripesize device fname allocation output readahead
341 fname=$MINDI_TMP/PLF.$$.txt
342 device=$1
343 output=""
344 $LVMCMD lvdisplay $device > $fname
345 stripes=`GetValueFromField $fname "Stripes"`
346 stripesize=`GetValueFromField $fname "Stripe size (MByte)"`m
347 [ "$stripesize" = "m" ] && stripesize=`GetValueFromField $fname "Stripe size (KByte)"`k
348 [ "$stripesize" = "k" ] && stripesize=""
349 allocation=`GetValueFromField $fname "LV Size"`
350 [ ! "`echo "$allocation" | grep "[k,m,g]"`" ] && allocation="$allocation"m
351 if echo "$allocation" | grep -E '^.*g$' > /dev/null 2> /dev/null ; then
352 val=`echo "$allocation" | sed s/g//`
353 allocation=`echo "$val" | awk '{c=$1; printf "%d", c*1024;}'`m
354 fi
355 readahead=`GetValueFromField $fname "Read ahead sectors"`
356 rm -f $fname
357 [ "$stripes" ] && output="$output -i $stripes"
358 [ "$stripesize" ] && output="$output -I $stripesize"
359 [ "$allocation" ] && output="$output -L $allocation"
360 [ "$readahead" ] && output="$output -r $readahead"
361 echo "$output"
362}
363
364
365
366
367
368
369ListAllLogicalVolumes() {
370 if [ $lvmversion = 2 ]; then
371 $LVMCMD lvscan 2> /dev/null | grep "'" | cut -d"'" -f2
372 else
373 lvscan 2> /dev/null | grep '"' | cut -d'"' -f2
374 fi
375}
376
377
378
379WriteShutdownScript() {
380 local i
381 echo ""
382 echo "Finally, to shut down and delete the volumes, do this:-"
383 for i in `ListAllLogicalVolumes` ; do
384 echo "($LVMCMD lvremove -f $i)"
385 done
386 for i in `ListAllVolumeGroups` ; do
387 echo "($LVMCMD vgchange -a n $i)"
388 done
389 for i in `ListAllVolumeGroups` ; do
390 echo "($LVMCMD vgremove $i)"
391 done
392 if [ $lvmversion = 2 ]; then
393 echo "(rmmod dm-mod & rmmod dm_mod & )"
394 else
395 echo "(rmmod lvm-mod)"
396 fi
397}
398
399
400
Note: See TracBrowser for help on using the repository browser.