2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-30 09:36:41 +00:00
xcat-core/xCAT-client/bin/zxcatCopyCloneList.pl
Chuck Brazie a4b658037f merge of xCAT_Client plus add one new file missed in xCAT
Change-Id: Iaa3b073333e75c64f7a0da35fb6dd1228e822059
2017-02-01 14:13:16 -05:00

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;