#!/usr/bin/perl -w # # Analyze the LVM configuration # and stor the configuration for restore time # # $Id$ # # Copyright B. Cornec 2008 # Provided under the GPL v2 # Syntax: see below use strict 'vars'; use Getopt::Long qw(:config auto_abbrev no_ignore_case); use Data::Dumper; use English; use File::Basename; use File::Copy; use File::stat; use File::Temp qw(tempdir); use POSIX qw(strftime); use lib qw (lib); use ProjectBuilder::Base; use ProjectBuilder::Distribution; =pod =head1 NAME mrprepare-lvm - A Mindi Tool to restore the LVM configuration and apply it =head1 DESCRIPTION B gets all the information related to the LVM configuration from stdin or a file and prepare a restoration script =head1 SYNOPSIS mrprepare-lvm [-v]|[-q]|[-h]|[--man][-i inputfile][-l logfile][-m multiplier] =head1 OPTIONS =over 4 =item B<-v|--verbose> Be more verbose =item B<-q|--quiet> Do not print any output. =item B<-h|--help> Print a brief help message and exits. =item B<--man> Prints the manual page and exits. =item B<-i|--input> Name of the file to get input from. Use stdin by default The input format is: LVM:lvm-version PV:pv-information as done with pvdisplay -c VG:vg-information as done with vgdisplay -c LV:lv-information as done with lvdisplay -c =item B<-o|--output> Name of the file to write output to. Use stdout by default. The output file is a srpit ready to run in order to setup correctly LVM =back =head1 WEB SITES The main Web site of the project is available at L. Bug reports should be filled using the trac instance of the project at L. =head1 USER MAILING LIST The mailing list of the project is available at L =head1 AUTHORS The Mondorescue.org team L lead by Bruno Cornec L. =head1 COPYRIGHT Analyze-LVM is distributed under the GPL v2.0 license described in the file C included with the distribution. =cut # --------------------------------------------------------------------------- # Globals my %opts; # CLI Options # Initialize the syntax string pb_syntax_init("mrprepare-lvm Version PBVER-rPBREV\n"); # Handle options # GetOptions("help|?|h" => \$opts{'h'}, "man" => \$opts{'man'}, "verbose|v+" => \$opts{'v'}, "quiet|q" => \$opts{'q'}, "input|i=s" => \$opts{'o'}, "output|o=s" => \$opts{'o'}, "multiplier|m=s" => \$opts{'o'}, "log-files|l=s" => \$opts{'l'}, "version|V" => \$opts{'V'}, ) || pb_syntax(-1,0); # easy options if (defined $opts{'h'}) { pb_syntax(0,1); } if (defined $opts{'man'}) { pb_syntax(0,2); } if (defined $opts{'v'}) { $pbdebug = $opts{'v'}; } if (defined $opts{'q'}) { $pbdebug = -1; } my $mrmult = 1; if (defined $opts{'m'}) { $mrmult = $opts{'m'}; } # # Global variables # my $MINDI_VERSION = "PBVER-rPBREV"; my $MINDI_PREFIX = "PBPREFIX"; my $MINDI_CONF = "PBCONF"; my $MINDI_LIB = "PBLIB"; my $MINDI_SBIN = "$MINDI_PREFIX/sbin"; # # Temp dir # pb_temp_init(); # -------------------------------- main ----------------------------------- my ($lvmver,$lvmcmd) = mr_lvm_check(); # Where to send the output my $OUTPUT = \*STDOUT; if (defined $opts{'o'}) { open(OUTPUT, "> $opts{'o'}") || mr_exit(-1, "Unable to write to $opts{'o'}"); $OUTPUT = \*OUTPUT; } # Where to get the input my $INPUT = \*STDIN; if (defined $opts{'i'}) { open(INPUT, " $opts{'i'}") || mr_exit(-1, "Unable to read from $opts{'i'}"); $INPUT = \*INPUT; } # Generate the startup scrit needed to restore LVM conf # from what is given on input # Multiply by the multiplier given in input or 1 of none print $OUTPUT "# Desactivate Volume Groups\n"; print $OUTPUT "$lvmcmd vgchange -an\n"; print $OUTPUT "\n"; my $firsttime = 0; while () { if (/^PV:/) { my ($tag,$pvname,$vgname,$pvsize,$ipvn,$pvstat,$pvna,$lvnum,$pesize,$petot,$pefree,$pelloc) = split(/:/); print $OUTPUT "# Creating Physical Volumes $pvname\n"; print $OUTPUT "$lvmcmd pvcreate -ff -y -s ".$pesize*$mrmult." $pvname\n"; print $OUTPUT "\n"; } elsif (/^VG:/) { my ($tag,$vgname,$vgaccess,$vgstat,$vgnum,$lvmaxnum,$lvnum,$ocalvinvg,$lvmaxsize,$pvmaxnum,$cnumpv,$anumpv,$vgsize,$pesize,$penum,$pealloc,$pefree,$uuid) = split(/:/); if ($lvmver < 2) { print $OUTPUT "# Removing device first as LVM v1 doesn't do it\n"; print $OUTPUT "rm -Rf /dev/$vgname\n"; } $lvmaxnum = 255 if ($lvmaxnum > 256); $pvmaxnum = 255 if ($pvmaxnum > 256); print $OUTPUT "# Create Volume Group $vgname\n"; # Pb sur pesize unite ? print $OUTPUT "$lvmcmd vgcreate $vgname -p $pvmaxnum -s $pesize -l $lvmaxnum\n"; print $OUTPUT "\n"; } elsif (/^LV:/) { if ($firsttime eq 0) { print $OUTPUT "\n"; print $OUTPUT "# Activate All Volume Groups\n"; print $OUTPUT "$lvmcmd vgchange -ay\n"; print $OUTPUT "\n"; $firsttime = 1; } my ($tag,$lvname,$vgname,$lvaccess,$lvstat,$lvnum,$oclv,$lvsize,$leinlv,$lealloc,$allocpol,$readahead,$major,$minor) = split(/:/); print $OUTPUT "# Create Logical Volume $lvname\n"; print $OUTPUT "$lvmcmd lvcreate -n $lvname -L ".$lvsize*$mrmult." -r $readahead $vgname\n"; #[ "$stripes" ] && output="$output -i $stripes" #[ "$stripesize" ] && output="$output -I $stripesize" } } print $OUTPUT "\n"; print $OUTPUT "# Scanning again Volume Groups\n"; print $OUTPUT "$lvmcmd vgscan\n"; print $OUTPUT "\n"; #WriteShutdownScript mr_exit(0,"End of mrprepare-lvm"); sub mr_exit { my $code = shift; my $msg = shift || ""; close(OUTPUT); print $msg."\n"; die "ERROR returned\n" if ($code < 0); print "No LVM handling\n" if ($code > 0); exit(0); }