#!/usr/bin/perl
#
#
# Copyright (c) 2006 Zmanda Inc.  All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
# Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
# Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
#

use strict;
use warnings;
use Getopt::Long;
use File::Path;
use lib '/usr/lib/mysql-zrm';
use ZRM::SnapshotCommon;


$SIG{'TERM'} = sub { &printAndDie("TERM signal"); };

my $LVCREATE="lvcreate";
my $LVDISPLAY="lvdisplay";
my $LVREMOVE="lvremove -f";
my $NOUUID=" -o nouuid ";
my $DEV="/dev/";
my $MAPPER="/dev/mapper/";

# Uses df to get the device name and filesystem type
# Uses lvdisplay to see if this device is an lvm volume
# $_[0] directory name
# $_[1] snapshot name
sub getSnapshotDeviceDetails()
{
	my $snapshotName = $_[1];
        my @ret = `sudo $DF '$_[0]'`;
        if( $? != 0 ) {
                &printAndDie( "Failed to find database: ".$_[0] );
        }
	chomp( @ret );
        my @fs = split(" " , $ret[1]);
        my $dev = $fs[0];
        my $volumeGroup;
        my $volumeName;

	# If mapper is being used the device 
	# output from df will show /dev/mapper/volume-group/volume-name. 
	# Split this up and create the actual device path
        if( $fs[0]=~/^$MAPPER/ ){
		my $x = $';
		$x =~ /([^-])-([^-])/;
		$volumeGroup = $`.$1;
		$volumeName = $2.$';
		$volumeGroup =~ s/--/-/g;
		$volumeName =~ s/--/-/g;
                $dev = "/dev/".$volumeGroup."/".$volumeName;
        } else {
                if( $fs[0]=~/^$DEV/ ){
                        ($volumeGroup, $volumeName) = split( "/", $' );
                }
        }
        @ret = `sudo $LVDISPLAY $dev 2>&1`;
        if( $? == 0 ) {
		print "device=$dev\n";
		print "snapshot-device=/dev/$volumeGroup/$snapshotName\n";
		print "device-mount-point=$fs[6]\n";
		print "filesystem-type=$fs[1]\n";
                my $str = &getCommonDetails( $_[0], $_[1], $fs[6] );
                print $str;
        }
}

sub doGetSnapshotdeviceDetails()
{
	if( !defined $opt{"directory"} ){
		&printAndDie( "Please supply --directory" );
	} 
	if( !defined  $opt{"sname"} ) {
		&printAndDie( "Please supply --sname" );
	}
	&getSnapshotDeviceDetails( $opt{"directory"}, $opt{"sname"} );
}

sub doCreateSnapshot()
{
	if( !defined $opt{"dev"} ){
		&printAndDie( "Please input --dev" );
	}
	if( !defined $opt{"sname"} ){
		&printAndDie( "Please input --sname" );
	}
	if( !defined $opt{"size"} ){
		&printAndDie( "Please input --size" );
	}

	my $cmd = "$LVCREATE -L";
	$cmd .= $opt{"size"};
	$cmd .= " -s -n ";
	$cmd .= $opt{"sname"};
	$cmd .= " ".$opt{"dev"};
	my $r = system( "sudo ".$cmd );
	if( $r != 0 ){
		&printAndDie( "Snapshot create failed" );
	}
}

sub doMount()
{
	if( !defined $opt{"directory"} ){
		&printAndDie("Please input mount directory using --directory");
	}
	if( !defined $opt{"dev"} ){
		&printAndDie("Please input device to be mounted using --dev");
	}
	if( !defined $opt{"fstype"} ){
		&printAndDie("Please input filesystem type using --fstype");
	}
	mkpath( $opt{'directory'} );
        my $command = $MOUNT;
        if( $opt{"fstype"} eq "xfs" ){
            $command .= $NOUUID;
        }
	$command .= " \"$opt{dev}\" $opt{directory}";
	my $r = system( "sudo ".$command );	
	if( $r != 0 ){
		&printAndDie( "mount of $opt{dev} on $opt{directory} failed" );
	}
}

sub doUmount()
{
	if( !defined $opt{"directory"} ){
		&printAndDie("Please specify the directory using --directory");
	}
	my $command = "$UMOUNT $opt{directory}";
	my $r = system( "sudo ".$command );	
	if( $r != 0 ){
		&printAndDie( "umount of $opt{directory} failed" );
	}
	rmtree( $opt{directory}, 0, 0 );
}

sub doRemoveSnapshot()
{
	if( !defined $opt{"dev"} ){
		&printAndDie("Please specify the snapshot device using --dev");
	}
	my $command = $LVREMOVE." \"$opt{dev}\"";  
	my $r = system( "sudo ".$command );	
	if( $r != 0 ){
		&printAndDie( "remove of $opt{dev} failed" );
	}
}

&initSnapshotPlugin();
if( $action eq "get-vm-device-details" ){
	&doGetSnapshotdeviceDetails();
}elsif( $action eq "create-snapshot" ){
	&doCreateSnapshot();
}elsif( $action eq "mount" ){
	&doMount();
}elsif( $action eq "umount" ){
	&doUmount();
}elsif( $action eq "remove-snapshot" ){
	&doRemoveSnapshot();
}
exit( 0 );


