#! /usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2019 
# 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 
#*======================================================================
#*
#* Module Name:  hagsp
#*
#* Description:
#*      Script to start the Group Services Daemon as an SRC subsystem.
#*
#*      This file is formatted with tabstops of 4.
#*======================================================================
# sccsid = "@(#)04   1.45   src/rsct/pgs/cmds/cluster/cthagsp.perl, gsctrl, rsct_rady, rady2035a 11/12/15 16:44:49"

#ARGS: -s ${SUBSYS} -p ${CLUSTER_ID_OR_NAME} -d ${DFLT_LOG}

# put the include path

unshift(@INC, '/opt/rsct/bin');
unshift(@INC, '/opt/rsct/bin');

#
require "/opt/rsct/bin/hagsSetup.pkg";

use POSIX;              # for uname()

($dir,$progname) = $0 =~ /(.*\/)?(.*)/; # get basename of $0

&TSprint( TRACE_FYI, "$0 $#ARGV $[ input arguments: @ARGV\n" );

sub Usage {
    warn "Usage: $progname -s <subsystem_name> -p <domain_name> [-d <default_log_name>]\n";
    exit -1;
}


# Too many arguments?
if (8 <= $#ARGV) {
    &Usage;
}
# Avoid getopts, to remove dependencies on Perl libraries...
while (@ARGV) {
    $arg = shift @ARGV;
    if ("-s" eq $arg) {
        $SUBSYS = shift @ARGV;
    } elsif ("-p" eq $arg) {
        $CLUSTER_ID_OR_NAME = shift @ARGV;
    } elsif ("-d" eq $arg) {
        $DefLogName = shift @ARGV;
    } else {
        &Usage;
    }
}

#


($SYS_SYSNAME, $SYS_NODENAME, $SYS_RELEASE, $SYS_VERSION, $SYS_MACHINE) =
    POSIX::uname();
$RSCT_ROOT = "/opt/rsct";
$RSCT_BIN = "$RSCT_ROOT/bin";


$Perl = $ENV{'PGSD_PERL'};
if( "" eq $Perl) {
	$Perl="/usr/bin/perl";
}
$daemon = $ENV{'PGSD_DAEMON'};


&TSprint(TRACE_FYI, "subsys=$SUBSYS, ClusterName=$CLUSTER_ID_OR_NAME, ".
	  "DefLogName=$DefLogName, Perl=$Perl\n" );

if (!defined $ENV{'PGSD_TID_DIR'}) {
   $TidDir = "/var/ct/$CLUSTER_ID_OR_NAME/lck/$SUBSYS/$SUBSYS.tid";
   $ENV{'PGSD_TID_DIR'} = $TidDir;
}
if(! -d $TidDir) {
    eval `mkdir -p $TidDir`;
    if ($? != 0) {
        local($msg) = " cannot create directory $TidDir.";
        &TSprint( TRACE_FYI, "$msg\n");
        printf STDERR "$msg\n";
        &fcstart_error(__LINE__,$msg);
        exit 3;
    }
    eval `chmod 0750 $TidDir`;
}

&TSprint( TRACE_FYI, "PGSD_TID_DIR=$ENV{'PGSD_TID_DIR'}\n" );
&TSprint( TRACE_FYI, "PATH=$ENV{'PATH'}\n" );


#
# Get the node number
$NodeNumber = $ENV{'PGSD_NODE_NUMBER'};
&TSprint( TRACE_FYI, "PGSD_NODE_NUMBER=$NodeNumber\n" );

# Get HATS/HAGS info -----------------------------------
my @lines = ();
my %tsInfo = ();
my %gsInfo = ();

$HATSINFOCMD="/opt/rsct/bin/ct_hats_info";
if(open(INFOCMDFILE, "${HATSINFOCMD} |")) {	#refresh
   @lines = <INFOCMDFILE>;
   %tsInfo = &trans_list_to_hash(@lines);
   close INFOCMDFILE;
}

$HAGSINFOCMD="/opt/rsct/bin/ct_hags_info";
if(open(INFOCMDFILE, "${HAGSINFOCMD} -l |")) {	#norefresh
   @lines = <INFOCMDFILE>;
   %gsInfo = &trans_list_to_hash(@lines);
   close INFOCMDFILE;
}

my $GSRealm = $gsInfo{"REALM"};

# Find the domain envrionmane
my $GSDomEnv = $gsInfo{"ENVIRONMENT"};
if(!defined($GSDomEnv)) { $GSDomEnv = "cfgmgr"; }

if($GSDomEnv eq "gpfs") {
    $ENV{"PGS_ENVIRONMENT"} = "GPFS";
} elsif($GSDomEnv eq "scaffold") {
    $ENV{"PGS_ENVIRONMENT"} = "SCAFFOLD";
} elsif($GSDomEnv eq "cfgmgr" || $GSDomEnv eq "configrm") {
    $ENV{"PGS_ENVIRONMENT"} = "CFGMGR";
} else {
    # assume it is under "ConfigRM"
    $ENV{"PGS_ENVIRONMENT"} = "CFGMGR";
    $GSDomEnv = "cfgmgr";
}

#
# HAGS or RPD_RSCT level 
if( $GSDomEnv eq "cfgmgr" || $GSDomEnv eq "configrm" ) {
   # RPD active version will be obtained inside the daemon (including in CAA).
   # Therefore, here ct_clusterinfo -v is not needed
   #.local($rsct_ver) = `/opt/rsct/bin/ct_clusterinfo -v`;
   #.$rc = $?;
   #.if($rc == 0) {
   #.	chomp($rsct_ver);
   #. 	$ENV{"RPD_ACTIVE_RSCT_VERSION"} = $rsct_ver;
   #.	&TSprint(TRACE_FYI, "RPD_ACTIVE_RSCT_VERSION=$rsct_ver\n");
   #.} else {
   #.	local($msg) = " cannot obtain RPD_ACTIVE_VERSION. RC=$rc.";
   #.     &TSprint( TRACE_FYI, "$msg\n");
   #.}
   $ENV{"PGSD_MIXEDLEVEL"} = "1";
}
else {
   # need RELEASE_LEVEL
   # Note: The level must be to the proper daemon level here
   # to ensure the proper behaviour of daemons
   $ENV{'PGSD_CODELEVEL'} = &GSCurrentReleaseLevel();
   &TSprint( TRACE_FYI, "PGSD_CODELEVEL=$ENV{'PGSD_CODELEVEL'}\n" );
   $ENV{'PGSD_MIXEDLEVEL'} = "yes"; # Yup, we've got mixed levels.
}

if (!defined( $ENV{'PGSD_ALLOW_MIXING'} ) ) {
   if($GSDomEnv eq "gpfs" || $GSDomEnv eq "scaffold") {
        $ENV{'PGSD_ALLOW_MIXING'} = "yes";
   } else {
	# ConfigRM..Donot Allow mixed level
        $ENV{'PGSD_ALLOW_MIXING'} = "no";
   }
}

#
&TSprint( TRACE_FYI, "PGSD_MIXEDLEVEL=$ENV{'PGSD_MIXEDLEVEL'}\n" );
&TSprint( TRACE_FYI, "PGSD_ALLOW_MIXING=$ENV{'PGSD_ALLOW_MIXING'}\n" );

#
# To disable "domain control delegation(eg merge)" (for the testing)
#..$ENV{"PGSD_DONT_DELEGATE_DOMAIN_CONTROL"} = "1";

# Set the fixed priority value of the daemon.  If not set, it won't setpri
# Logsize control

$GSLogLength = $ENV{'PGSD_LOGSIZE'};
if( !defined($GSLogLength) ) { 
    $GSLogLength = $gsInfo{"LOGFILELEN"}; 
}
# GSLogLength is in no of lines
if( !defined($GSLogLength) || ($GSLogLength < 5000) ) {
    $GSLogLength = 5000;
}
# now convert "GSLogLength" to "GSLogSize" in byte if "CT_TR_FILE_SIZE" is not defined
$GSLogSize = $ENV{'CT_TR_FILE_SIZE'};     
if (!defined($ENV{'CT_TR_FILE_SIZE'})) {
	$GSLogSize = $GSLogLength * 200 * 4;  # make initial size as 4MB
} else {
	$GSLogSize = $ENV{'CT_TR_FILE_SIZE'};     # use whatever it is in the environment variable
}
$KbSzUnit = 256 * 1024;		# 256Kb
$GSLogSize = (($GSLogSize / $KbSzUnit)  + 1 ) * $KbSzUnit;

$ENV{'CT_TR_FILE_SIZE'} = $GSLogSize;


# Log Dir Size in KB
$GSLogDirSize=$ENV{'PGSD_REAP_SIZE'};
if(!defined($GSLogDirSize)) {
    $GSLogDirSize = $gsInfo{"LOGDIRSIZE"};
}
if( !defined($GSLogDirSize) || ($GSLogDirSize < 3000) ) {
        $GSLogDirSize = 5000; # in MB
}
$ENV{'PGSD_LOGDIRSIZE'} = $GSLogDirSize;

# Fixed priority?
my $TSpriority = $tsInfo{"FIXED_PRI"};
my $GSpriority = 0;
# Defect 146172: save the TS priority as default 
my $GSDefaultPriority = 0;
$GSDefaultPriority = `/opt/rsct/bin/cthats -V PRIO`;
$ENV{'GSDEFAULT_PRIORITY'} = $GSDefaultPriority;

if( defined($TSpriority) ) {

   # $TSpriority == 0 means "no fixed priority" (PGSD_FIXED_PRIORITY env
   # variable is not set)
   if($TSpriority != 0) {
       if($TSpriority < 0) {
           $TSpriority = `/opt/rsct/bin/cthats -V PRIO`;
           if($? != 0) {
               $TSpriority = -1;
           }
       }
       if($TSpriority >= 0) {
           my $osname=`/bin/uname`; 
           if( $osname =~ "AIX" ) {
       	       $GSpriority = $TSpriority + 1;
           } else {
               $GSpriority = $TSpriority - 1;
           }
       }
       $ENV{'PGSD_FIXED_PRIORITY'} = $GSpriority;
    }
}

&TSprint( TRACE_FYI, "PGSD_FIXED_PRIORITY=$GSpriority\n" );
&TSprint( TRACE_FYI, "CT_TR_FILE_SIZE=$ENV{'CT_TR_FILE_SIZE'}\n" );
&TSprint( TRACE_FYI, "PGSD_LOGDIRSIZE=$ENV{'PGSD_LOGDIRSIZE'}\n" );

#
#
# Handling for Markfile is now changed.
# In principal, every node will have a markfile and it will be updated
# whenever the state of daemon is changed. The daemon will also update
# the content of the markfile at the time of death.
# The daemon will read the file, compute the time how much the daemon
# has been down, and call hb_simulate_death with the time length
# if it was LNN or NS. Otherwise it call the function to stop SD.
# Note: if the markfile does not exist, the time length will be zero.
#
# A new environment will be passed so that the daemon knows whether
# SD is enabled(PSSP,CLUSTER) or disabled(under HAES)
#	PGSD_ALLOW_SIMULATE_DEATH
# If this environment is not defined, it is assumed as enabled.
#
# After the change of SD, PGSD_STEP_ON_HATS will be obsolete
# although it will still be passed for awhile.
#
#
$MarkFile = "$TidDir/${SUBSYS}.status.$CLUSTER_ID_OR_NAME";
$ENV{'PGSD_MARKFILE'} = $MarkFile;
&TSprint( TRACE_FYI, "PGSD_MARKFILE=$ENV{'PGSD_MARKFILE'}\n" );

#
#simulate death will be enabled
$ENV{'PGSD_ALLOW_SIMULATE_DEATH'} = "yes";
if ( ! -e $MarkFile ) {
	&TSprint( TRACE_FYI, "No Markfile $MarkFile found.\n" );
	$ENV{'PGSD_STEP_ON_HATS'} = "no";
} else {
	&TSprint( TRACE_FYI, "Markfile $MarkFile found.\n");
	$ENV{'PGSD_STEP_ON_HATS'} = "yes";
}

&TSprint( TRACE_FYI, "SimulateDeath is set to $ENV{'PGSD_ALLOW_SIMULATE_DEATH'}\n");
TSprint( TRACE_FYI, "(Obsolete) Step On Hats value = $ENV{'PGSD_STEP_ON_HATS'}\n");

#
#
$IncarnationNumber = &GetInstance( $TidDir, "${SUBSYS}d" );
$ENV{'PGSD_INCARNATION_NUMBER'} = $IncarnationNumber;
&TSprint( TRACE_FYI, "PGSD_INCARNATION_NUMBER=$ENV{'PGSD_INCARNATION_NUMBER'}\n" );

#
#
#
# set PGSD_LOGFILE
local($LogDir) = $ENV{'PGSD_LOGDIR'};
if(!defined($LogDir)) {
    $LogDir = "/var/ct/$CLUSTER_ID_OR_NAME/log/$SUBSYS";
    $ENV{'PGSD_LOGDIR'} = $LogDir;
}

$TRACEFILEPREFIX="trace";

if (!defined( $ENV{'PGSD_LOGFILE'} ) ) {
    $ENV{'PGSD_LOGFILE'} =
        "$LogDir/${TRACEFILEPREFIX}";
}
if(! -d $LogDir) {
    eval `mkdir -p $LogDir`;
    if ($? != 0) {
        local($msg) = " cannot create directory $LogDir.";
        &TSprint( TRACE_FYI, "$msg\n");
        printf STDERR "$msg\n";
        &fcstart_error(__LINE__,$msg);
        exit 3;
    }
    eval `chmod 0750 $LogDir`;
}

&TSprint( TRACE_FYI, "PGSD_LOGFILE=$ENV{'PGSD_LOGFILE'}, ",
                     "PGSD_LOGDIR=$ENV{'PGSD_LOGDIR'}\n" );

#
#Set run dir
if (!defined $ENV{'PGSD_RUN_DIR'}) {
    $RunDir = "/var/ct/$CLUSTER_ID_OR_NAME/run/$SUBSYS";
    $ENV{'PGSD_RUN_DIR'} = $RunDir;
}
# defect 169686: avoid the invocation of  /usr/bin/pwd  by sh/ksh
$ENV{'PWD'} = $ENV{'PGSD_RUN_DIR'};

if(! -d $RunDir) {
    eval `mkdir -p $RunDir`;
    if ($? != 0) {
        local($msg) = " cannot create directory $RunDir.";
        &TSprint( TRACE_FYI, "$msg\n");
        printf STDERR "$msg\n";
        &fcstart_error(__LINE__,$msg);
        exit 3;
    }
    eval `chmod 0750 $RunDir`;
}
&TSprint( TRACE_FYI, "PGSD_RUN_DIR=$ENV{'PGSD_RUN_DIR'}\n" );


# note that MoveToRunDir should probably be called BEFORE hagsreap,
# so that the core file is found and renamed before we calculate how
# much disk space we are using, otherwise it's not counted.
# so that the core file is found and renamed before we calculate how
# much disk space we are using, otherwise it's not counted.
# It will be counted the next time we restart, however.
# If we move it, we lose some parallelism, as we'd have to determine
# our incarnation number first.

&MoveToRunDir( $RunDir, $NodeNumber, $IncarnationNumber );

if ("" ne $DefLogName) {
    # We want to save the messages in the default log.
    # so, we rename it to the log name, and daemon appends to the log!
    local($newDefLogName) = "$DefLogName.${NodeNumber}_$IncarnationNumber";
    &TSprint(TRACE_FYI, "rename $DefLogName to $newDefLogName\n");
    rename($DefLogName, $newDefLogName) 
	|| warn "rename of $DefLogName to $newDefLogName failed!: $!\n";
    eval `chmod 0644 $newDefLogName`;
}


# hagsreap is a perl script which will trim the amount of space that
# hags logs and cores occupies.  We fire it off, and then just let it
# go, and check back on it later.

# hagsreap will remove hags logs and core files so that they consume
# no more than sizeLimit bytes.
$Command=$ENV{'PGSD_REAP_CMD'};
$sizeLimit = $GSLogDirSize * 1024;	# in Bytes

if( "" eq $DefLogName ) {
   $DefLogName="/var/ct/$CLUSTER_ID_OR_NAME/log/$SUBSYS/$SUBSYS.default";
   #$DefLogName="/var/ct/$CLUSTER_ID_OR_NAME/log/$SUBSYS/$TRACEFILEPREFIX.default";
}
$DefLogNameParameter = "-d $DefLogName";
#    
$cmd = "$Perl -S hagsreap  $DefLogNameParameter $SUBSYS $CLUSTER_ID_OR_NAME ".
       " $Command   $sizeLimit $NodeNumber " .
       "  $ENV{'PGSD_LOGDIR'}   $ENV{'PGSD_RUN_DIR'}";
#
select STDOUT; $|=1;	# disable buffering

&TSprint( TRACE_FYI, "cmd = $cmd.\n" );
if (0 == ($kidPid = fork)) {
    exec $cmd;
    die "Couldn't exec hagsreap: $!\n";
}


select STDOUT; $|=0;	# enable buffering

#
# Remove the client socket directory 
# (/var/ct/<cluster_name>/soc/ctgrpsvcs/clients.<cluster_name>) on CLUSTER
#
$client_dir = "/var/ct/$CLUSTER_ID_OR_NAME/soc/$SUBSYS/$SUBSYS.clients";

select STDOUT; $|=1;	# disable buffering

# 1. Fork another process that will remove the client socket files
if( 0 == ($client_rm_pid = fork) ) {
	# create the client dir
        eval `mkdir -p $client_dir`;
        eval `chmod 1777 $client_dir`;

        # child process. delete the socket files and directory
        eval `rm -rf $client_dir/*`;
        exit(0);
}

select STDOUT; $|=0;	# enable  buffering

# Set the envrionment variables for HA stacks
#

if (!defined( $ENV{'PGSD_PRM_SOCK'} ) ) {
    $ENV{'PGSD_PRM_SOCK'} = "$SUBSYS";
}
&TSprint( TRACE_FYI, "PGSD_PRM_SOCK=$ENV{'PGSD_PRM_SOCK'}\n");

if (!defined( $ENV{'PGSD_SUPP_SOCK'} ) ) {
    $ENV{'PGSD_SUPP_SOCK'} = "/var/ct/$CLUSTER_ID_OR_NAME/soc/${SUBSYS}/${SUBSYS}dsocket";
}

&TSprint( TRACE_FYI, "PGSD_SUPP_SOCK=$ENV{'PGSD_SUPP_SOCK'}\n");

# remove pgsd socket (so that client can get errno=ENO rather ECONNREFUSED)
# 145396 - (esp. Interix), socket file can be deleted cleanly via 'unlink()' (in hagsd)
#if( -e $ENV{'PGSD_SUPP_SOCK'} ) {
#   eval `rm -f $ENV{'PGSD_SUPP_SOCK'}`;
#}

# If in HAES/CLUSTER, worry about setting our hats socket pointer.
if (!defined( $ENV{'HB_SERVER_SOCKET'} ) ) {
   $ENV{'HB_SERVER_SOCKET'} = "/var/ct/$CLUSTER_ID_OR_NAME/soc/cthats/server_socket";
}
&TSprint( TRACE_FYI, "HB_SERVER_SOCKET=$ENV{HB_SERVER_SOCKET}\n");

# Allowing new function differs between HAES and PSSP, since HAES has
# no SDR to give us the lowest common denominator.

$ENV{'PGSD_NEW_FUNCTION'} = "unsafe";    
&TSprint( TRACE_FYI, "PGSD_NEW_FUNCTION=$ENV{'PGSD_NEW_FUNCTION'}\n" );

$| = 1; #flush and unbuffer stdout to get next messages asap.

# Allow hagsreap to finish, if it hasn't already.
if (0 != $kidPid) {
    local($startedWaiting) = time;
    waitpid( $kidPid, 0 );
    if ( 0 < ($waited = time - $startedWaiting) ) {
        &TSprint( TRACE_FYI, "We waited $waited seconds for hagsreap.\n" );
    }
}

#
# Wait the child process that is removing the client socket files
#
waitpid($client_rm_pid, 0);
#
#if ( ! -d $client_dir ) {
#    # create the client directory
#    mkdir($client_dir, 0777) || die "Can't make $client_dir: $!";
#}

# make sure the filemode (rwxrwxrwt) of the client socket directory
eval `chmod 1777 $client_dir`;
&TSprint( TRACE_FYI, "Client socket directory = $client_dir\n" );

# The environment PGSD_AUTH_BY_DAEMON to enable the new auth. method
$ENV{"PGSD_AUTH_BY_DAEMON"} = 1;

# Now that the GS daemon has an auxiliary thread, make sure that the
# system scope threads are used
$ENV{"AIXTHREAD_SCOPE"} = "S";

# Load the DMS if needed
load_dms_CAA_env();
wait_till_dms_loaded();

#
#  run the daemon
$cmd = "$daemon $SUBSYS @ARGV";

&TSprint( TRACE_FYI, "cmd = $cmd\n" );

exec $cmd;

die "exec $cmd failed!: $!\n";


#-----------------------------------------------------------------
#
# GS Current Release level
sub GSCurrentReleaseLevel
{
    $CURRENT_MIN_RELEASE_LEVEL = 10;
    return $CURRENT_MIN_RELEASE_LEVEL;
}



#
# print_message(list)
sub print_message
{
   local(@args) = @_;
   local($MSGCMD)="/opt/rsct/bin/hadspmsg hagsctrl ha_gs.cat";
   local($MSGOUT)=`$MSGCMD @args`;
   printf STDERR $MSGOUT;
}

#
# start_error(lineno, msg)
#
sub fcstart_error
{
   local($lineno) = $_[0];
   local($tmsg) = $_[1];
   if(!defined($lineno) || $lineno eq "") { $lineno = "0"; }
   local($cmd) = "/opt/rsct/bin/fclogerr -x ALPHA -y 100 ".
		 "-d \"$tmsg\" -p $lineno -s $0 -v 1.45 -l RSCT ".
		 "-r $SUBSYS -t ERRID_GS_STARTERR_ER -e FFDC_ERROR ".
                 "-i /opt/rsct/include/ha_gs.err.S.h ".
		 "-b \"hagsp: $tmsg\"";
   `$cmd`;
}

#
#
# Input:  list of a pair of <K> and <V>
#	eg: K1 V1
#	    K2 V2
# Output: hash table with pairs of {K}={V}
sub trans_list_to_hash
{
    my @lines = @_;
    my %outtbl = ();
    foreach $aline (@lines) {
	chomp($aline);
        my @kv=split(" ",$aline);
        $outtbl{$kv[0]} = join(" ",@kv[1..$#kv]);
    }
    return %outtbl;
}


#
# load_dms(): Check if the Dead Man Switch module is loaded. Load it if it is
# not loaded or the loaded DMS version is too old.
#
# Currently, DMS is only supported in AIX. Also note that the DMS should only
# get loaded in the CAA environment, since HATS is responsible for loading
# it in the non-CAA environment.
#

sub load_dms {
    my ($query_output);
    my ($load_dms_output);

    if ("$SYS_SYSNAME" eq "AIX") {

        &TSprint( TRACE_FYI,
            "---- Performing DMS kernel extension check ----\n");
        &TSprint( TRACE_FYI, "     (errors that follow are not critical)\n");
        $query_output = `$RSCT_BIN/haDMS/haDMS_query`;
        if ($? != 0) {

            &TSprint( TRACE_FYI,
                "DMS kernel extension not loaded or has an older version.\n");
            &TSprint( TRACE_FYI, "---- Initial check completed ----\n");

            &TSprint( TRACE_FYI,
                "Loading DMS kernel extension.\n");

            $load_dms_output =
                `$RSCT_BIN/haDMS/haDMS_load $RSCT_BIN/haDMS/haDMS_kex 2>&1`;
           
            if ($? != 0) {

                &TSprint( TRACE_ERROR, "$load_dms_output");
                &TSprint( TRACE_FYI, "Startup will continue in case DMS module gets loaded by other means.\n");

                # In principle, failing to load the DMS module is a fatal
                # error, since hagsd may be unable to load to missing
                # symbols. But the script will be allowed to continue, in
                # case the DMS module gets loaded by other means.

            }
        } else {
            &TSprint( TRACE_FYI, "$query_output");
            &TSprint( TRACE_FYI,
                  "No need to load DMS kernel extension: already loaded.\n");
            &TSprint( TRACE_FYI, "---- Initial check completed ----\n");
        }
    }
}


#
# load_dms_CAA_env(): load the DMS in the CAA environment (since HATS will
# not do it for us)
#

sub load_dms_CAA_env() {
    my ($realm);

    $realm = `$RSCT_BIN/ct_clusterinfo -r`;
    chomp($realm);
    if($realm eq "CAA") {
        load_dms();
    }
    else {
        &TSprint( TRACE_FYI, "Not CAA environment: not loading DMS\n");
    }
}

#
# wait_till_dms_loaded(): in an AIX environment, wait until the DMS kernel
# module is loaded. This is needed because, as long as the DMS is not
# loaded, the GS daemon cannot start. And worse, failing to load because of
# missing symbols causes perl to quit execution even if there are statements
# following 'exec'.
#

sub wait_till_dms_loaded {
    my ($query_output);
    my ($cnt);
    my ($rc);

    # if not AIX then just return
    if ("$SYS_SYSNAME" eq "AIX") {

        $query_output = `$RSCT_BIN/haDMS/haDMS_query`;
        if ($? != 0) {

            &TSprint( TRACE_FYI,
                "DMS kernel extension not loaded or has an older version.\n");

            for_cnt:
            for($cnt = 0; $cnt < 10; $cnt++) {

                sleep(10);

                $query_output = `$RSCT_BIN/haDMS/haDMS_query`;
                $rc = $?;

                if($rc == 0) { # success: quit waiting
                    last for_cnt;
                }

                &TSprint( TRACE_FYI,
                          "DMS kernel extension still not loaded.\n");

            }  # for

        } # if haDMS_query
        else {
            &TSprint( TRACE_FYI, "DMS kernel extension is loaded.\n");
        }

    } # AIX
}