#!/usr/bin/perl
# 
# $Header: has/install/crsconfig/roothas.pl /st_has_11.2.0/19 2011/09/05 19:00:42 xyuan Exp $
#
# roothas.pl
# 
# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 
#
################ Documentation ################

# The SYNOPSIS section is printed out as usage when incorrect parameters
# are passed

=head1 NAME

  roothas.pl - root configuration script for SI-HAS

=head1 SYNOPSIS

  roothas.pl [-verbose] [-upgrade | -patch]
             [-paramfile <parameter-file>] [-deconfig] [-force]
             [-unlock [-hahome <path to Oracle Restart home>] [-nocrsstop]]

  Options:
   -verbose   Run this script in verbose mode
   -upgrade   Oracle HA is being upgraded from previous version
   -patch     Oracle HA is being upgraded to a patch version
   -paramfile Complete path of file specifying HA parameter values
   -deconfig  To deconfigure Oracle Restart
   -force     To deconfigure Oracle Restart when configuration
              is in a good condition
   -unlock    Unlock Oracle Restart home
   -hahome    Complete path of Oracle HA home. Use with unlock option
   -nocrsstop used with unlock option to reset permissions on an inactive Oracle HA home

  If neither -upgrade nor -patch is supplied, a new install is performed

  To see the full manpage for this program, execute:
    perldoc roothas.pl

=head1 DESCRIPTION

  This script performs the operations necessary to install the Oracle
  SingleInstance-HighAvailability stack.  This is run once during the
  configuration of SI-HAS home.

  This script does the following:
  1) Setup permissions of binaries and DSOs in SI-HAS home
  2) Setup OLR for storing SI-HAS configuration data

  Upon successful completion on each node, the Oracle SI-HA stack will
  be executing.

=cut

################ End Documentation ################

#    MODIFIED   (MM/DD/YY)
#    xyuan       08/30/11 - Fix bug 12896850
#    rdasari     08/30/11 - Start CSS for upgrade from pre-11.2
#    xyuan       08/25/11 - Support -nocrsstop option
#    rdasari     08/25/11 - use stopOracleRestart to stop has
#    rdasari     08/22/11 - bounce the has stack instead of CSS_start
#    xyuan       08/04/11 - Fix bug 12529687
#    sidshank    07/28/11 - Adding NSDIR path for bug 12773063
#    xyuan       07/26/11 - Fix bug 12770075
#    xyuan       07/11/11 - Fix bug 12701521
#    sidshank    06/01/11 - Adding noterm option, to be used internally on Windows
#    ksviswan    05/16/11 - Fix Bug 12554154.
#    rdasari     05/13/11 - fix bug 12414848
#    sidshank    05/10/11 - Backport sidshank_bug-12393931 from main
#    ksviswan    05/08/11 - Remove ORA_CRS_HOME env setting
#    agraves     04/11/11 - Add oraacfs.pm to this file.
#    ksviswan    03/08/11 - Backport ksviswan_febbugs2 from main
#    dpham       10/11/10 - Fix bug 10143662
#    diguma      08/26/10 - 10048027: remove sockets owned by root
#    dpham       06/30/10 - Add set_perms_ocr_vdisk() function (9850696)
#    ksviswan    06/22/10 - isoldver112 -> isVersion112
#    dpham       06/02/10 - add_ons() should be called after upgsihamodel()
#    dpham       06/01/10 - Fix bug 9648820
#    ksviswan    05/26/10 - Fix bug 9740970
#    dpham       05/19/10 - XbranchMerge dpham_bug9282344 from st_has_11.2.0.1.0
#    ksviswan    04/28/10 - Implment 11201 to 11202 SIHA upgrade logic (9647774)
#    samjo       01/12/10 - Bug 9129708. Use 'clscfg -local' in SIHA
#    dpham       02/01/10 - Call add_ons() to add ons (9129615)
#    dpham       01/13/10 - Fix upgrade issue (9268527)
#    dpham       12/20/09 - Change -delete to -deconfig
#    dpham       12/14/09 - XbranchMerge dpham_bug-9174159 from
#                           st_has_11.2.0.1.0
#    dpham       12/08/09 - ohasd resource should be owned by user in test env
#    dpham       12/07/09 - Increase wait time to 30 mins for ohasd
#    dpham       11/30/09 - Remove obsolete options
#    jleys       09/29/09 - Clean CSS local endpts on upgrade
#    ksviswan    07/30/09 - XbranchMerge ksviswan_bug-8693624 from
#                           st_has_11.2.0.1.0
#    ksviswan    07/21/09 - add -unlock
#    ksviswan    06/26/09 - Change default perl path
#    dpham       05/05/09 - Backup OLR (8484172)
#    ksviswan    05/02/09 - Patching support
#    dpham       04/21/09 - Add CRSDelete option
#    dpham       04/16/09 - Fix logic error when checking during upgrade
#    dpham       04/15/09 - Call 'crsctl pin css' if local_config doesn't exist
#    dpham       04/07/09 - Install acfsroot kernel
#    dpham       03/31/09 - ACFS is not supported in SIHA in 11gR2
#    dpham       03/25/09 - Call createLocalOnlyOCR
#    ksviswan    03/20/09 - Stop CSSD first before ocr migration
#    dpham       03/11/09 - Call CSS_start if ($RESTART_CSS || 
#			    ($cfg->params('ASM_UPGRADE') =~ m/true/i)) 
#    dpham       03/10/09 - Call isCRSAlreadyConfigured to check if SIHA is
#                           already configured
#                         - Add ORACLE_BASE
#    dpham       02/26/09 - Call start_acfs_registry instead of add_acfs_registry
#    ksviswan    02/20/09 - Fix bug 8255312 and create SCR/NS dirs for upgrade
#    dpham       02/11/09 - Call add_acfs_registry
#    ksviswan    02/05/09 - Fix bug 8208293
#    dpham       02/04/09 - Add isRAC_appropriate to check for rac_on/rac_off
#    dpham       01/20/09 - Remove configure_ACFS 
#    jleys       11/30/08 - Remove setting of HAS_USER (done in
#                           crsconfig_lib->new
#    jleys       11/26/08 - Remove setusage call
#    jleys       11/14/08 - Packagize perl scripts
#    ksviswan    11/19/08 - Support SIHA deconfig
#    diguma      11/18/08 - adding use oracss
#    dpham       10/09/08 - Trap error output from usm_root so that it gets written
#                           to the CRS log.
#    jleys       09/24/08 - Add callback to get params hash
#    dpham       09/05/08 - Change all SIHA resources to own by "NT AUTHORITY\SYSTEM".
#    jleys       07/11/08 - Put this program path into perl search path
#    jleys       04/15/08 - Use parameters hash
#    dpham       06/23/08 - change PERLLIB583 to use OH/perl/5.8.3/lib
#    averhuls    06/03/08 - Call usm_root to install the USM sub-system.
#    srisanka    05/12/08 - Bug 5748551: copy earlier local-only OCR to SIHA
#                           home
#    srisanka    05/12/08 - validate SIHA params
#    srisanka    05/08/08 - fix local_only check
#    samjo       05/02/08 - Use hostname in olr file name
#    srisanka    05/01/08 - ASM_UPGRADE check for true/false
#    srisanka    04/09/08 - handle pre-existing CSS/ASM
#    jleys       04/06/08 - Use configure_hasd instead of invoking
#                           hasdconfig.pl
#    srisanka    02/26/08 - remove output to STDOUT
#    srisanka    02/25/08 - modify args to hasdconfig.pl
#    srisanka    01/08/08 - separate generic and OSD code
#    samjo       12/07/07 - Making OCR and OLR names consistent
#    srisanka    11/20/07 - make HOST a global var
#    srisanka    08/21/07 - Creation
# 

use strict;
use English;

use File::Spec::Functions;
use File::Basename;

BEGIN {
  # Add the directory of this file to the search path
  push @INC, dirname($PROGRAM_NAME);
}

use Getopt::Long;
use Pod::Usage;
use crsconfig_lib;
use oracss;
use oraacfs;
require crsdelete;
use crspatch;

my $USAGE;
my $hahome = "";
my $upgrade;
our $g_delete = 0;
our $g_force = 0;
our $g_patch = 0;
our $g_unlock = 0;
our $g_noterm = 0;

my $SUCC_REBOOT = 0;

# the return code to give when the incorrect parameters are passed
my $usage_rc = 1;

#
# MAIN SCRIPT BODY
#

push @INC, dirname ($0);

our $DEBUG = FALSE;

our $PARAM_FILE_PATH = catfile (dirname ($0), "crsconfig_params");

#noterm option is used internally by the installer on Windows alone.
GetOptions('verbose!'    => \$DEBUG,
           'upgrade!',   => \$upgrade,
           'deconfig!',  => \$g_delete,
           'force'       => \$g_force,
           'patch!'      => \$g_patch,
           'unlock'      => \$g_unlock,
           'hahome=s'    => \$hahome,
           'nocrsstop!'  => \$NOCRSSTOP,
           'paramfile=s' => \$PARAM_FILE_PATH,
	   'noterm!'	 => \$g_noterm
          ) or pod2usage($usage_rc);

# Check validity of args
pod2usage(-msg => "Invalid extra options passed: @ARGV",
          -exitval => $usage_rc) if (@ARGV);


local $SIG{'__DIE__'} = sub { dietrap(@_); };

# pull all parameters defined in crsconfig_params and s_crsconfig_defs (if
# it exists) as variables in Perl
my $defsfile = catfile (dirname ($0), "s_crsconfig_defs");

### check if run as super user
my $SUPERUSER = check_SuperUser ();
if (!$SUPERUSER) {
  error("Insufficient privileges to execute this script");
  exit 1;
}


my $HOST = tolower_host ();
die "$!" if ($HOST eq "");

# Read the config files and set up the configuration data for
# subsequent processing
my $cfg =
  crsconfig_lib->new(IS_SIHA             => TRUE,
                     paramfile           => $PARAM_FILE_PATH,
                     osdfile             => $defsfile,
                     crscfg_trace        => TRUE,
                     CRSDelete           => $g_delete,
                     hahome              => $hahome,
                     NOCRSSTOP           => $NOCRSSTOP,
                     HOST                => $HOST,
                     UPGRADE             => $upgrade,
                     HAPatch             => $g_patch,
                     );
if($g_noterm)
{
# redirect stdout/stderr as appropriate
s_redirect_souterr ($cfg->crscfg_trace_file. "_OUT");
}

my $ORACLE_HOME  = $cfg->params('ORACLE_HOME');
my $ORACLE_BASE  = $cfg->params('ORACLE_BASE');
my $ORA_HA_HOME  = $ORACLE_HOME;
my $ORA_CRS_HOME = $ORACLE_HOME;

### Set this host name (lower case and no domain name)
# Set the following vars appropriately for SI-HA env
my $OCRCONFIGBIN = catfile ($ORACLE_HOME, "bin", "ocrconfig");

if    ($g_delete) { HADeconfigure(); }
elsif ($g_patch)  { HAPatch(); }
elsif ($g_unlock) { unlockHAHome(); }
else {

 if (isPrereqIgnored())
 {
  error("User ignored Prerequisites during installation");
  }
  
  # check if CRS is configured
  if (( ! $upgrade ) && isCRSAlreadyConfigured()) {
     exit 1;
  }

  # validate RAC_ON/RAC_OFF
  if (! is_dev_env () && ! isRAC_appropriate()) {
     exit 1;
  }

  # run directory creation, script instantiation, files creation/permissions
  # modules
  run_env_setup_modules (); 

  rscPreChecks();

  # on NT, set_perms_ocr_vdisk() function cannot be executed until
  # s_osd_setup() and first_node_tasks() functions are finhish
  set_perms_ocr_vdisk();

  $ENV{'ORACLE_HOME'} = $ORACLE_HOME;
  $ENV{'ORACLE_BASE'} = $ORACLE_BASE;


  my $local_config_exists = local_only_config_exists();

  if ($upgrade && isVersion112())
  {
     $local_config_exists = FALSE;
     performpost112upg()
  }

  validate_olrconfig ($cfg->OLR_LOCATION, $ORA_CRS_HOME)
    or die "Error in validate_olrconfig";

  if (! $local_config_exists) {
     createLocalOnlyOCR();
  }

  olr_initial_config() or die("OLR configuration failed\n");
 
  # check if older version SI CSS exists, by looking in OCRLOC
  my $status;
  my $RESTART_CSS = FALSE;
  if ($local_config_exists) {
    # If the stack is up, keep track of this and stop it now
    if (($RESTART_CSS = local_only_stack_active())) {
      if (!stop_local_only_stack()) {
        die("Unable to stop running CSS");
      }
      #Bug 8255312 - In single instance asm upgrade to siha
      #these directories gets removed when stopping the old css
      #by localconfig -delete
      my $SCRDIR = catfile ($SCRBASE, $HOST);
      my @NS_DIRS  = ("/var/tmp/.oracle","/tmp/.oracle");
      my $ORA_DBA_GROUP = $CFG->params('ORA_DBA_GROUP');
      if (! -d $SCRBASE) {
         trace("creating dir $SCRDIR");
         create_dir($SCRDIR);
         s_set_ownergroup ($CFG->SUPERUSER, $ORA_DBA_GROUP, $SCRDIR);
      }
      for my $NSDIR (@NS_DIRS) {
       if (! -d $NSDIR) { 
         trace("creating dir $NSDIR");
         create_dir($NSDIR);
         s_set_ownergroup ($CFG->SUPERUSER, $ORA_DBA_GROUP, $NSDIR);
         s_set_perms ("01777", $NSDIR);
       }    
      }
    }

    # Clean up local endpts used by CSSD, bug 891745
    CSS_Clean_Local_Endpts($cfg);

    if (!migrate_dbhome_to_SIHA()) {
      die("Migration of older version local_only to SIHA failed");
    }
  }
  # Confgiure local only OCR and pin the node 
  else {
    if (! configure_OCR()) {
       error("Creating local-only OCR ... failed");
       exit;
    } else {
       trace ("Creating local-only OCR ... succeeded");
    }
  }

  # Initialize the SCR settings.
  s_init_scr ();

  # register OHASD service/daemon with OS
  trace ("Registering ohasd");
  register_service ("ohasd") 
     or die "Can't register ohasd service";

  # Need to start OHASD as non-$SUPERUSER, i.e., as crsuser, which in this case
  # would be ORACLE_OWNER
  trace ("Starting ohasd");
  start_service ("ohasd", $cfg->HAS_USER) or
    die "ohasd failed to start";

  # Check if the service/daemon has started
  trace ("Checking ohasd");
  my $ohasd_running = check_service ("ohasd", 360);

  if ($ohasd_running) {
    trace ("ohasd started successfully");
  } else {
    error ("Timed out waiting for ohasd to start.");
    exit 1;
  }

  trace ("Creating HA resources and dependencies");

  my $owner = $cfg->params('ORACLE_OWNER');
  if ((! is_dev_env()) && ($cfg->platform_family eq "windows")) {
     $owner = '';
  }

  #Delete ohasd resources for SIHA for 11.2 upgrade
  if ($upgrade && isVersion112()) {
     $status = configure_hasd('has', $HOST, $owner, $owner,
                           $cfg->params('ORA_DBA_GROUP'), "delete");
  }

  $status = configure_hasd('has', $HOST, $owner, $owner,
                           $cfg->params('ORA_DBA_GROUP'));

  if ($status) {
    trace ("Successfully created HA resources for HAS daemon and ASM");
  } else {
    error ("Failed to create HA resources for HAS daemon and ASM");
    exit 1;
  }

  # if old SI CSS was running when roothas.pl was invoked *or* ASM needs to be
  # upgraded,
  # a) For post-11.2 upgrades, restart the stack so that ohasd starts all autostart
  #    resources (ASM, DB). CSS gets started as a dependency here.
  # b) For pre-11.2 upgrades, start SIHA CSS
  # CSS needs to be up for ASMCA to configure/start the new ASM.
  if ($RESTART_CSS || ($cfg->params('ASM_UPGRADE') =~ m/true/i)) {
    if ($upgrade && isVersion112()) #upgrade from post-11.2
    {
      trace("Upgrading from a post 11.2 version");
      # Enable ora.cssd
      my $crsctl = catfile($CFG->ORA_CRS_HOME, 'bin', 'crsctl');
      my @cmd = ($crsctl, 'modify', 'res', 'ora.cssd', '-attr',
                  "\"ENABLED=1\"", '-init');
      my $status = system_cmd(@cmd);
      if (0 != $status)
      {
        die("Failed to enable CSSD startup");
      }

      # Enable ora.diskmon
      @cmd = ($crsctl, 'modify', 'res', 'ora.diskmon', '-attr',
               "\"ENABLED=1\"", '-init');
      $status = system_cmd(@cmd);
      if (0 != $status)
      {
        die("Failed to enable DISKMON startup");
      }   

      trace("Restarting the stack");
      # restart the ohasd so that all its managed resources start with the new profiles
      stopOracleRestart() or
        die "Failed to stop the Oracle Restart stack";
      
      start_service ("ohasd", $cfg->HAS_USER) or
        die "ohasd failed to start";
    }
    else #upgrade from pre-11.2
    {
      trace("Upgrading from a pre 11.2 version, starting CSS");
      if (!CSS_start()) {
        error ("Failed to start CSS daemon");
        exit 1;
      }
    }
  }

  #invoke upgrademodel for SIHA
  if ($upgrade && isVersion112()) {
     upgsihamodel();
  }

  # add ons by default for SIHA
  if (($upgrade && (! isONSexist())) || (!$upgrade)) {
     add_ons();
  }

  # start evmd in SIHA mode to replace eonsd functionality
  if (!start_resource("ora.evmd", "-init")) {
      error ("Failed to start EVM daemon");
      exit 1;
  }

  # install acfsroot kernel
  my $ret = installUSMDriver();
  if (FAILED == $ret)
  {
    error("ACFS drivers installation failed");
    exit 1;
  }
  else
  {
    trace("ACFS drivers installation completed");
    if (WARNING == $ret)
    {
      trace("Set reboot flag to 1");
      $SUCC_REBOOT = 1;
    }
  }

  # backup OLR
  my $ocrconfig = catfile($cfg->params('ORACLE_HOME'), 'bin', 'ocrconfig');
  my $rc = system ("$ocrconfig -local -manualbackup");
  if ($rc == 0) {
     trace ("$ocrconfig -local -manualbackup ... passed");
  } else {
     trace ("$ocrconfig -local -manualbackup ... failed");
  }

  # This code is getting in 11203, so we only check old version < 11203 here.
  if ($upgrade && isVersionLT11203($cfg->oldconfig('ORA_CRS_VERSION')))
  {
    trace("Cleaning up ASM files ...");
    s_cleanASMFiles();
  }

  print color 'bold';
  print "Successfully configured Oracle Grid Infrastructure for a Standalone Server\n";
  if (1 == $SUCC_REBOOT)
  {
    print "A system reboot is recommended before using ACFS\n";
  }  
  print color 'reset';
  trace ("Successfully configured Oracle Grid Infrastructure for a Standalone Server");
}

if($g_noterm)
{
# restore stdout/stderr as appropriate
s_restore_souterr ();
}

0;

