#!/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<mrprepare-lvm> 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<http://www.mondorescue.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.mondorescue.org/>.

=head1 USER MAILING LIST

The mailing list of the project is available at L<mailto:mondo@lists.sf.net>
 
=head1 AUTHORS

The Mondorescue.org team L<http://www.mondorescue.org/> lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.

=head1 COPYRIGHT

Analyze-LVM is distributed under the GPL v2.0 license
described in the file C<COPYING> 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 (<INPUT>) {
	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";
		}
		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);
}
