#!/usr/bin/perl -w
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
#
#
# Licensed Materials - Property of IBM
#
# (C) COPYRIGHT International Business Machines Corp. 2005,2006
# All Rights Reserved
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
# IBM_PROLOG_END_TAG
#-------------------------------------------------------------------------------
# Items that may be overridden:
# - GPFS source location -- Does not require any knowledge of the system
# configurable parameters.
# - OS Kernel headers -- Does not necessarily preclude the automatically
# determined system configuration (but the implications of specifying them
# indicates a mismatch with automatically determinable items).
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# function: usage
#
# This function displays the usage for the auto-configuration program.
#-------------------------------------------------------------------------------
sub usage()
{
# Obtain invoked program name
$program = `basename $0`;
chomp($program);
# Display full syntax description
print "\nUsage: ${program} [--help] [sharkcloneroot=
]\n";
print "\nOptions:\n";
print "\n --help";
print "\n Display ${program} help and exit.\n";
print "\n sharkcloneroot=";
print "\n Specify the location of the source tree to configure.";
print "\n If not specified, check the SHARKCLONEROOT environment";
print "\n variable. If neither is specifiec, default to the GPL";
print "\n source directory /usr/lpp/mmfs/src.\n";
}
#-------------------------------------------------------------------------------
# function: get_OS
#
# This function determines the target Operating System.
#-------------------------------------------------------------------------------
sub get_OS()
{
local ($os);
local ($gpfs_os);
$os = `uname`;
if ($os =~ "AIX")
{
$gpfs_os = "GPFS_AIX";
}
elsif ($os =~ "Linux")
{
$gpfs_os = "GPFS_LINUX";
}
else
{
$gpfs_os = "UNSUPPORTED";
}
return($gpfs_os);
}
#-------------------------------------------------------------------------------
# function: get_Architecture
#
# This function determines the target hardware architecture.
#-------------------------------------------------------------------------------
sub get_Architecture()
{
local ($arch);
local ($gpfs_arch);
$arch = `uname -m`;
if ($arch =~ /^ia64$/)
{
$gpfs_arch = "GPFS_ARCH_IA64";
}
elsif ($arch =~ /^i\d86$/)
{
$gpfs_arch = "GPFS_ARCH_I386";
}
elsif ($arch =~ /^ppc$/)
{
$gpfs_arch = "GPFS_ARCH_POWER";
}
elsif ($arch =~ /^ppc64$/)
{
$gpfs_arch = "GPFS_ARCH_PPC64";
}
elsif ($arch =~ /^x86_64$/)
{
$gpfs_arch = "GPFS_ARCH_X86_64";
}
else
{
$gpfs_arch = "UNSUPPORTED";
}
return($gpfs_arch);
}
#-------------------------------------------------------------------------------
# function: get_DistValues
#
# This function determines the target Linux distribution values.
#-------------------------------------------------------------------------------
sub get_DistValues()
{
local ($redhat_release, $suse_release);
local ($dist, $dist_level, $kernel_string);
local($version, $release, $modification, $fix);
local($modification_actual, $fix_actual);
local($kernel, $kernel_actual);
$suse_release = "/etc/SuSE-release";
$redhat_release = "/etc/redhat-release";
# Obtain the running kernel version string
$kernel_string = `uname -r`;
chomp($kernel_string);
if ($kernel_string =~ /([2])\.([46]).(\d+)(.*)$/)
{
# Obtain the version, release, modification and fix level. Also obtain
# the "actual" modification and fix values (full, unmodified numeric only
# values) required for SLES 9 kernel headers.
$version = $1;
$release = $2;
$modification_actual = $modification = $3;
$fix = $4;
if ($modification > 99)
{
# Reduce modification to two digits to fit format string.
$modification = 99;
}
if ($fix =~ /^.(\d+)([.-])(\d+)([.-])(\d+)/)
{
# Fix level utilizes a multi-numeric format "." or "-" separated.
$fix = $1;
$fix_actual = $1 . $2 . $3 . $4 . $5;
}
elsif ($fix =~ /^([.-])(\d+)([.-])(\d+)/)
{
# Fix level utilizes a multi-numeric format "." or "-" separated.
$fix = $2;
$fix_actual = $1 . $2 . $3 . $4;
}
elsif ($fix =~ /^-(\d+)/)
{
# Fix level utilizes a single-numeric format.
$fix_actual = $fix = $1;
}
else
{
# No fix level in format; assign one to fit format string.
$fix = "00";
}
if ($fix > 99)
{
# Reduce fix to two digits to fit format string.
$fix = 99;
}
$kernel = sprintf("%01d%02d%02d%02d", $version, $release, $modification,
$fix);
$kernel_actual = sprintf("%d.%d.%d-%s", $version, $release,
$modification_actual, $fix_actual);
}
else
{
die("Cannot parse kernel version $kernel_string\n");
}
# DES: Fix this...if we do NOT do alternate configurations
# If the requested build is for the local machine, then we can determine the
# following information from local files. Otherwise, the user will have to
# provide that information.
if (-f $suse_release)
{
# SuSE Release
$dist = "SUSE_LINUX";
$dist_level = "80";
open(RELFILE, $suse_release) || die "Cannot open $suse_release";
LINE: while ($line = )
{
if ($line =~ /VERSION = (\d+)/ )
{
$dist_version = $1;
}
}
close(RELFILE);
# Determine the kernel headers directory
$lib_mod_bld_dir = "/lib/modules/$kernel_string/build/include";
$lib_mod_src_dir = "/lib/modules/$kernel_string/source/include";
$usr_src_dir = "/usr/src/linux-$kernel_actual/include";
if ($dist_version eq "8" && (-f "$lib_mod_bld_dir/linux/version.h"))
{
$kernel_hdr_dir = $lib_mod_bld_dir;
# Build directory not required for the 2.4 kernel
$kernel_bld_dir = "";
}
elsif ($dist_version eq "9" && (-f "$lib_mod_src_dir/linux/version.h"))
{
$kernel_hdr_dir = $lib_mod_src_dir;
# Build directory for the linux 2.6 kernel
$kernel_bld_dir = "/lib/modules/$kernel_string/build";
}
elsif ($dist_version eq "9" && (-f "$usr_src_dir/linux/version.h"))
{
$kernel_hdr_dir = $usr_src_dir;
# cannot guess the value in this case - let the user specify this
$kernel_bld_dir = "";
}
elsif ($dist_version eq "10" && (-f "$lib_mod_src_dir/linux/version.h"))
{
$kernel_hdr_dir = $lib_mod_src_dir;
# cannot guess the value in this case - let the user specify this
$kernel_bld_dir = "/lib/modules/$kernel_string/build";
}
elsif ($dist_version eq "10" && (-f "$usr_src_dir/linux/version.h"))
{
$kernel_hdr_dir = $usr_src_dir;
# cannot guess the value in this case - let the user specify this
$kernel_bld_dir = "";
}
else
{
die ("Cannot find a valid kernel include dir\n");
}
# ensure that the source directory has the right autoconf.h and version.h
# copied to it. Due to some distro bugs this may not always be the case.
if ($kernel_hdr_dir ne "" && $kernel_bld_dir ne "")
{
if (system("/usr/bin/diff -q $kernel_hdr_dir/linux/version.h $kernel_bld_dir/include/linux/version.h") != 0)
{
die("Kernel source tree does not have the correct version.h file.\n",
"See /usr/lpp/mmfs/src/README for further information\n");
}
if (system("/usr/bin/diff -q $kernel_hdr_dir/linux/autoconf.h $kernel_bld_dir/include/linux/autoconf.h") != 0)
{
die("Kernel source tree does not have the correct autoconf.h file.\n",
"See /usr/lpp/mmfs/src/README for further information\n");
}
}
}
elsif (-f $redhat_release)
{
# RedHat Release
open(RELFILE, $redhat_release) || die "Cannot open $redhat_release";
LINE: while ($line = )
{
if ($line =~ /Red Hat Linux release (\S+)/ )
{
$dist = "REDHAT_LINUX";
$dist_level = $1 eq "9" ? "90" : "80";
}
elsif ($line =~ /Red Hat Enterprise Linux/ )
{
$dist = "REDHAT_AS_LINUX";
$dist_level = "80";
}
}
close(RELFILE);
# Determine the kernel headers directory
$lib_mod_dir = "/lib/modules/$kernel_string/build/include";
$usr_src_dir = "/usr/src/linux-$kernel_string/include";
if (-f "$lib_mod_dir/linux/version.h")
{
$kernel_hdr_dir = $lib_mod_dir;
$kernel_bld_dir = "/lib/modules/$kernel_string/build";
}
elsif (-f "$usr_src_dir/linux/version.h")
{
$kernel_hdr_dir = $usr_src_dir;
$kernel_bld_dir = "/usr/src/linux-$kernel_string";
}
else
{
die ("Cannot find a valid kernel include dir\n");
}
}
else
{
$dist = "UNSUPPORTED";
$dist_level = "UNSUPPORTED";
$kernel = "UNSUPPORTED";
$kernel_hdr_dir = "UNSUPPORTED";
$kernel_bld_dir = "UNSUPPORTED";
}
return($dist, $dist_level, $kernel, $kernel_hdr_dir, $kernel_bld_dir);
}
#-------------------------------------------------------------------------------
# function: write_config
#
# This function writes the build configuration file, combining the template and
# the supplied configuration values.
#-------------------------------------------------------------------------------
sub write_config()
{
local ($os, $architecture, $dist, $dist_level, $kernel);
local ($kernel_hdr_dir, $template_dir);
$os = shift;
$architecture = shift;
$dist = shift;
$dist_level = shift;
$kernel = shift;
$kernel_hdr_dir = shift;
$kernel_bld_dir = shift;
$template_dir = shift;
# Open the template and build configuration files
open(TEMPLATE, "$template_dir/site.mcr.proto") ||
die "Unable to open template file $template_dir/site.mcr.proto\n";
open(CONFIG, ">$template_dir/site.mcr") ||
die "Unable to open configuration file $template_dir/site.mcr\n";
#-----------------------------
# Generate configuration file
#-----------------------------
foreach $line ()
{
# Substitute variable fields in configuration file
if ($line =~ m/^#define GPFS_LINUX$/)
{
$line =~ s/GPFS_LINUX$/$os/;
}
elsif ($line =~ m/^#define GPFS_ARCH_I386$/)
{
$line =~ s/GPFS_ARCH_I386$/$architecture/;
}
elsif (($line =~ m/^LINUX_DISTRIBUTION = REDHAT_LINUX$/) && ($os eq "GPFS_LINUX"))
{
$line =~ s/REDHAT_LINUX$/$dist/;
}
elsif (($line =~ m/^#define LINUX_DISTRIBUTION_LEVEL 90$/) && ($os eq "GPFS_LINUX"))
{
$line =~ s/90$/$dist_level/;
}
elsif (($line =~ m/^#define LINUX_KERNEL_VERSION 2042028$/) && ($os eq "GPFS_LINUX"))
{
$line =~ s/2042028$/$kernel/;
}
elsif (($line =~ m/^KERNEL_HEADER_DIR = \/lib\/modules\/`uname -r`\/build\/include$/) && ($os eq "GPFS_LINUX"))
{
$line =~ s/\/lib\/modules\/`uname -r`\/build\/include$/$kernel_hdr_dir/;
}
elsif (($line =~ m/^KERNEL_BUILD_DIR = \/lib\/modules\/`uname -r`\/build$/) && ($os eq "GPFS_LINUX"))
{
$line =~ s/\/lib\/modules\/`uname -r`\/build$/$kernel_bld_dir/;
}
print CONFIG "$line";
}
# Close the template and configuration files.
close(TEMPLATE);
close(CONFIG);
}
#-------------------------------------------------------------------------------
# function: configure
#
# This function obtains the full set of build configuration values, generating
# the configuration file from the template.
#-------------------------------------------------------------------------------
sub configure()
{
local ($architecture, $dist, $dist_level, $kernel, $kernel_hdr_dir, $os);
local ($sharkcloneroot, $template_dir);
# Obtain input parameters
$sharkcloneroot = shift;
#------------------------
# Verify source location
#------------------------
if ($sharkcloneroot =~ m/^[^\/]/)
{
# Source path not fully qualified
print STDERR "Source path not fully qualified: $sharkcloneroot\n";
return(-1);
}
#----------------------------------------------------------------
# Verify build type (GPL or development) from template location.
#----------------------------------------------------------------
if (-e "$sharkcloneroot/config/site.mcr.proto")
{
$template_dir = "$sharkcloneroot/config";
}
elsif (-e "$sharkcloneroot/shark-config/site.mcr.proto")
{
$template_dir = "$sharkcloneroot/shark-config";
}
else
{
print STDERR "Missing or incomplete source at: $sharkcloneroot\n";
return(-1);
}
#-------------------------
# Determine the target OS
#-------------------------
$os = get_OS();
if ($os eq "GPFS_LINUX")
{
#---------------------------------------
# Determine Linux specific settings
#---------------------------------------
# Determine the Architecture
$architecture = get_Architecture();
if ($architecture eq "UNSUPPORTED")
{
print STDERR "Unsupported Architecture: $architecture\n";
$rc = -1;
return($rc);
}
# Determine the Distribution, Kernel, Kern Header Directory
($dist, $dist_level, $kernel, $kernel_hdr_dir, $kernel_bld_dir) = get_DistValues();
if ($dist eq "UNSUPPORTED")
{
print STDERR "Unsupported Distribution: $dist\n";
$rc = -1;
return($rc);
}
if ($dist_level eq "UNSUPPORTED")
{
print STDERR "Unsupported Distribution Level: $dist_level\n";
$rc = -1;
return($rc);
}
}
elsif ($os eq "GPFS_AIX")
{
#---------------------------------
# Determine AIX specific settings
#
# NOTE: Only require architecture
#---------------------------------
$architecture = "GPFS_ARCH_POWER";
}
else
{
#------------------------------
# Unsupported Operating System
#------------------------------
print STDERR "Unsupported Operating System: $os\n";
$rc = -1;
exit($rc);
}
# If we have gotten to this point without an error occurrence, then process
# the site.mcr.proto and write a site.mcr file for the source code build.
if ($rc eq 0)
{
&write_config($os, $architecture, $dist, $dist_level, $kernel,
$kernel_hdr_dir, $kernel_bld_dir, $template_dir);
}
return(0);
}
#-------------------------------------------------------------------------------
# Main program
#-------------------------------------------------------------------------------
# Initialize utility variables
$rc = 0;
# Initialize core variables
$sharkcloneroot = undef;
# Process command-line arguments
foreach $arg (sort @ARGV)
{
if ($arg =~ m/^-/)
{
# Option specified
if ($arg eq "--help")
{
# Help requested ==> Display usage, exit success
usage();
exit(0);
}
else
{
# Unknown option ==> Display usage, exit failure
usage();
exit(1);
}
}
else
{
# Attribute/value pair specified
($attr, $value) = split("=", $arg);
if ($attr eq "sharkcloneroot")
{
# Source override specified
if (!$sharkcloneroot)
{
$sharkcloneroot = $value;
}
else
{
### prtMsg(36, "source");
usage();
exit(1);
}
}
else
{
# Invalid override
print STDERR "Invalid override: $attr\n";
usage();
exit(1);
}
}
}
#--------------------------------------
# Assign program defaults as necessary
#--------------------------------------
# Define the source directory. The default value may be overridden with the
# following priority utilized:
# 1) sharkcloneroot attribute setting supplied via command line
# 2) SHARKCLONEROOT environment variable
# 3) /usr/lpp/mmfs/bin default
if (!$sharkcloneroot)
{
# sharkcloneroot attribute unspecified
if (defined $ENV{SHARKCLONEROOT})
{
# SHARKCLONEROOT environment variable specified
$sharkcloneroot = $ENV{SHARKCLONEROOT};
}
else
{
# SHARKCLONEROOT environment variable unspecified
$sharkcloneroot = "/usr/lpp/mmfs/src";
}
}
#----------------------------------------------------------
# Process the configuration; Return success/failure status
#----------------------------------------------------------
$rc = &configure($sharkcloneroot);
exit($rc);
#-------------------------------------------------------------------------------