mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-30 09:36:41 +00:00
354 lines
12 KiB
Perl
354 lines
12 KiB
Perl
#!/usr/bin/perl
|
|
###############################################################################
|
|
# IBM (C) Copyright 2015, 2016 Eclipse Public License
|
|
# http://www.eclipse.org/org/documents/epl-v10.html
|
|
###############################################################################
|
|
# COMPONENT: zxcatCopyCloneList.pl
|
|
#
|
|
# This is a program to copy the "DOCLONE COPY" file from the 193 disk to
|
|
# /opt/xcat/doclone.txt
|
|
###############################################################################
|
|
|
|
use strict;
|
|
#use warnings;
|
|
use Capture::Tiny ':all';
|
|
use Getopt::Long;
|
|
|
|
my $file_location = '/var/opt/xcat/';
|
|
my $source_file = 'DOCLONE.COPY';
|
|
my $file_name = 'doclone.txt';
|
|
my $tempPattern = 'doclone.XXXXXXXX';
|
|
my $source_vdev = '193';
|
|
my $version = "1.0";
|
|
my $out;
|
|
my $err;
|
|
my $returnvalue;
|
|
my $displayHelp = 0; # Display help information
|
|
my $versionOpt = 0; # Show version information flag
|
|
|
|
my $usage_string = "This script copies the DOCLONE COPY from the MAINT 193
|
|
to the $file_location$file_name\n\n
|
|
Usage:\n
|
|
$0 [ -v ]
|
|
$0 [ -h | --help ]\n
|
|
The following options are supported:\n
|
|
-h | --help Display help information\n
|
|
-v Display the version of this script.\n";
|
|
|
|
# Copied this routine from sspmodload.pl
|
|
# This will get the Linux address of the vdev
|
|
sub get_disk($)
|
|
{
|
|
my ($id_user) = @_;
|
|
my $id = hex $id_user;
|
|
my $hex_id = sprintf '%x', $id;
|
|
my $completed = 1;
|
|
my $dev_path = sprintf '/sys/bus/ccw/drivers/dasd-eckd/0.0.%04x', $id;
|
|
if (!-d $dev_path) {
|
|
$dev_path = sprintf '/sys/bus/ccw/drivers/dasd-fba/0.0.%04x', $id;
|
|
}
|
|
if (!-d $dev_path) {
|
|
print "(Error) Unable to find a path to the $source_vdev in /sys/bus/ccw/drivers/\n";
|
|
}
|
|
-d $dev_path or return undef;
|
|
|
|
#offline the disk so that a new online will pick up the current file
|
|
my @sleepTimes = ( 1, 2, 3, 5, 8, 15, 22, 34, 60);
|
|
system("echo 0 > $dev_path/online");
|
|
|
|
my $dev_block = "$dev_path/block";
|
|
|
|
#wait if the disk directory is still there
|
|
if (-d $dev_block) {
|
|
$completed = 0;
|
|
foreach (@sleepTimes) {
|
|
system("echo 0 > $dev_path/online");
|
|
sleep $_;
|
|
if (!-d $dev_block) {
|
|
$completed = 1;
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$completed) {
|
|
print "(Error) The 193 disk failed to complete the offline!\n";
|
|
return undef;
|
|
}
|
|
|
|
system("echo 1 > $dev_path/online");
|
|
# Bring the device online if offline
|
|
if (!-d $dev_block) {
|
|
$completed = 0;
|
|
foreach (@sleepTimes) {
|
|
system("echo 1 > $dev_path/online");
|
|
sleep $_;
|
|
if (-d $dev_block) {
|
|
$completed = 1;
|
|
last;
|
|
}
|
|
}
|
|
if (!$completed) {
|
|
print "(Error) The 193 disk failed to come online!\n";
|
|
return undef;
|
|
}
|
|
}
|
|
if (opendir(my $dir, $dev_block)) {
|
|
my $dev;
|
|
while ($dev = readdir $dir) {
|
|
last if (!( $dev eq '.' || $dev eq '..' ) );
|
|
}
|
|
closedir $dir;
|
|
if (!defined $dev) {
|
|
print "(Error) undefined $dev\n";
|
|
}
|
|
defined $dev ? "/dev/$dev" : undef;
|
|
} else {
|
|
print "(Error) Unable to opendir $dev_block\n";
|
|
return undef;
|
|
}
|
|
}
|
|
|
|
# ***********************************************************
|
|
# Mainline. Parse any arguments, usually no arguments
|
|
$Getopt::Long::ignorecase = 0;
|
|
Getopt::Long::Configure( "bundling" );
|
|
|
|
GetOptions(
|
|
'h|help' => \$displayHelp,
|
|
'v' => \$versionOpt );
|
|
|
|
if ( $versionOpt ) {
|
|
print "Version: $version\n";
|
|
exit 0;
|
|
}
|
|
|
|
if ( $displayHelp ) {
|
|
print $usage_string;
|
|
exit 0;
|
|
}
|
|
|
|
my $tempFileName = '';
|
|
my $rc = 0;
|
|
my $oldFileExists = 0;
|
|
my $dev = get_disk($source_vdev);
|
|
if (defined($dev)) {
|
|
# make sure directory exists
|
|
if (!-d $file_location) {
|
|
$returnvalue = mkdir "$file_location", 0755;
|
|
if (!$returnvalue) {
|
|
print "(Error) mkdir $file_location failed with errno:$!";
|
|
$rc = 1;
|
|
goto MAIN_EXIT;
|
|
|
|
}
|
|
}
|
|
my $oldFiletime;
|
|
# Create a temp file name to use while validating
|
|
$tempFileName = `/bin/mktemp -p $file_location $tempPattern`;
|
|
chomp($tempFileName);
|
|
# if we are overwriting an existing file, save time stamp
|
|
if (-e "$file_location$file_name") {
|
|
# stat will return results in $returnvalue
|
|
( $out, $err, $returnvalue ) = eval { capture { `stat \'-c%y\' $file_location$file_name` } };
|
|
chomp($out);
|
|
chomp($err);
|
|
chomp($returnvalue);
|
|
if (length($err) > 0) {
|
|
print "(Error) Cannot stat the $file_location$file_name\n$err\n";
|
|
$rc = 1;
|
|
goto MAIN_EXIT;
|
|
}
|
|
$oldFileExists = 1;
|
|
$oldFiletime = $returnvalue;
|
|
}
|
|
|
|
( $out, $err, $returnvalue ) = eval { capture { `/sbin/cmsfscp -d $dev -a $source_file $tempFileName` } };
|
|
chomp($out);
|
|
chomp($err);
|
|
chomp($returnvalue);
|
|
if (length($err) > 0) {
|
|
# skip any blksize message for other blksize
|
|
if ($err =~ 'does not match device blksize') {
|
|
} else {
|
|
print "(Error) Cannot copy $source_file\n$err\n";
|
|
$rc = 1;
|
|
goto MAIN_EXIT;
|
|
}
|
|
}
|
|
|
|
if ($oldFileExists == 1) {
|
|
( $out, $err, $returnvalue ) = eval { capture { `stat \'-c%y\' $tempFileName` } };
|
|
chomp($out);
|
|
chomp($err);
|
|
chomp($returnvalue);
|
|
if (length($err) > 0) {
|
|
print "(Error) Cannot stat the $tempFileName\n$err\n";
|
|
$rc = 1;
|
|
goto MAIN_EXIT;
|
|
}
|
|
if ($oldFiletime eq $returnvalue) {
|
|
print "The $source_file copied to temporary file $tempFileName is the same time stamp as original.\n";
|
|
} else {
|
|
print "$source_file copied to temporary file $tempFileName successfully\n";
|
|
}
|
|
} else {
|
|
print "$source_file copied to temporary file $tempFileName successfully\n";
|
|
}
|
|
|
|
print "Validating $tempFileName contents for proper syntax...\n";
|
|
if (-f "$tempFileName") {
|
|
$out = `cat $tempFileName`;
|
|
} else {
|
|
print "(Error) Missing temporary file: $tempFileName\n";
|
|
$rc = 1;
|
|
goto MAIN_EXIT;
|
|
}
|
|
my @lines = split('\n',$out);
|
|
my %hash = ();
|
|
my %imagenames = ();
|
|
my $count = @lines;
|
|
if ($count < 1) {
|
|
print "(Error) $tempFileName does not have any data.\n";
|
|
( $out, $err, $returnvalue ) = eval { capture { `rm $tempFileName` } };
|
|
chomp($out);
|
|
chomp($err);
|
|
chomp($returnvalue);
|
|
if (length($err) > 0) {
|
|
print "(Error) Cannot erase temporary file $tempFileName $err\n";
|
|
}
|
|
$rc = 1;
|
|
goto MAIN_EXIT;
|
|
}
|
|
|
|
# loop for any lines found
|
|
for (my $i=0; $i < $count; $i++) {
|
|
# skip comment lines, * or /*
|
|
if ( $lines[$i] =~ '^\s*[\*]') {
|
|
next;
|
|
}
|
|
if ( $lines[$i] =~ '^\s*/[*]') {
|
|
next;
|
|
}
|
|
# is this a blank line? if so skip it
|
|
if ($lines[$i] =~/^\s*$/) {
|
|
next;
|
|
}
|
|
my $semicolons = $lines[$i] =~ tr/\;//;
|
|
if ($semicolons < 3) {
|
|
print "(Error) Semicolons need to end each key=value on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
|
|
%hash = ('IMAGE_NAME' => 0,'CLONE_FROM' => 0,'ECKD_POOL' => 0, 'FBA_POOL' => 0 );
|
|
# IMAGE_NAME=imgBoth; CLONE_FROM=testFBA; ECKD_POOL=POOLECKD; FBA_POOL=POOLFBA
|
|
my @parms = split( ';', $lines[$i]);
|
|
my $parmcount = @parms;
|
|
# get the key and value for this item, store in hash
|
|
for (my $j=0; $j < $parmcount; $j++) {
|
|
# if this token is all blanks skip it. Could be reading blanks at the end of the line
|
|
if ($parms[$j] =~ /^\s*$/) {
|
|
next;
|
|
}
|
|
my $parmlength = length($parms[$j]);
|
|
my @keyvalue = split('=', $parms[$j]);
|
|
my $key = $keyvalue[0];
|
|
$key =~ s/^\s+|\s+$//g; # get rid of leading and trailing blanks
|
|
|
|
if ( length( $key ) == 0 ) {
|
|
print "(Error) Missing keyword on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
next;
|
|
}
|
|
my $value = $keyvalue[1];
|
|
$value =~ s/^\s+|\s+$//g;
|
|
if ( length( $value ) == 0 ) {
|
|
print "(Error) Missing value for key $key on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
next
|
|
}
|
|
#uppercase both key and value;
|
|
my $UCkey = uc $key;
|
|
my $UCvalue = uc $value;
|
|
$hash{$UCkey} = $hash{$UCkey} + 1;
|
|
if ($UCkey eq "IMAGE_NAME") {
|
|
if (exists $imagenames{$UCvalue}) {
|
|
print "(Error) Duplicate IMAGE_NAME found on line ".($i+1)." with value: $value\n";
|
|
$rc = 1;
|
|
} else {
|
|
$imagenames{$UCvalue} = 1;
|
|
}
|
|
}
|
|
if ($UCkey ne "IMAGE_NAME" && $UCkey ne "CLONE_FROM" && $UCkey ne "ECKD_POOL" && $UCkey ne "FBA_POOL") {
|
|
print "(Error) Unknown keyword $key found on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
}
|
|
# Check to make sure they have at least an image name, from and one pool
|
|
if ($hash{IMAGE_NAME} == 1 && $hash{CLONE_FROM} == 1 && ($hash{ECKD_POOL} ==1 || $hash{FBA_POOL} ==1 )) {
|
|
next;
|
|
} else {
|
|
if ($hash{IMAGE_NAME} == 0) {
|
|
print "(Error) Missing IMAGE_NAME key=value on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
if ($hash{IMAGE_NAME} > 1) {
|
|
print "(Error) Multiple IMAGE_NAME keys found on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
if ($hash{CLONE_FROM} == 0) {
|
|
print "(Error) Missing CLONE_FROM key=value on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
if ($hash{CLONE_FROM} > 1) {
|
|
print "(Error) Multiple CLONE_FROM keys found on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
if ($hash{ECKD_POOL} == 0 && $hash{FBA_POOL} == 0) {
|
|
print "(Error) Missing ECKD_POOL or FBA_POOL on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
if ($hash{ECKD_POOL} > 1) {
|
|
print "(Error) Multiple ECKD_POOL keys found on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
if ($hash{FBA_POOL} > 1) {
|
|
print "(Error) Multiple FBA_POOL keys found on line ".($i+1)."\n";
|
|
$rc = 1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
print "(Error) Unable to access the $source_vdev disk.\n";
|
|
$rc = 1;
|
|
}
|
|
# Main exit for this routine. Handles any necessary clean up.
|
|
MAIN_EXIT:
|
|
if (length($tempFileName) > 0 ) {
|
|
# If a good rc, Copy the temp file to the correct file
|
|
if ($rc == 0) {
|
|
( $out, $err, $returnvalue ) = eval { capture { `/bin/cp -f $tempFileName $file_location$file_name` } };
|
|
print $out;
|
|
print $err;
|
|
print $returnvalue;
|
|
chomp($out);
|
|
chomp($err);
|
|
chomp($returnvalue);
|
|
if (length($err) > 0) {
|
|
print "(Error) Cannot copy the temporary file $tempFileName to $file_location$file_name \n $err\n";
|
|
$rc = 1;
|
|
} else {
|
|
print "Validation completed. Temporary file copied to $file_location$file_name.\nIt is ready to use\n";
|
|
}
|
|
}
|
|
( $out, $err, $returnvalue ) = eval { capture { `rm $tempFileName` } };
|
|
chomp($out);
|
|
chomp($err);
|
|
chomp($returnvalue);
|
|
if (length($err) > 0) {
|
|
print "(Error) Cannot erase temporary file $tempFileName\n$err\n";
|
|
$rc = 1;
|
|
}
|
|
}
|
|
exit $rc;
|