#!/usr/bin/perl

my $scsi_list;
my $scsi_disk_count = 0;

sub max {
	if ($_[0]<$_[1]) {return $_[1]} else {return $_[0]};
}

sub get_scsi_info($)
{
	my ($scsiid) = @_;
	my $FD;

	open(FD, "lsscsi $scsiid|");
	my @lines=<FD>;
	foreach $line (@lines) {
		if ($line =~ /.*\/dev\/([a-z]*)$/) {
			$scsi_list{$scsiid}->{'NAME'} = $1;
		}
	}
	close(FD);
	open(FD, "/proc/partitions");
	my @lines=<FD>;
	foreach $line (@lines) {
		if ($line =~ /\s*(\d+)\s*(\d+)\s*(\d+)\s*([a-z]+)$/) {
			# Full scsi_disk
			my $name = $4;
			my $size = $3;
			if ($name eq $scsi_list{$scsiid}->{'NAME'}) {
				$scsi_list{$scsiid}->{"SIZE"} = $size;
			}
		}
		if ($line =~ /\s*(\d+)\s*(\d+)\s*(\d+)\s*([a-z]+)(\d+)/) {
			my $part_name = $4;
			my $part_num = $5;
			my $size = $3;
			my $major = $1;
			my $minor = $2;
			if ($part_name eq $scsi_list{$scsiid}->{'NAME'}) {
				$scsi_list{$scsiid}->{"PART_SIZE_$part_num"} = $size;
				$scsi_list{$scsiid}->{"PART_MAJOR_$part_num"} = $major;
				$scsi_list{$scsiid}->{"PART_MINOR_$part_num"} = $minor;
				$scsi_list{$scsiid}->{'PART_COUNT'} = max($part_num, $scsi_list{$scsiid}->{'PART_COUNT'});
			}
		}
	}
	close(FD);
}

sub get_scsi_list()
{
	open(FD, "lszfcp -D|");
	my @lines=<FD>;
	foreach $line (@lines) {
		if ($line =~ /(0.0.[a-f0-9]+)\/0x([a-f0-9]+)\/0x([a-f0-9]+) (.*)/) {
			$scsi_list{$4}->{'BUSID'} = $1;
			$scsi_list{$4}->{'WWPN'} = $2;
			$scsi_list{$4}->{'LUN'} = $3;
			$scsi_list{$4}->{'SCSIID'} = $4;
			$scsi_count += 1;
			get_scsi_info($scsi_list{$4}->{'SCSIID'});
		}
	}
	close(LSDASD)
}

sub print_scsi_list()
{
	print "======================\n";
	print "Available SCSI disks:\n";
	print "======================\n";
	foreach $scsi_disk (sort keys %scsi_list) {
		my $scsiid, $online, $type;
		$scsiid = $scsi_list{$scsi_disk}->{'SCSIID'};
		$size = $scsi_list{$scsi_disk}->{'SIZE'};
		$name = $scsi_list{$scsi_disk}->{'NAME'};
		print "$scsiid name=$name size=$size Kb";
		if (($dumpconf->{'DUMP_TYPE'} eq "fcp") &&
			($dumpconf->{'DEVICE'} eq
			$scsi_list{$scsi_disk}->{'BUSID'}) &&
			($dumpconf->{'WWPN'} eq
			$scsi_list{$scsi_disk}->{'WWPN'}) &&
			($dumpconf->{'LUN'} eq
			$scsi_list{$scsi_disk}->{'LUN'})) {
			print " (dump on panic configured)";
		}
		print "\n";
		for ($i = 1; $i <= $scsi_list{$scsi_disk}->{'PART_COUNT'}; $i++) {
			$size = $scsi_list{$scsi_disk}->{"PART_SIZE_$i"};
			print " - part $i: $size Kb\n";
		}
	}
}

sub prepare_dump_scsi_disk($$)
{
	my ($scsiid, $part) = @_;

	$major = $scsi_list{$scsiid}->{"PART_MAJOR_$part"};
	$minor = $scsi_list{$scsiid}->{"PART_MINOR_$part"};
	$part_size = $scsi_list{$scsiid}->{"PART_SIZE_$part"};

	if ($mem_size > $part_size) {
		print "WARNING: System size ($mem_size Kb) is bigger than
		dump device ($part_size Kb)\n";
	}
	system("rm -f /tmp/scsi_disk_dump_$scsiid\_$part");
	system("mknod /tmp/scsi_disk_dump_$scsiid\_$part b $major $minor");
	system("mke2fs -j /tmp/scsi_disk_dump_$scsiid\_$part");
	system("mkdir /tmp/mnt");
	system("mount /tmp/scsi_disk_dump_$scsiid\_$part /tmp/mnt");
	system("zipl -n -D /tmp/scsi_disk_dump_$scsiid\_$part -t /tmp/mnt");
	system("umount /tmp/mnt");
	system("rm -f /tmp/scsi_disk_dump_$scsiid\_$part");
	system("rmdir /tmp/mnt");
}

sub prepare_dump_conf($)
{
	my ($scsiid) = @_;

	$busid = $scsi_list{$scsiid}->{'BUSID'};
	$wwpn = $scsi_list{$scsiid}->{'WWPN'};
	$lun = $scsi_list{$scsiid}->{'LUN'};

	open(FD, ">/tmp/dumpconf");
	print FD "# Automatically created by dump_install_scsi_disk.pl\n";
	print FD "ON_PANIC=dump\n";
	print FD "DUMP_TYPE=fcp\n";
	print FD "DEVICE=$busid\n";
	print FD "WWPN=$wwpn\n";
	print FD "LUN=$lun\n";
	print FD "BOOTPROG=0\n";
	print FD "BR_LBA=0\n";
	close(FD);
	system("install -b /tmp/dumpconf /etc/sysconfig/dumpconf");
	system("service dumpconf start > /dev/null");
}

sub get_mem_size()
{
	open(FD, "free -k|");
	my @lines=<FD>;
	$lines[1] =~ /Mem:\s*(\d+)/;
	$mem_size = $1;
}

sub get_dumpconf()
{
	open(FD, "/etc/sysconfig/dumpconf");

	my @lines=<FD>;
	foreach $line (@lines) {
		if ($line =~/^ON_PANIC=(.*)/) {
			$dumpconf->{'ON_PANIC'} = $1;
		}
		if ($line =~/^DUMP_TYPE=(.*)/) {
			$dumpconf->{'DUMP_TYPE'} = $1;
		}
		if ($line =~/^DEVICE=(.*)/) {
			$dumpconf->{'DEVICE'} = $1;
		}
		if ($line =~/^WWPN=(.*)/) {
			$dumpconf->{'WWPN'} = $1;
		}
		if ($line =~/^LUN=(.*)/) {
			$dumpconf->{'LUN'} = $1;
		}
		if ($line =~/^BOOTPROG=(.*)/) {
			$dumpconf->{'BOOTPROG'} = $1;
		}
		if ($line =~/^BR_LBA=(.*)/) {
			$dumpconf->{'BR_LBA'} = $1;
		}
	}
}

get_dumpconf();
get_mem_size();
get_scsi_list();
print_scsi_list();
print "SELECT DUMP SCSI DISK: ";
$dump_scsi_disk_scsiid = <STDIN>;
$dump_scsi_disk_scsiid =~ s/\n//g;
print "SELECT PARTITION: ";
$dump_scsi_disk_part = <STDIN>;
$dump_scsi_disk_part =~ s/\n//g;
print "WARNING: All information on the partition will be lost. Continue (y/n)?";
$answer = <STDIN>;
$answer =~ s/\n//g;
if ($answer eq "y") {
	prepare_dump_scsi_disk($dump_scsi_disk_scsiid, $dump_scsi_disk_part);
	prepare_dump_conf($dump_scsi_disk_scsiid);
	print "Dump Configuration complete\n";
} else {
	print "Operation canceled by user\n";
}
