# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # # NAME # crsinstall.pm # # DESCRIPTION # This module contains fresh install related functions for CRS/SIHA # # NOTES # # # MODIFIED (MM/DD/YY) # xyuan 10/31/16 - Backport xyuan_bug-24692493 from main # xyuan 10/18/16 - Backport xyuan_bug-24588125 from main # luoli 10/18/16 - Add and start RHP client on Member Cluster # xyuan 09/13/16 - Fix bug 24588125 # yilhu 08/03/16 - Fix bug 23727991 # samjo 07/27/16 - XbranchMerge samjo_bug-24323778 from main # xyuan 07/20/16 - Fix bug 24314345 # luoli 07/14/16 - Fix bug 24295250 # yilhu 07/14/16 - Fix bug 24292731 # xyuan 07/06/16 - Fix bug 23716240 # samjo 06/20/16 - Add NAS support for CW files # yilhu 06/14/16 - Fix bug 19585275 # xyuan 05/27/16 - Fix bug 23326932 # dpham 04/27/16 - add CRS_HOME parameter # luoli 04/25/16 - Modify forceCheck() # xyuan 04/21/16 - ODA Lite/SIP/IaaS # bbeelamk 04/13/16 - Fix bug 23095140 # ssprasad 03/24/16 - Invoke afdScanDevices, afdPostConfigActions # bbeelamk 03/16/16 - Fix bug 22685861 # muhe 03/16/16 - Fix bug 22936276 # bbeelamk 03/02/16 - Fix srvctl error # dpham 02/16/16 - move install_xag() to crsxag.pm module # muhe 12/23/15 - Fix bug 22454227 # luoli 12/15/15 - Fix bug 21921412 # muhe 12/07/15 - Fix bug 22321294 # madoming 11/25/15 - Fix bug 21239350 # sbezawad 11/17/15 - Bug 21919798: Add cluster properties to clscfg # xyuan 11/10/15 - Fix bug 22177601 # muhe 11/04/15 - Fix bug 21745923 # luoli 11/02/15 - Fix a minor message issue # muhe 10/29/15 - Fix bug 22116434 # muhe 10/21/15 - Fix bug 21886212 # bbeelamk 09/30/15 - Fix bug 20679385 # akhaladk 10/04/15 - Add ONS wallets # muhe 09/23/15 - Fix bug 21872800 # bbeelamk 09/15/15 - Changing srvctl method # muhe 09/09/15 - Fix issues in RTI 18493933 # luoli 08/16/15 - Fix bug 20861530 # luoli 07/28/15 - Add -y -z -h to CLSCFG command # bbeelamk 07/22/15 - Fix lrg 17723321 # bbeelamk 07/09/15 - Fix bug 21269876 # xyuan 06/26/15 - Fix bug 21318022 # jmarcias 06/19/15 - Add first node check to OPC key write # shullur 06/15/15 - For migrating CHM to new rootscript framework # luoli 06/15/15 - Change print_error to print_info when printing # success information # luoli 06/08/15 - Remove some useless code in postconfig_actions() # bbeelamk 06/02/15 - Fix bug 21177510 # jmarcias 05/20/15 - Fix bug 21101733 # muhe 05/14/15 - Fix bug 21090134 # jmarcias 05/08/15 - Fix bug 20975868 # muhe 05/07/15 - Fix bug 21039599 # bbeelamk 05/07/15 - Fix bug 20950908 # luoli 05/05/15 - Fix bug 21032304 # luoli 04/23/15 - Fix bug 20947747 # jmarcias 04/10/15 - Fix bug 20853464 # xyuan 04/09/15 - Clean-ups # xyuan 04/07/15 - Fix bug 20689570 # muhe 03/24/15 - Fix bug 20725601 # emarron 03/20/15 - Move perform_installKADriver to crska.pm # bbeelamk 03/19/15 - Fix bug 20657928 # muhe 03/19/15 - Fix bug 20740091 # jmarcias 03/17/15 - Fix bug 20569941 # madoming 03/16/15 - Changes for new framework # jmarcias 03/11/15 - Fix bug 20684249 # muhe 03/06/15 - Fix bug 20659982 # sbezawad 03/02/15 - Bug 20620752: Move setup_env after comp OCR init # emarron 02/19/15 - Move OKA checkpoint before supported check # xyuan 02/11/15 - Fix bug 20511101 # jmarcias 02/10/15 - Fix bug 20441873 # jmarcias 01/29/15 - Fix bug 20425262 # bbeelamk 01/08/15 - Fix lrg 14597150 # muhe 01/05/15 - Fix bug 20079862 # bbeelamk 12/23/14 - upgrade from std cluster # sbezawad 12/19/14 - Bug 20019354: Migrate OCR and OLR to new framework # xyuan 12/18/14 - Fix bug 20225412 # jmarcias 12/15/14 - Fix bug 14117160 # muhe 12/11/14 - Fix bug 20187693, 20193873 # xyuan 11/12/14 - Application Cluster # muhe 11/04/14 - Fix bug 18844632 # xyuan 11/04/14 - Add orasrvm.pm # ssprasad 11/04/14 - Fix 19911021: Perform AFD disk scan always # luoli 09/05/14 - Fix bug 19450633 # xyuan 08/06/14 - rsc modeling # luoli 08/05/14 - Fix bug 19258020 # lcarvall 07/21/14 - Bug 13800615 - Use mnemonic string instead numeric values # jmarcias 06/30/14 - Fix bug 19028836 # luoli 06/12/14 - Fix bug 18886094 # luoli 05/15/14 - Fix bug 18660020 # luoli 04/23/14 - Fix bug 18643537 # xyuan 04/17/14 - Fix bug 18606913 # ssprasad 04/03/14 - #18506269: afd call before firstNodeCheck # luoli 04/01/14 - Fix bug 18480923 # luoli 03/13/14 - Fix bug 17967087 # xyuan 03/06/14 - Fix lrg 11535037 # xyuan 03/02/14 - Fix bug 18279534 # xyuan 02/26/14 - Fix bug 18317281 # xyuan 02/21/14 - Fix bug 18278616 - Move sub getcrsrelver1 to # crsutils.pm # xyuan 02/12/14 - Fix bug 18128918 # luoli 02/07/14 - Fix bug 18161639 # hmbui 02/06/14 - Add install/upgrade/deconfig/downgrade - KA Driver. # luoli 02/06/14 - Fix bug 18013254 # madoming 02/04/14 - Bug 18176819 Check isACFSPath after create adr dirs # luoli 01/21/14 - Ocr backup and restore # ssprasad 01/14/14 - Move osd_setup() to crsutils.pm # shmubeen 01/09/14 - Run AFD install only if it's supported (#17442900) # xyuan 01/08/14 - Fix bug 18046306 # luoli 12/25/13 - Fix bug 18002693 # satg 12/05/13 - Fix Bug 17536735 # shiyer 11/25/13 - #17855029 # madoming 11/22/13 - Fix bug 17841639 # luoli 11/21/13 - write ckpts in ocr # luoli 11/12/13 - Fix bug 17762422 # madoming 10/28/13 - Add validation for current working directory # xyuan 10/28/13 - Fix bug 17649114 # agraves 10/23/13 - Remove temporary code that added the proxy now that # bug 17542011 is fixed and uploaded. # xyuan 10/11/13 - Fix bug 17469910 # xyuan 10/07/13 - Move two utils functions into crsutils.pm # agraves 09/25/13 - Readd the proxy enablement code temporarily until we # can resolve bug with ASMCA team. # xyuan 08/23/13 - Fix bug 17309302 # bamorale 08/20/13 - bug17340646 proxy is added only when needed # samjo 08/13/13 - Bug 17173973. Start CHA on add node # shmubeen 07/29/13 - Install AFD before installing resources # xyuan 07/16/13 - Fix bug 17076097 # xyuan 07/09/13 - Fix bug 16943141 # shmubeen 07/08/13 - bug# 17046459 and support for HA install/upgrade # xyuan 07/02/13 - Move sub backupOCR to crsutils.pm # xyuan 05/29/13 - Fixed the issue with checkpoint ROOTCRS_PARAM # xyuan 05/13/13 - Fix bug 16792798 # xyuan 05/09/13 - Fix bug 16765010 # madoming 03/25/13 - Bouncing OHASD after ACFS Install is successful # in SIHA # shiyer 03/01/13 - #16384817:xag # dpham 20/27/13 - Fix bug 16411596. # xyuan 02/27/13 - Changes as part of fix for bug 16274133 # xyuan 02/25/13 - Fix bug 16399449 - start the node listener on newly # added node only for Windows # rdasari 02/21/13 - delay create of credential domains for far asm # xyuan 02/05/13 - Fix bug 16246087 - Exit if CKPT ROOTCRS_STACK=SUCCESS # madoming 01/30/13 - Disable asm proxy when ACFS is not supported # xyuan 01/06/13 - XbranchMerge xyuan_bug-16026674 from st_has_12.1.0.1 # xyuan 12/25/12 - Fix bug 16014163 - disable listener changes for # Windows # xyuan 12/09/12 - Fix bug 15969912 # shiyer 11/28/12 - #15926544:XAG msg files # takiba 10/09/12 - bug13868167: recreate local.ocr on SIHA upgrade # ssprasad 11/13/12 - Disable OKA actions for 12.1 # xyuan 10/29/12 - Fix bug 14796373 & 14827104 # rdasari 10/29/12 - no need to pass role for first stack startup # rdasari 10/26/12 - createCredDomain for legacy asm # xyuan 10/24/12 - Fix bug 14801109 # dpham 10/19/12 - Fix bug 14782707. # rdasari 10/17/12 - fix import_asm_credentials # rdasari 10/09/12 - create credential domains in all cases # rdasari 10/09/12 - update gpnp stage profile for add node # epineda 09/27/12 - Bugfix 13539130 # xyuan 09/27/12 - Fix bug 14671774 - fix sub getHostVIP so that it can # recognize "prefixlen6" for IPV6 # shullur 09/25/12 - For moving getcrsrelver to crsutils.pm # sidshank 09/24/12 - fix bug 14620416. # shullur 09/17/12 - For adding check of version greater than 12 in case # of bdb # rdasari 09/13/12 - start asm proxy only on hub nodes # rdasari 09/13/12 - fix copy_asm_credentials for far asm # xyuan 09/11/12 - Fix bug 14592705 # xyuan 09/04/12 - Fix bug 14560280 # xyuan 08/31/12 - Fix bug 14535011 # ssprasad 08/23/12 - Fix bug 14528631 - add isOKASupported() check # in perform_installKADriver() # rdasari 08/22/12 - add configure_ASM_oda # dpham 08/21/12 - Add XAG component # madoming 08/17/12 - Fix bug 14320731. Start proxy asm on all nodes using # near ASM Configuration. # xyuan 08/08/12 - Fix bug 9584563 # rdasari 08/01/12 - change node role to rim if hub role fails # rdasari 07/25/12 - do not start ohasd before CSS exclusive start # shmubeen 07/18/12 - add AFD installation # ssprasad 07/18/12 - Report msg 400 instead of 2008 on reboot. # xyuan 07/12/12 - Fix bug 14302401 # xyuan 07/08/12 - Fixed an issue where the 'ROOTCRS_BOOTCFG' # checkpoint is missing on non-first nodes # sidshank 07/03/12 - fix bug 14196853. # rdasari 07/03/12 - import credentials before configure OCR for Far asm # shullur 06/15/12 - Change the bdbloc to default in the ora file. # rdasari 06/13/12 - create asm credential domains for legacy asm also # ssprasad 06/07/12 - KA driver calls in install path # rdasari 06/01/12 - make root auto option default for Windows # xyuan 05/24/12 - Fix bug 14111446 # sidshank 05/23/12 - fix bug 14106919 # xyuan 05/18/12 - Fix bug 14082413 - Only start CSS in X mode on the # first node # xyuan 05/16/12 - Fix bug 13795377 # rdasari 05/01/12 - start ohasd before importing asm credentials # akhaladk 04/30/12 - undo w/q for 13983808 # rdasari 04/26/12 - WA for bug 13983808 # sidshank 04/20/12 - fix for bug 13926993. # rtamezd 04/12/12 - Fix bug 13931049 # sidshank 04/09/12 - removing the call to redirect/restore stdout on # windows. # rdasari 04/04/12 - bounce stack after create asm credentials # rtamezd 03/26/12 - Move stop_ohasd_resources to crsutils.pm # rdasari 03/22/12 - bounce ohasd before initial config # rtamezd 03/09/12 - Fix bug 13822648 # xyuan 03/08/12 - Fix bug 13797791 # rtamezd 03/07/12 - Fix bug 13786398 # rtamezd 02/21/12 - Fix bug 13730374 # shullur 02/15/12 - XbranchMerge shullur_bug-12976590 from st_has_11.2.0 # rtamezd 02/09/12 - Fix bug 10083997 # sidshank 02/09/12 - Remove call to first_node_tasks() # xyuan 02/07/12 - Moved isVersionMatch to crsutils.pm # rtamezd 02/07/12 - Fix bug 13643262 # xyuan 02/07/12 - Fix bug 13691391 # xyuan 02/05/12 - Fix bug 13405738 # anjiwaji 01/19/12 - Fix chkpoint comparison. # anjiwaji 01/17/12 - Remove debug lines # rtamezd 01/17/12 - Moved add_localOlr_OlrConfig_OcrConfig to crsutils # xesquive 12/16/11 - Fix bug 13342583 # xyuan 12/13/11 - Added setHubSize # xyuan 12/13/11 - Fix bug 13480148 # xyuan 12/06/11 - Fix bug 12863550 # xesquive 12/05/11 - Create gridhome domain credentials in OCR # agraves 11/30/11 - Add functionality to check for reboot necessary in # ACFS driver install. # rdasari 11/28/11 - stop ohasd before stack startup on rim nodes # sidshank 11/21/11 - fix for bug 13416034 # xyuan 11/20/11 - Fix bug 13404894 # sidshank 11/15/11 - adding backupOCR subroutine # xyuan 11/14/11 - Fix bug 13340630 # xesquive 11/07/11 - Not start/stop ASM while adding a node # xyuan 11/05/11 - Fix bug 13329109 # xyuan 11/02/11 - Fix bug 13251040 # xyuan 10/31/11 - Fix bug 13328777 # xyuan 10/20/11 - XbranchMerge ksviswan_bug-12630162 from # st_has_11.2.0.3.0 # xyuan 10/05/11 - Fix bug 13066014 # rdasari 09/07/11 - create asm credentials after configNode # xyuan 09/07/11 - Fix bug 12908387 # xesquive 08/15/11 - forward merge from bug 12587677 # xyuan 08/10/11 - Far ASM support # xyuan 08/09/11 - Fix bug 12843894 # xyuan 08/03/11 - Fix bug 11851866 # xyuan 07/27/11 - XbranchMerge xyuan_bug-12701521 from # st_has_11.2.0.3.0 # xesquive 07/26/11 - Add functions set_bold and reset_bold instead of # print color # xyuan 07/19/11 - BC commands for 12c # jkellegh 07/15/11 - Root.sh should not call asmca for add node # nkorehis 07/03/11 - bug-12710656:fix get_has_version # lmortime 06/27/11 - Make EVMD start first # rdasari 06/16/11 - near ASM support # dpham 05/23/11 - Modulize upgrade function # dpham 03/28/11 - New for 12c # package crsinstall; use strict; use English; use Exporter; use File::Copy; use File::Path; use File::Find; use File::Basename; use File::Spec::Functions; use Sys::Hostname; use POSIX qw(tmpnam); use Carp; use Socket; use Config; use Cwd; use Env qw(NLS_LANG); use Env qw(CRS_ADR_DISABLE); # root script modules use crsutils; use crsgpnp; use oracss; use oraacfs; use crska; use oraafd; use s_crsutils; use crstfa; use oraClusterwareComp; use oraolr; use oraocr; use oraasm; use oraohasd; use orasrvm; use orachm; use oraios; use oraons; use crsxag; use Exporter; use vars qw(@ISA @EXPORT @EXPORT_OK); @ISA = qw(Exporter); my @exp_func = qw(create_starting_ckpt_entry precheck save_param_file precheck_siha check_CRSConfig start_siha_ohasd configureCvuRpm start_asm perform_initial_config create_CHMConfig perform_installAFDriver forceCheck create_asm_credentials ); push @EXPORT, @exp_func; our $GPNP_SETUP_TYPE = GPNP_SETUP_BAD; sub new { shift; crsutils->new(@_); # Put a null string in for VF discover string so that the change # will not be rejected (bug 7694835) $CFG->VF_DISCOVERY_STRING(''); if ((! $CFG->ASM_STORAGE_USED) && (! $CFG->SIHA) && ($CFG->defined_param('VOTING_DISKS'))) { $CFG->VF_DISCOVERY_STRING($CFG->params('VOTING_DISKS')); } # initialize $CFG->VF_DISCOVERY_STRING if ($CFG->ASM_STORAGE_USED) { # Put a null string in for VF discover string so that the change # will not be rejected (bug 7694835) $CFG->VF_DISCOVERY_STRING(''); } else { if (! $CFG->SIHA) { if ($CFG->defined_param('VOTING_DISKS')) { $CFG->VF_DISCOVERY_STRING($CFG->params('VOTING_DISKS')); } else { $CFG->VF_DISCOVERY_STRING(''); } } } rscPreChecks(); if ($CFG->init) { InitEnv(); } # fresh install elsif ($CFG->SIHA) { HAInstall(); } else { # Clusterware on NAS from user point of view # User selected NAS storage. GI will configure disk group on NAS. # # This option is indicated by 'CDATA_SIZE' parameter having a non zero # value. if ($CFG->defined_param('CDATA_SIZE') && ($CFG->params('CDATA_SIZE') != 0)) { configureStorageOnNAS(); } CRSInstall(); } } #------------------------------------------------------------------------------- # Function: This function does three things # 1. Initializes the permissions on the files in the home. # 2. Instantiates the sbs files. # 3. Copies the instantiated scripts to their destination. # Args: # Returns: #------------------------------------------------------------------------------- sub InitEnv { $CFG->compACFS(oraClusterwareComp::oraacfs->new("ACFS")); # instantiate scripts instantiate_scripts(); # Before File Permissions module is invoked, we need to add entries for # OCR and Voting Disk locations to crsconfig_fileperms (Bug 8236090). add_localOlr_OlrConfig_OcrConfig(); # Before Directories Creation module is invoked, we need to add entries # for RCALLDIR locations to crsconfig_dirs # Note: this is done only on platforms where RCALLDIR is defined. if ($CFG->defined_param('RCALLDIR')) { add_RCALLDIR_to_dirs (); } # add ITDI _to crsconfig_dirs add_ITDIR_to_dirs(); # create dirs & set permissions my @crsconfig_dirs = read_file(catfile($CFG->ORA_CRS_HOME, 'crs', 'utl', $CFG->HOST, 'crsconfig_dirs')); # Set CRS_ADR_DISABLE=true before crsconfig_dirs processing, which will stop # CLSB initializing ADR, and also prevents the check that leads to 'clsecho' # throwing a warning in case 'clsecho' is used during crsconfig_dirs # processing before the ADR home is created. # Doing this here as a workaround is part of fix for bug#18606913 trace("Set CRS_ADR_DISABLE to stop CLSB initializing ADR"); $ENV{'CRS_ADR_DISABLE'} = "true"; create_dirs(\@crsconfig_dirs); trace("Enable CLSB to initialize ADR"); undef $CRS_ADR_DISABLE; copy_wrapper_scripts(); my @crsconfig_fileperms = read_file(catfile($CFG->ORA_CRS_HOME, 'crs', 'utl', $CFG->HOST, 'crsconfig_fileperms')); set_file_perms(\@crsconfig_fileperms); # Set owner/group of ORA_CRS_HOME and its parent dir to root/dba if (! is_dev_env() && (! $CFG->SIHA) && ($CFG->platform_family eq "unix")) { s_setParentDirOwner ($CFG->SUPERUSER, $CFG->ORA_CRS_HOME); } # Assure correct permissions on ADR directories initialize_ADR_dirs(); } my @CRS_INSTALL_STAGES = ( {"name" => "SetupEnv", "checkpoint" => "null", "sub" => \&crs_install_init}, {"name" => "SetupTFA", "checkpoint" => "null", "sub" => \&setup_tfa}, {"name" => "ValidateEnv", "checkpoint" => "null", "sub" => \&crs_install_validate}, {"name" => "CheckFirstNode", "checkpoint" => "null", "sub" => \&check_firstnode}, {"name" => "GenSiteGUIDs", "checkpoint" => "null", "sub" => \&gen_site_GUIDs}, {"name" => "SaveParamFile", "checkpoint" => "ROOTCRS_PARAM", "sub" => \&save_param_file}, {"name" => "SetupOSD", "checkpoint" => "null", "sub" => \&osd_setup_actions}, {"name" => "CheckCRSConfig", "checkpoint" => "null", "sub" => \&check_crs_config}, {"name" => "SetupLocalGPNP", "checkpoint" => "ROOTCRS_GPNPSETUP", "sub" => \&setup_local_gpnp}, {"name" => "ConfigOLR", "checkpoint" => "ROOTCRS_OLR", "sub" => \&config_olr}, {"name" => "ConfigCHMOS", "checkpoint" => "null", "sub" => \&create_CHMConfig}, {"name" => "CreateOHASD", "checkpoint" => "ROOTCRS_OHASD", "sub" => \&create_ohasd}, {"name" => "ConfigOHASD", "checkpoint" => "ROOTCRS_INITRES", "sub" => \&config_ohasd}, {"name" => "InstallAFD", "checkpoint" => "ROOTCRS_AFDINST", "sub" => \&install_AFD}, {"name" => "InstallACFS", "checkpoint" => "ROOTCRS_ACFSINST", "sub" => \&install_ACFS}, {"name" => "InstallKA", "checkpoint" => "ROOTCRS_OKAINST", "sub" => \&install_KA}, {"name" => "InitConfig", "checkpoint" => "ROOTCRS_BOOTCFG", "sub" => \&init_config}, {"name" => "StartCluster", "checkpoint" => "null", "sub" => \&start_cluster}, {"name" => "ConfigNode", "checkpoint" => "ROOTCRS_NODECONFIG","sub" => \&config_node}, {"name" => "PostConfig", "checkpoint" => "null", "sub" => \&postconfig_actions} ); my @CONFIG_APPCLUSTER_STEPS = ( {"name" => "ConfigAppVIP", "checkpoint" => "ROOTCRS_APPVIP", "sub" => \&config_appvip} ); sub crs_install_init { # validate RAC_ON/RAC_OFF if (! is_dev_env () && ! isRAC_appropriate()) { exit 1; } $CFG->compACFS(oraClusterwareComp::oraacfs->new("ACFS")); # instantiate scripts instantiate_scripts(); # Before File Permissions module is invoked, we need to add entries for # OCR and Voting Disk locations to crsconfig_fileperms (Bug 8236090). add_localOlr_OlrConfig_OcrConfig(); # Initialize oraolr and oraocr modules $CFG->compOLR(oraClusterwareComp::oraolr->new("OLR")); $CFG->compOCR(oraClusterwareComp::oraocr->new("OCR")); # Initialize oraios module $CFG->compIOS(oraClusterwareComp::oraios->new("IOS")); # Initialize orachm module $CFG->compCHM(oraClusterwareComp::orachm->new("CHM")); # run directory creation, files creation/permissions modules setup_env(($CFG->isRerun) ? FALSE : TRUE); ($CFG->compACFS)->checkPath(); # Set the node attribute for fresh install based on the determination # if the current node is the first node to configure or not (isFirstNodeToConfig($CFG->HOST)) ? $CFG->nodeAttributeConfig(FIRST_NODE_TO_CONFIG): $CFG->nodeAttributeConfig(NONFIRST_NODE_TO_CONFIG); $CFG->compASM(oraClusterwareComp::oraasm->new("ASM")); $CFG->compSRVM(oraClusterwareComp::orasrvm->new("SRVM")); $CFG->compOHASD(oraClusterwareComp::oraohasd->new("OHASD")); } sub crs_install_validate { create_starting_ckpt_entry(); if (isAddNode($CFG->HOST)) { pullGlobalCkptFileNIndex(); } precheck(); } sub check_firstnode { # Use the global checkpoints file to store the status of the first node forceCheck(); # Skip the first node status check for adding node if (! isAddNode($CFG->HOST)) { checkFirstNodeStatus(); } } sub osd_setup_actions { osd_setup(); # on NT, set_perms_ocr_vdisk() function cannot be executed until # s_osd_setup() is finished set_perms_ocr_vdisk(); } sub check_crs_config { # Check if CRS is already configured my $crsConfigured = FALSE; my $orachm = $CFG->compCHM; my $gpnp_setup_type = GPNP_SETUP_BAD; check_CRSConfig($CFG->ORA_CRS_HOME, $CFG->HOST, $CFG->params('ORACLE_OWNER'), $CFG->params('ORA_DBA_GROUP'), $CFG->params('GPNPGCONFIGDIR'), $CFG->params('GPNPCONFIGDIR'), $crsConfigured, $gpnp_setup_type) || die(dieformat(315)); $GPNP_SETUP_TYPE = $gpnp_setup_type; # Verify bdb location. Initially its in CRS HOME. oclumon changes later if ($orachm->isSupported() && !is_dev_env() && !$orachm->isReposBDB()) { my $bdbloc = catfile($CFG->ORA_CRS_HOME, 'crf', 'db', $CFG->HOST); $orachm->chm_check_bdbloc($bdbloc, $CFG->params('NODE_NAME_LIST')); } # Verify ONS setup - must be called on all nodes to ensure the # wallet directory is created. verify_ons_dirs() || die(dieformat(49)); } sub config_olr { # Populates the cluster properties in the global variables getClusterProperties(); # Check existing configuration, Create and populate OLR and OCR keys perform_olr_config() || die(dieformat(316)); # Initialize the settings in the SCRBASE s_init_scr (); } sub create_CHMConfig { my $orachm = $CFG->compCHM; $orachm->create_CHM_config(); } sub setup_local_gpnp { $GPNP_SETUP_TYPE = GPNP_SETUP_NONE if (isFirstNodeToConfig($CFG->HOST)); # create GPnP wallet/profile initialize_local_gpnp($CFG->HOST, $GPNP_SETUP_TYPE); } sub create_ohasd { # Setup OHASD service/daemon perform_register_ohasd(); } sub config_ohasd { # Start OHASD service/daemon perform_start_ohasd() || die(dieformat(318)); # create OHASD resources create_ohasd_resources(); # set CSS priority for app cluster before cssd is up if (isAppCluster()) { CSS_set_config_parameter('priority', '3'); } } sub install_AFD { # install ASM Filter Driver perform_installAFDriver(USECHKPOINTS); } sub install_ACFS { # install USM driver my $oraacfs = $CFG->compACFS; $oraacfs->configureCurrentNode($oraacfs->CONFIGURE_ACFS); } sub install_KA { # install KA driver. Supported only in cluster. perform_installKADriver(); } sub init_config { # bounce the ohasd so that the ohasd resources/types take effect stopFullStack("force") || die(dieformat(349)); # Do initial cluster configuration. # It handles first and non-first nodes appropriately if (! perform_init_config()) { print_error(198); exit 1; } } sub config_node { if (isFirstNodeToConfig($CFG->HOST)) { setClusterType(); } if (isAddNode($CFG->HOST)) { add_clscfg(); } # SRVM needs to know dom-u or odaLite/odaSip # when configuring node VIP/apps if (isFirstNodeToConfig($CFG->HOST)) { my $ocrkey = ""; my $ocrval = ""; if (isOPCDomu()) { $ocrkey = 'OPC_CLUSTER'; $ocrval = 'dom-u'; } if (isODALite() || isODASIP() || isODAIaaS()) { $ocrkey = 'ODA_CONFIG'; $ocrval = lc($CFG->params('ODA_CONFIG')); } if (($ocrkey ne "") && ($ocrval ne "")) { trace("Writing SYSTEM.$ocrkey : $ocrval into OCR"); my $oraocr = $CFG->compOCR; my $success = $oraocr->writeOcrKeyPair($ocrkey, $ocrval); if (!$success) { die(dieformat(608, "SYSTEM.$ocrkey")); } } } # configure node perform_configNode(); } #------------------------------------------------------------------------------- # Function: This function does the following # Invoked only when Clusterware on NAS from user point of view # 1. NOOP on all nodes except first node # 2. Create file for OCRVF disk group. Sets owenerhip and perms # [OPT] 3. Create file for BACKUP disk group. Sets owenerhip and perms # # Args: # Returns: #------------------------------------------------------------------------------- sub configureStorageOnNAS { # User selected NAS storage. GI will configure disk group on NAS. # # This option is indicated by 'CDATA_SIZE' parameter having a non zero # value. # # Create the files on the first node. if (!isFirstNodeToConfig($CFG->HOST)) { return; } if ($CFG->defined_param('CDATA_SIZE') && ($CFG->params('CDATA_SIZE') != 0)) { my $msg1 = "Root or administrative user is not able to perform " . "superuser operations on this filesystem.\n" . "Check export options on NAS filer : "; my $ocrvfdgfile = $CFG->params('CDATA_DISKS'); open(CDATAFILE, ">$ocrvfdgfile") or die("Failed to create file for OCR disk group $ocrvfdgfile: $!"); # CDATA_SIZE is in MB where 1 MB = 1024000 bytes seek(CDATAFILE, ($CFG->params('CDATA_SIZE') * 1024000) - 1, 0) or die("Failed to seek to required offset for $ocrvfdgfile: $!"); print CDATAFILE "\0"; close(CDATAFILE); if (!s_set_ownergroup($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_ASM_GROUP'), $ocrvfdgfile)) { die("$msg1 $ocrvfdgfile\n"); } if (!s_set_perms("0660", $ocrvfdgfile)) { die("$msg1 $ocrvfdgfile\n"); } if ($CFG->defined_param('CDATA_BACKUP_SIZE') && ($CFG->params('CDATA_BACKUP_SIZE') != 0)) { my $backupdgfile = $CFG->params('CDATA_BACKUP_DISKS'); open (CDATABACKUPFILE, ">$backupdgfile") or die("Failed to create file for backup disk group " . "$backupdgfile: $!"); # CDATA_BACKUP_SIZE is in MB where 1 MB = 1024000 bytes seek(CDATABACKUPFILE, ($CFG->params('CDATA_BACKUP_SIZE') * 1024000) - 1, 0) or die("Failed to seek to required offset for $backupdgfile: $!"); print CDATABACKUPFILE "\0"; close(CDATABACKUPFILE); if (!s_set_ownergroup($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_ASM_GROUP'), $backupdgfile)) { die("$msg1 $backupdgfile\n"); } if (!s_set_perms("0660", $backupdgfile)) { die("$msg1 $backupdgfile\n"); } } } return; } sub CRSInstall { my $count = 0; if (isAppCluster()) { push(@CRS_INSTALL_STAGES, @CONFIG_APPCLUSTER_STEPS); } foreach my $stage (@CRS_INSTALL_STAGES) { my $name = $stage->{"name"}; my $checkpoint = $stage->{"checkpoint"}; my $func = $stage->{"sub"}; trace("Executing the [$name] step with checkpoint [$checkpoint] ..."); # We don't print the first step as clsecho might not be available # so to keep the steps consistent the first step is never printed. if (0 != $count) { print_info(594, $count, scalar(@CRS_INSTALL_STAGES) - 1, $name); } if ($name eq "ConfigCHMOS") { # Initialize orachm module $CFG->compCHM(oraClusterwareComp::orachm->new("CHM")); trace ("Successfully initialized CHM"); } &$func(); $count++; } if ($count == scalar(@CRS_INSTALL_STAGES)) { writeCkpt("ROOTCRS_STACK", CKPTSUC); set_bold(); print_info(325); if (1 == $CFG->SUCC_REBOOT) { print_info(400); } reset_bold(); } else { set_bold(); print_info(326); reset_bold(); exit(-1); } } sub postconfig_actions { # the OLR domain is created on all nodes createCredDomain('ASM', 'OLR') || die(dieformat(377)); if(isFirstNodeToStart()) { createCredDomain('GRIDHOME', 'OCR') || die(dieformat(380)); if (isFarASM()) { importASMCredentials('OCR'); } } # Create backup diskgroup on first node. The backup diskgroup # needs to be create after the crsd ora.asm resource gets created. my $success = $CFG->compASM->postConfigureCurrentNode(); if (!$success) { my $backupDg = $CFG->params('CDATA_BACKUP_DISK_GROUP'); die(dieformat(612, $backupDg)); } if ((lc($CFG->params('RHP_CONF')) eq "true") && isFirstNodeToStart()) { $CFG->compSRVM->add_rhpserver(); } my $isMemberCluster = (lc(trim($CFG->params('CLUSTER_CLASS'))) eq lc(CLUSTER_CLASS_MEMBER)); if ($isMemberCluster && isFirstNodeToStart()) { $CFG->compSRVM->start_rhpclient() if ($CFG->compSRVM->add_rhpclient()); } $CFG->compOLR->postConfigureCurrentNode(); $CFG->compOCR->postConfigureCurrentNode(); # Configure IOS only where it is supported if ($CFG->compIOS->isSupported()) { $CFG->compIOS->postConfigureCurrentNode(); } configureCvuRpm(); install_xag($CFG->ORA_CRS_HOME); createMgmtdbDir(); if (! isAddNode($CFG->HOST)) { gpnp_update_config(); } if ((! isAppCluster()) && ($CFG->platform_family eq "unix")) { createNetLsnrWithUsername(getLsnrUsername()); if (isAddNode($CFG->HOST)) { trace("Starting listeners on the node being added ...."); startListeners(TRUE); } else { startNetLsnr(TRUE, getLsnrUsername()); } } $CFG->compACFS->postConfigureCurrentNode(); afdPostConfigActions(); } my @HA_INSTALL_STAGES = ( {"name" => "SetupEnv", "checkpoint" => "null", "sub" => \&siha_install_init}, {"name" => "ValidateEnv", "checkpoint" => "null", "sub" => \&siha_install_validate}, {"name" => "GenSiteGUIDs","checkpoint" => "null", "sub" => \&gen_site_GUIDs}, {"name" => "SetupOSD", "checkpoint" => "null", "sub" => \&osd_setup_actions}, {"name" => "InstallAFD", "checkpoint" => "ROOTCRS_AFDINST", "sub" => \&install_AFD}, {"name" => "ConfigOLR", "checkpoint" => "ROOTCRS_OLR", "sub" => \&config_olrocr_siha}, {"name" => "CreateOHASD", "checkpoint" => "ROOTCRS_OHASD", "sub" => \&create_ohasd_siha}, {"name" => "ConfigOHASD", "checkpoint" => "ROOTCRS_INITRES", "sub" => \&config_ohasd_siha}, {"name" => "InstallACFS", "checkpoint" => "ROOTCRS_ACFSINST","sub" => \&install_ACFS}, {"name" => "PostConfig", "checkpoint" => "null", "sub" => \&siha_post_config} ); sub HAInstall { my $count = 0; foreach my $stage (@HA_INSTALL_STAGES) { my $name = $stage->{"name"}; my $checkpoint = $stage->{"checkpoint"}; my $func = $stage->{"sub"}; trace("Executing the [$name] step with checkpoint [$checkpoint] ..."); &$func(); $count++; } if ($count == scalar(@HA_INSTALL_STAGES)) { writeCkpt("ROOTCRS_STACK", CKPTSUC); set_bold(); print_info(327); if (1 == $CFG->SUCC_REBOOT) { print_info(400); } reset_bold(); } else { set_bold(); print_info(596); reset_bold(); exit(-1); } } sub siha_install_init { # validate RAC_ON/RAC_OFF if (! is_dev_env () && (! isRAC_appropriate())) { exit 1; } $CFG->compACFS(oraClusterwareComp::oraacfs->new("ACFS")); # instantiate scripts instantiate_scripts(); # Before File Permissions module is invoked, we need to add entries for # OCR and Voting Disk locations to crsconfig_fileperms (Bug 8236090). add_localOlr_OlrConfig_OcrConfig(); # Initialize oraolr and oraocr modules $CFG->compOLR(oraClusterwareComp::oraolr->new("OLR")); $CFG->compOCR(oraClusterwareComp::oraocr->new("OCR")); # run directory creation, files creation/permissions modules setup_env(($CFG->isRerun) ? FALSE : TRUE); precheck_siha(); ($CFG->compACFS)->checkPath(); $CFG->nodeAttributeConfig(SIHA_NODE_TO_CONFIG); $CFG->compOHASD(oraClusterwareComp::oraohasd->new("OHASD")); } sub siha_install_validate { my $ckpt = "ROOTCRS_STACK"; if (isCkptSuccess($ckpt)) { trace("Oracle Restart has been configured."); my $crshome = $CFG->ORA_CRS_HOME; print_info(352, $crshome); exit 0; } else { trace("Oracle Restart configuration has started"); writeCkpt($ckpt, CKPTSTART); } } sub config_olrocr_siha { my $oraocr = $CFG->compOCR; my $local_config_exists = $oraocr->localonlyOCR_exists(); # Populates the cluster properties in the global variables getClusterProperties(); create_upgrade_sihaOLR(); configure_local_OCR($local_config_exists); } sub create_upgrade_sihaOLR { # check the check point "ROOTCRS_OLR" if (isOLRConfiguredCkpt()) { return SUCCESS; } # Configure OLR for SIHA my $oraolr = $CFG->compOLR; $oraolr->configureCurrentNode(); } sub configure_local_OCR { my $local_config_exists = $_[0]; my $oraocr = $CFG->compOCR; my $ckptName = "ROOTCRS_LOCOCR"; if (isCkptexist($ckptName)) { if (isCkptSuccess($ckptName)) { trace("Local-only OCR has been created."); $CFG->wipCkptName("ROOTCRS_STACK"); return SUCCESS; } } writeCkpt($ckptName, CKPTSTART); $CFG->wipCkptName($ckptName); # check if older version SI CSS exists, by looking in OCRLOC $CFG->restart_css(FALSE); if ($local_config_exists) { # If the stack is up, keep track of this and stop it now if ($CFG->restart_css(local_only_stack_active())) { if (!stop_local_only_stack()) { die(dieformat(319)); } #Skipping the steps below on Windows. if ($CFG->platform_family ne "windows") { # Bug 8255312 - In single instance asm upgrade to siha # these directories gets removed when stopping the old css # by localconfig -delete my $SCRDIR = catfile ($CFG->params('SCRBASE'), $CFG->HOST); my @NS_DIRS = ("/var/tmp/.oracle", "/tmp/.oracle"); if (! -d $CFG->params('SCRBASE')) { trace("creating dir $SCRDIR"); create_dir($SCRDIR); s_set_ownergroup($CFG->SUPERUSER, $CFG->params('ORA_DBA_GROUP'), $SCRDIR); } for my $NSDIR (@NS_DIRS) { if (! -d $NSDIR) { trace("creating dir $NSDIR"); create_dir($NSDIR); s_set_ownergroup($CFG->SUPERUSER, $CFG->params('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()) { writeCkpt($ckptName, CKPTFAIL); die(dieformat(320)); } else { writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } } # Configure local only OCR and pin the node else { if (! $oraocr->configureCurrentNode($oraocr->CONFIGURE_OCR)) { print_error(156); trace ("Creating local-only OCR ... failed"); writeCkpt($ckptName, CKPTFAIL); exit; } else { trace ("Creating local-only OCR ... succeeded"); writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } } } sub create_ohasd_siha { # Initialize the SCR settings. s_init_scr (); my $ckptName = "ROOTCRS_OHASD"; # register OHASD service/daemon with OS trace("Registering ohasd"); if (isCkptexist($ckptName)) { if (isCkptSuccess($ckptName)) { trace("ohasd already registered"); $CFG->wipCkptName("ROOTCRS_STACK"); return SUCCESS; } } writeCkpt($ckptName, CKPTSTART); $CFG->wipCkptName($ckptName); my $oraohasd = $CFG->compOHASD; my $status; if (! $CFG->UPGRADE) { $status = $oraohasd->configureCurrentNode($oraohasd->REGISTER_OHASD_SERVICE); } else { $status = $oraohasd->upgradeCurrentNode($oraohasd->REGISTER_OHASD_SERVICE); } if (FAILED == $status) { writeCkpt($ckptName, CKPTFAIL); die(dieformat(317)); } writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } sub config_ohasd_siha { my $oraohasd = $CFG->compOHASD; my $status; # Need to start OHASD as non-$SUPERUSER, i.e., as crsuser, which in this case # would be ORACLE_OWNER trace ("Starting ohasd"); start_siha_ohasd(); # 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 { print_error(199); exit 1; } trace ("Creating HA resources and dependencies"); my $ckptName = "ROOTCRS_INITRES"; if (isCkptexist($ckptName)) { if (isCkptSuccess($ckptName)) { trace("OHASD Resources are already configured"); $CFG->wipCkptName("ROOTCRS_STACK"); return SUCCESS; } else { trace("Removing OHASD init resources and types"); $oraohasd->cleanupOHASDResources(); } } writeCkpt($ckptName, CKPTSTART); $CFG->wipCkptName($ckptName); if (! $CFG->UPGRADE) { $status = $oraohasd->configureCurrentNode($oraohasd->CREATE_OHASD_RESOURCES); } else { $status = $oraohasd->upgradeCurrentNode($oraohasd->CREATE_OHASD_RESOURCES); } if ($status) { trace ("Successfully created HA resources for HAS daemon and ASM"); writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } else { writeCkpt($ckptName, CKPTFAIL); print_error(200); exit 1; } # add ons by default for SIHA add_ons(); # start evmd in SIHA mode to replace eonsd functionality if (!start_resource("ora.evmd", "-init")) { print_error(202); exit 1; } } sub siha_post_config { # 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"); } afdPostConfigActions(); } sub create_starting_ckpt_entry { # hack to get crs ver from sqlplus. use getcrsrelver once bug 11077430 is fixed my $crsrelver = getcrsrelver1(); if (!isCkptexist("ROOTCRS_STACK")) { trace("Oracle clusterware configuration has started"); writeCkpt("ROOTCRS_STACK", CKPTSTART); writeCkptProperty("ROOTCRS_STACK", "VERSION", $crsrelver); $CFG->wipCkptName("ROOTCRS_STACK"); } else { if (!isCkptPropertyExists("ROOTCRS_STACK", "VERSION")) { trace("Removing older checkpoints"); remove_checkpoints(); trace("Oracle clusterware configuration has started"); writeCkpt("ROOTCRS_STACK", CKPTSTART); writeCkptProperty("ROOTCRS_STACK", "VERSION", $crsrelver); $CFG->wipCkptName("ROOTCRS_STACK"); } else { my $ckptcrsver = getCkptPropertyValue("ROOTCRS_STACK", "VERSION"); if (!isVersionMatch($ckptcrsver, $crsrelver)) { if (isCkptexist("ROOTCRS_OLDHOMEINFO")) # it is a upgrade case { # Fix bug 19450633 # ckptcrsver does not match crsrelver means it is upgrading from # an intermediate version which has been upgraded from a lower # version. e.g., 11.2.0.3 -> 12.1.0.2 -> 12.2 $CFG->skipUpgCheck(TRUE); } trace("Removing older checkpoints"); remove_checkpoints(); trace("Oracle clusterware configuration has started"); writeCkpt("ROOTCRS_STACK", CKPTSTART); writeCkptProperty("ROOTCRS_STACK", "VERSION", $crsrelver); $CFG->wipCkptName("ROOTCRS_STACK"); } else { trace("Setting isRerun to TRUE"); $CFG->isRerun(TRUE); # Fix bug 19450633 $CFG->skipUpgCheck(TRUE) if (!isCkptSuccess("ROOTCRS_STACK")); } my $ckptStatus = getCkptStatus("ROOTCRS_STACK"); if ($ckptStatus eq CKPTSTART) { # It likely that the node crashed. # Hence this ckpt is not labeled FAILED $CFG->isNodeCrashed(TRUE); } # Even if local CKPT is SUCCESS, user still can force local node to do # the last-node operations with '-force' option. my $condition1 = (($ckptStatus eq CKPTSUC) && (!$CFG->FORCE)); # During fresh install, if local CKPT is SUCCESS, no need to run root # script again on local node. my $condition2 = (($ckptStatus eq CKPTSUC) && (!$CFG->UPGRADE)); # Do not allow to run with -force -first if the root script was # already successful. my $condition3 = (($ckptStatus eq CKPTSUC) && ($CFG->FORCE) && ($CFG->FIRST)); if ($condition1 || $condition2 || $condition3) { trace("Oracle Clusterware has already been successfully ". "configured; hence exiting ..."); set_bold(); print_info(456); reset_bold(); exit(0); } $CFG->wipCkptName("ROOTCRS_STACK"); } } } sub precheck { if (isPrereqIgnored()) { print_info(363); } # validate filesystem if (! isFilesystemSupported()) { writeCkpt("ROOTCRS_STACK", CKPTFAIL); exit 1; } } sub isFilesystemSupported { if (is_dev_env()) { return SUCCESS; } my $success = SUCCESS; my $msg1 = "Root is not able to perform superuser operations " . "on this filesystem"; my $msg2 = "Check export options on NAS filer"; if (! s_set_ownergroup($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_DBA_GROUP'), $CFG->params('ORACLE_HOME'))) { print_error(26, $CFG->params('ORACLE_HOME')); trace ("Filesystem of " . $CFG->params('ORACLE_HOME') . " is not supported"); trace ($msg1); trace ($msg2); return FAILED; } else { #Reset the ownership of grid home directory to root. Bug 9974887 s_set_ownergroup($CFG->SUPERUSER, $CFG->params('ORA_DBA_GROUP'), $CFG->params('ORACLE_HOME')); } if (($CFG->platform_family eq 'unix') && ($CFG->params('CRS_STORAGE_OPTION') == 2)) { my @ocr_locs = split (/\s*,\s*/, $CFG->params('OCR_LOCATIONS')); foreach my $loc (@ocr_locs) { create_dir (dirname($loc)); $success = s_set_ownergroup($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_DBA_GROUP'), dirname($loc)); if (! $success) { print_error(26,$loc); trace ("Filesystem of $loc is not supported"); trace ($msg1); trace ($msg2); } } } return $success; } sub save_param_file { # save param file my $ckptstatus = getCkptStatus("ROOTCRS_STACK"); trace("Saving the configuration parameter file data"); trace("checkpoint status of ROOTCRS_STACK is $ckptstatus"); if (!isCkptexist("ROOTCRS_PARAM") && ($ckptstatus ne CKPTSUC)) { writeCkpt("ROOTCRS_PARAM", CKPTSTART); $CFG->wipCkptName("ROOTCRS_PARAM"); } if (isCkptexist("ROOTCRS_PARAM") && (! isCkptSuccess("ROOTCRS_PARAM"))) { trace("inside rootcrs_param"); writeCkptPropertyFile("ROOTCRS_PARAM", $CFG->paramfile); writeCkpt("ROOTCRS_PARAM", CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } } sub create_asm_credentials #------------------------------------------------------------------------------- # Function: Create and import ASM credentials. # This is called in a Local and Near ASM clusters. # Args : None. # Returns : None. #------------------------------------------------------------------------------- { my $ckptName = "ROOTCRS_CREATEASMCRED"; my $ckptStatus = CKPTSTART; if (isCkptexist($ckptName)) { $ckptStatus = getCkptStatus($ckptName); trace("'$ckptName' state is $ckptStatus"); if (CKPTSUC eq $ckptStatus) { trace("Flex ASM has already been enabled"); } } if (CKPTSUC ne $ckptStatus) { writeCkpt($ckptName, CKPTSTART); my $wipCkpt = $CFG->wipCkptName; $CFG->wipCkptName($ckptName); if (FAILED == createASMCredentials()) { die(dieformat(365)); } writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName($wipCkpt); } $ckptStatus = CKPTSTART; $ckptName = "ROOTCRS_IMPORTASMCRED"; if (isCkptexist($ckptName)) { $ckptStatus = getCkptStatus($ckptName); trace("'$ckptName' state is $ckptStatus"); if (CKPTSUC eq $ckptStatus) { trace("Already successfully imported ASM credentials"); } } if (CKPTSUC ne $ckptStatus) { writeCkpt($ckptName, CKPTSTART); my $wipCkpt = $CFG->wipCkptName; $CFG->wipCkptName($ckptName); import_asm_credentials(); writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName($wipCkpt); } push_seed_dir($CFG->params('NODE_NAME_LIST')); } sub start_cluster { trace(sprintf("Startup level is %d", $CFG->stackStartLevel)); # start the entire stack in shiphome if (START_STACK_ALL == $CFG->stackStartLevel) { trace("Attempt to start the whole CRS stack"); my $rc = startFullStack($CFG->params('ORACLE_HOME')); my $rc2 = check_resource_state($CFG->params('ORACLE_HOME')); if (WARNING == $rc) { # maximum number of hub nodes reached, try this as a rim node. my $role = NODE_ROLE_RIM; setNodeRole($role); stopFullStack("force") || die(dieformat(349)); $rc = startFullStack($CFG->params('ORACLE_HOME'), $role); $rc2 = check_resource_state($CFG->params('ORACLE_HOME')); } if ( SUCCESS != $rc || SUCCESS != $rc2 ) { die(dieformat(117)); } print_info(343); # set CSS values for app cluster after cssd is up if (isAppCluster() && isFirstNodeToConfig($CFG->HOST)) { CSS_set_config_parameter('misscount', '90'); CSS_set_config_parameter('disktimeout', '251'); } return; } # Start OHASD right here so that CRS stack can get started up # to the specified level startOhasdOnly() || die(dieformat(117)); # Start EVM if ($CFG->stackStartLevel >= START_STACK_EVMD) { if ( ! start_resource("ora.evmd", "-init") ) { print_error(117); die(dieformat(250)); } } # Start mdnsd if ($CFG->stackStartLevel >= START_STACK_MDNSD) { if (!start_resource("ora.mdnsd", "-init")) { print_error(117); # TODO: add an entry for mdnsd start failure to clsrscus.msg die(dieformat(117)); } } # Start gpnpd if ($CFG->stackStartLevel >= START_STACK_GPNPD) { if (!(start_resource("ora.gpnpd", "-init") && wait_for_gpnpd_start())) { print_error(117); die(dieformat(242)); } } # Start gipcd if ($CFG->stackStartLevel >= START_STACK_GIPCD) { if (!(start_resource("ora.gipcd", "-init"))) { print_error(117); # TODO: add an entry for gipcd start failure to clsrscus.msg die(dieformat(117)); } } # Start CSS in clustered mode if ($CFG->stackStartLevel >= START_STACK_CSSD) { if ( ! CSS_start_clustered() ) { print_error(117); die(dieformat(244)); } } # Start CTSS with reboot option to signal step sync # Note: Before migrating stack startup to 'crsctl start crs', # 'CTSS_REBOOT=TRUE' is a workaround to signal step sync. if ($CFG->stackStartLevel >= START_STACK_CTSSD) { if ( ! start_resource("ora.ctssd", "-init", "-env", "USR_ORA_ENV=CTSS_REBOOT=TRUE") ) { print_error(117); die(dieformat(245)); } } # Start CRF if ($CFG->stackStartLevel >= START_STACK_CHM) { my $orachm = $CFG->compCHM; if (! $orachm->isSupported() || ! start_resource("ora.crf", "-init")) { trace ("start_cluster: Failed to start CRF"); # We don't want IPD failure to stop rest of the stack # from coming up. So, no exit here! } } # startup the HAIP if it has been configured if ($CFG->stackStartLevel >= START_STACK_HAIP) { enable_HAIP(); } # Start ASM if needed. if ($CFG->stackStartLevel >= START_STACK_ASM) { if (($CFG->params('CRS_STORAGE_OPTION') == 1)) { my $rc; if (isLegacyASM()) { trace("Starting ASM on all nodes for Local ASM"); $rc = start_resource("ora.asm", "-init"); } elsif (isNearASM() && isFirstNodeToStart()) { trace("Starting ASM on the first node for Near ASM"); $rc = start_resource("ora.asm", "-init"); } else { trace("No need to start ASM on this node"); $rc = SUCCESS; } if ($rc != SUCCESS) { print_error(117); die(dieformat(247)); } } } # Start CRS if ($CFG->stackStartLevel >= START_STACK_CRSD) { if ( ! start_resource("ora.crsd", "-init") ) { print_error(117); die(dieformat(249)); } } if ($CFG->stackStartLevel >= START_STACK_CRSD) { if (!check_service("crs", 120)) { die(dieformat(251)); } } else { # Stack started up partially. trace("Started the Clusterware stack to level $CFG->stackStartLevel"); } print_info(343); } # This code installs USM, OKA and Asm Filter Drivers. sub perform_installDrivers { # # IMPORTANT NOTE: **** # perform_installUSMDriver() & perform_installKADriver() # have to be kept together so that the user only needs to # reboot 1 time at max. (if driver unload/load fails). # # install USM driver my $oraacfs = $CFG->compACFS; $oraacfs->configureCurrentNode($oraacfs->CONFIGURE_ACFS); # install KA driver. Supported only in cluster. perform_installKADriver(); } sub perform_installAFDriver { my $chkpoints = $_[0]; my $ret; # HA does not honour checkpoint functionality if ($chkpoints == USECHKPOINTS) { if (!isCkptexist("ROOTCRS_AFDINST")) { writeCkpt("ROOTCRS_AFDINST", CKPTSTART); $CFG->wipCkptName("ROOTCRS_AFDINST"); } } # NOTE: # As of 12.1.0.2.0, AFD and ASMLIB can not # co-exist. (linux specific requirement). # Between runs of this script, if ASMLIB # is installed, isAFDSupported() could change. # Hence, all AFD processing is done under # check points. # if(!isAFDSupported()) { trace("AFD is not supported."); if ($chkpoints == USECHKPOINTS) { writeCkpt("ROOTCRS_AFDINST", CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } return; } if (($chkpoints != USECHKPOINTS) || !isCkptSuccess("ROOTCRS_AFDINST")){ $CFG->wipCkptName("ROOTCRS_AFDINST"); # install AF driver $ret = installAFDriver(); if (FAILED == $ret) { # This is some failure that doesn't relate to driver load\unload. # For instance, this could be an issue generating symbols. print_error(2501); if ($chkpoints == USECHKPOINTS) { writeCkpt("ROOTCRS_AFDINST", CKPTFAIL); } exit 1; } elsif (REBOOT == $ret) { trace("ASM filter drivers unable to be installed."); set_bold(); print_error(400); reset_bold(); if ($chkpoints == USECHKPOINTS) { writeCkpt("ROOTCRS_AFDINST", CKPTFAIL); } else { writeCkpt("ROOTHAS_AFDINST", CKPTFAIL); } exit 1; } else { # It worked! trace("AF driver installation completed"); if ($chkpoints == USECHKPOINTS) { writeCkpt("ROOTCRS_AFDINST", CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } } } # On, root script re-execution, safe to scan for AFD devices again. # Run 'asmcmd afd_scan' to inform AF Driver about managed devices. afdScanDevices(); } ####--------------------------------------------------------- #### Function for checking if CRS is already configured # ARGS : 1 # ARG1 : CRS home # ARG2 : Host name # ARG3 : CRS user # ARG4 : isCrsConfigured? (OUT var) sub check_CRSConfig { my $crshome = $_[0]; my $hostname = $_[1]; my $crsuser = $_[2]; my $dbagroup = $_[3]; my $gpnpghome = $_[4]; my $gpnplhome = $_[5]; my $crsconfigok = FALSE; my $gpnp_setup_type = GPNP_SETUP_BAD; # init outers $_[6] = $crsconfigok; $_[7] = $gpnp_setup_type; trace ("Oracle CRS home = " . $crshome); if (!$hostname) { print_error(15); return FAILED; } trace ("Host name = " . $hostname); if (!$crsuser) { print_error(16); return FAILED; } trace ("CRS user = " . $crsuser); ## Define gpnp globals and validate gpnp directories. # Note: This step must be performed unconditionally, # because successfull script use gpnp globals. # if (! verify_gpnp_dirs( $crshome, $gpnpghome, $gpnplhome, $hostname, $crsuser, $dbagroup ) ) { trace("GPnP cluster-wide dir: $gpnpghome, local dir: $gpnplhome."); print_error(17); return FAILED; } if ($CFG->JOIN) { if (! pull_cluserwide_gpnp_setup($CFG->EXISTINGNODE)) { my $nodeName = $CFG->EXISTINGNODE; die(dieformat(440, $nodeName)); } } if (isAddNode($CFG->HOST)) { trace("Copy GPnP setup and ASM credentials from existing nodes ". "if they are not present"); my $succ = SUCCESS; if (! check_clusterwide_gpnp_profile()) { $succ = pull_cluserwide_gpnp_setup2($CFG->params('NODE_NAME_LIST')); } # For fresh install, the local gpnp profile is a copy of stage profile at this point, # so it doesn't make sense to update the gpnp stage profile right away. trace("Updating the clusterwide gpnp stage profile with the latest node profile"); gpnp_update_config(); # The stage profile must be updated before accessing it to get the ASM mode. my ($rc, $asm_mode) = gpnp_get_asm_mode(get_peer_profile_file(FALSE)); if (0 != $rc) { trace("Unable to get ASM mode from Oracle Clusterware GPnP profile"); } if (! $asm_mode) { trace("Undefined ASM mode: $asm_mode"); die(dieformat(509)); } else { $asm_mode = trim($asm_mode); if ($asm_mode eq '') { trace("ASM mode is not present in the profile, " . "hence defaults to legacy"); $asm_mode = ASM_MODE_LEGACY; } trace("ASM mode = $asm_mode"); $CFG->ASM_MODE($asm_mode); } if ($succ) { $succ = pull_asm_cred_file($CFG->params('NODE_NAME_LIST')); } if (SUCCESS != $succ) { die(dieformat(442)); } } ##Checking if CRS has already been configured trace ("Checking to see if Oracle CRS stack is already configured"); # call OSD API if (s_check_CRSConfig ($hostname, $crsuser)) { $crsconfigok = TRUE; } ## GPnP validate existing setup, if any # If a cluster-wide setup found, it will be promoted to local $gpnp_setup_type = check_gpnp_setup( $crshome, $gpnpghome, $gpnplhome, $hostname, $crsuser, $dbagroup ); if ($gpnp_setup_type != GPNP_SETUP_GOTCLUSTERWIDE && $gpnp_setup_type != GPNP_SETUP_CLUSTERWIDE) { trace ("GPNP configuration required"); $crsconfigok = FALSE; # gpnp setup is not ok or not finalized } $CFG->gpnp_setup_type($gpnp_setup_type); # reinit outers $_[6] = $crsconfigok; $_[7] = $gpnp_setup_type; return SUCCESS; } sub perform_olr_config { my $ckptName = "ROOTCRS_OLR"; if (isOLRConfiguredCkpt()) { return SUCCESS; } my $ocr = $CFG->compOCR; $ocr->configureCurrentNode($ocr->INITIALIZE_OCRLOC_FILE); my $olr = $CFG->compOLR; $olr->configureCurrentNode($olr->UPDATE_OLRLOC); initial_cluster_validation(); $olr->configureCurrentNode($olr->CONFIGURE_OLR); writeCkpt($ckptName, CKPTSUC); trace("OLR initialization - successful"); return SUCCESS; } sub add_clscfg { # add clscfg for new node if (!isCkptexist("ROOTCRS_ADDNODE")) { trace("Writing checkpoint for add node actions"); writeCkpt("ROOTCRS_ADDNODE", CKPTSTART); $CFG->wipCkptName("ROOTCRS_ADDNODE"); } if (!isCkptSuccess("ROOTCRS_ADDNODE")) { $CFG->wipCkptName("ROOTCRS_ADDNODE"); writeCkpt("ROOTCRS_ADDNODE", CKPTSTART); my $status = run_crs_cmd('clscfg', '-add'); if ($status == 0) { writeCkpt("ROOTCRS_ADDNODE", CKPTSUC); trace ("clscfg -add completed successfully"); } else { writeCkpt("ROOTCRS_ADDNODE", CKPTFAIL); trace("clscfg -add command failed with status $status"); print_error(180, "clscfg -add"); exit 1; } } } # checkpoint wrapper function for perform_initial_config sub perform_init_config { my $ckptStatus; my $ckptName = "ROOTCRS_BOOTCFG"; if (isCkptexist($ckptName)) { $ckptStatus = getCkptStatus($ckptName); trace("'$ckptName' state is $ckptStatus"); if ((($ckptStatus eq CKPTSTART) && $CFG->isNodeCrashed) || ($ckptStatus eq CKPTFAIL)) { clean_perform_initial_config(); $CFG->isNodeCrashed(FALSE); } elsif ($ckptStatus eq CKPTSUC) { trace("Node specific initial boot configuration already completed"); $CFG->wipCkptName("ROOTCRS_STACK"); return SUCCESS; } } return perform_initial_config(); } sub clean_perform_initial_config { trace("Clean perform_initial_config"); stopFullStack("force") || die(dieformat(349)); } =head2 perform_initial_config Checks for existing CSS configuration and creates initial configuration if no configuration found =head3 Parameters The parameter hash =head3 Returns TRUE - A CSS configuration was found or created FALSE - No CSS configuration was found and none created =cut sub perform_initial_config { my $rc; my $success = TRUE; my $ckptName = "ROOTCRS_BOOTCFG"; my $excl_ret; my $css_up_normal = FALSE; my $localNode = $CFG->HOST; ## Enter exclusive mode to setup the environment trace ("Checking if initial configuration has been performed"); writeCkpt($ckptName, CKPTSTART); $CFG->wipCkptName($ckptName); startOhasdOnly() || die(dieformat(117)); my $oraasm = $CFG->compASM; my $ocr = $CFG->compOCR; # Setup ASM|IOS|APX audit logs redirection $oraasm->configureCurrentNode($oraasm->REDIRECT_ASMAPXIOS_AUDIT_LOGS); if (! isFirstNodeToConfig($localNode)) { trace("Node $localNode is not the first node to configure, ". "hence do not start CSS in exclusive mode"); # Import credentials for ASM on non-first nodes, including rim nodes # A rim node can never be a first node, hence CSS is never started in X mode # on a rim node. # The ASM mode doesn't get updated in the local gpnp profile # until the remote ASM is enabled. $oraasm->configureCurrentNode(); stopFullStack("force") || die(dieformat(349)); writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); return $success; } # the credentials need to be imported before starting CSS in X mode $oraasm->configureCurrentNode($oraasm->IMPORT_ASM_CREDS_FARASM); if (checkServiceDown("css")) { $excl_ret = CSS_start_exclusive(); } elsif (!CSS_is_configured()) { $excl_ret = CSS_EXCL_SUCCESS; } else {$css_up_normal = TRUE;} if ((!$css_up_normal) && $excl_ret != CSS_EXCL_SUCCESS) { if ($excl_ret == CSS_EXCL_FAIL_CLUSTER_ACTIVE) { # The exclusive mode startup failure should not happen due to # another node being already up print_error(443); $success = FALSE; } else { trace("The exlusive mode cluster start failed, see Clusterware alert log", "for more information"); die(dieformat(119)); } stopFullStack("force"); } # in business # Need to find out whether we should be doing something as # exclusive node or not. Use CSS voting files as a way of # checking cluster initialization status elsif (CSS_is_configured()) { trace("Existing configuration setup found"); if (! startExclCRS()) { writeCkpt($ckptName, CKPTFAIL); die(dieformat(260)); } } else { trace("This is the first node to start"); trace("Performing initial configuration for cluster"); if (!start_resource("ora.ctssd", "-init")) { $success = FALSE; writeCkpt($ckptName, CKPTFAIL); die(dieformat(257)); } # If ASM diskgroup is defined, need to configure and start ASM # ASM is started as part of the config else { $success = $oraasm->configureCurrentNode($oraasm->CONFIGURE_ASM); if (!$success) { writeCkpt($ckptName, CKPTFAIL); die(dieformat(258)); } } # ocrconfig - Create OCR keys if (! ($ocr->configureCurrentNode($ocr->CONFIGURE_OCR))) { $success = FALSE; writeCkpt($ckptName, CKPTFAIL); die(dieformat(259)); } elsif (!startExclCRS()) { $success = FALSE; writeCkpt($ckptName, CKPTFAIL); die(dieformat(260)); } else { trace ("Creating voting files"); if (!add_voting_disks()) { writeCkpt($ckptName, CKPTFAIL); die(dieformat(261)); } my $CRSCTL = crs_exec_path('crsctl'); system("$CRSCTL query css votedisk"); } } if (isFirstNodeToConfig($localNode)) { trace("The node:" . $CFG->HOST . " is the first node to configure"); createCredDomain('ASM', 'OLR') || die(dieformat(377)); createCredDomain('ASM', 'OCR') || die(dieformat(377)); if (isNearASM()) { create_asm_credentials(); } if (($success) && (isBigCluster()) && (! ($CFG->params('HUB_NODE_LIST'))) && ($CFG->defined_param('HUB_SIZE'))) { $success = setHubSize(); } } # Call this after 'ocrconfig -upgrade' only on the first node # Sync the OCR locations list to other nodes $ocr->configureCurrentNode($ocr->DISTRIBUTE_ORCLOC_FILE); if ($excl_ret == CSS_EXCL_SUCCESS) { # Push local gpnp setup to be cluster-wide. # This will copy local gpnp file profile/wallet setup to a # list of cluster nodes, including current node. # This promotes a node-local gpnp setup to be "cluster-wide" trace ("Promoting local gpnp setup to cluster-wide. Nodes " . $CFG->params('NODE_NAME_LIST')); if (! push_clusterwide_gpnp_setup( $CFG->params('NODE_NAME_LIST'))) { $success = FALSE; writeCkpt($ckptName, CKPTFAIL); die(dieformat(262)); } trace("Stopping CSS which is running exclusive mode"); if (! stopFullStack("force")) { writeCkpt($ckptName, CKPTFAIL); die(dieformat(267)); } } # copy the gpnp setup files from existing nodes if they are not present. if (! check_clusterwide_gpnp_profile()) { trace("Copy gpnp setup files from existing nodes ". "because they're deleted during a previous deconfiguration."); if (! pull_cluserwide_gpnp_setup2($CFG->params('NODE_NAME_LIST'))) { die(dieformat(639)); } } if ($success != TRUE) { writeCkpt($ckptName, CKPTFAIL); } else { writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } return $success; } sub add_voting_disks { my $CDATA_DISK_GROUP = $CFG->params('CDATA_DISK_GROUP'); my $success; # Depending on whether using ASM or not, create # accordingly if ($CFG->ASM_STORAGE_USED) { $success = CSS_add_vfs($CFG, "+$CDATA_DISK_GROUP"); } else { $success = CSS_add_vfs($CFG, split(',', $CFG->params('VOTING_DISKS'))); } return $success; } sub perform_configNode { my $ckptStatus; my $ckptName = "ROOTCRS_NODECONFIG"; if (isCkptexist($ckptName)) { $ckptStatus = getCkptStatus($ckptName); trace("'$ckptName' state is $ckptStatus"); if ($ckptStatus eq CKPTSUC) { trace("CRS node configuration resources are already configured"); $CFG->wipCkptName("ROOTCRS_STACK"); return SUCCESS; } } writeCkpt($ckptName, CKPTSTART); $CFG->wipCkptName($ckptName); configNode(); } sub configNode #------------------------------------------------------------------------------- # Function: Configure node # Args : none # Returns : TRUE if success # FALSE if failed #------------------------------------------------------------------------------- { trace ("Configuring node"); my $success = TRUE; my $ckptName = "ROOTCRS_NODECONFIG"; # Configure new node if (isAddNode($CFG->HOST)) { trace("Performing new node configurations"); if (isAppCluster()) { trace("Configure a newly added node in an application cluster"); $success = startCHA_onNewNode($CFG->HOST); } else { $success = configNewNode($CFG->HOST); } if ($success) { writeCkptProperty($ckptName, $CFG->HOST, "ADDED_NODE"); writeCkpt($ckptName, CKPTSUC); } else { writeCkpt($ckptName, CKPTFAIL); die(dieformat(277)); } return $success; } # Configure fresh install node my $orasrvm = $CFG->compSRVM; if (FAILED == $orasrvm->postConfigureCurrentNode()) { writeCkpt($ckptName, CKPTFAIL); exit(-1); } writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); return $success; } sub configNewNode #--------------------------------------------------------------------- # Function: Configure nodeapps for new node # Args : [0] new node # [1] DHCP tag to indicate if DHCP is used # Returns : TRUE if success # FALSE if failed #--------------------------------------------------------------------- { my $newnode = $_[0]; my $srvctl = crs_exec_path('srvctl'); my $run_as_owner = FALSE; my (@capout, @cmd, $status); trace ("Configure Nodeapps for new node=$newnode"); if (isBigCluster() && isRimNode()) { trace("Skip configuring nodeapps on rim node"); return TRUE; } # network type: static, DHCP: false # network type: mixed, both DHCP and static addresses are true # network type: dynamic, DHCP: true # network type 'mixed' means a combination of static and dynamic, # for either IPv4 or IPv6 address types # DHCP is dhcp(for IPv4) or autoconfig(for IPv6) # for DHCP, wait for vip resource to exist before start vip if (($CFG->params('CRS_DHCP_ENABLED') eq 'true') && (getNetworkType() ne 'mixed')) { my $vip_exists = waitForVipRes(); if (! $vip_exists) { print_error(10); return FALSE; } } else { # same operations for network type static and mixed # get VIP my $hostvip = getHostVIP($newnode); if (! $hostvip) { die(dieformat(276)); } # add vip $status = srvctl($run_as_owner, "add vip -n $newnode -k 1 -A \"$hostvip\" "); if ($status) { trace ("add vip on node=$newnode ... success"); } else { error ("add vip on node=$newnode ... failed"); return FALSE; } } # start vip $status = srvctl($run_as_owner, "start vip -i $newnode"); if (${status}) { trace ("start vip on node:$newnode ... success"); } else { print_error(108, $newnode); return FALSE; } if ($CFG->platform_family eq "windows") { # start listener my $run_as_user = TRUE; my $cmd = "start listener -n $newnode"; my $status = srvctl($run_as_user, $cmd); if ( $status ) { trace("@cmd ... success"); } else { trace("@cmd ... failed"); return FALSE; } } if (! startCHA_onNewNode($newnode)) { return FALSE; } return TRUE; } sub startCHA_onNewNode { my $newnode = $_[0]; my $succ = TRUE; # Start OCHAD on the newly added node only if OCHAD is # configured and running on at least one node in the cluster # This node is assumed to be HUB node if ((isCHASupported())&&(isCHAConfigured()) && (status_cha(getCurrentNodenameList())) ) { if (start_cha(FALSE, $newnode)) { trace("CHA started on the new added node"); } else { trace("Failed to start CHA on this node"); $succ = FALSE; } } return $succ; } # Call 'appvipcfg' to configure an application vip if users specify it sub config_appvip { if (($CFG->params('APPLICATION_VIP')) && (isFirstNodeToStart())) { trace("Configuring the specified application VIP ..."); my $ckptStatus; my $ckptName = "ROOTCRS_APPVIP"; if (isCkptexist($ckptName)) { $ckptStatus = getCkptStatus($ckptName); trace("'$ckptName' state is $ckptStatus"); if ($ckptStatus eq CKPTSUC) { trace("The specified application VIP already configured"); $CFG->wipCkptName("ROOTCRS_STACK"); return SUCCESS; } } writeCkpt($ckptName, CKPTSTART); $CFG->wipCkptName($ckptName); my $cluster_name = $CFG->params('CLUSTER_NAME'); my $vip = trim($CFG->params('APPLICATION_VIP')); my $vipname = "$cluster_name"."-vip"; my $user = $CFG->params('ORACLE_OWNER'); my $grp = $CFG->params('ORA_DBA_GROUP'); my $appvipcfg = catfile($CFG->ORA_CRS_HOME, "bin", "appvipcfg"); my $cmd; if ($CFG->platform_family eq "windows") { $cmd = "$appvipcfg create -network=1 -ip=$vip -vipname=$vipname " . "-user=$user"; } else { $cmd = "$appvipcfg create -network=1 -ip=$vip -vipname=$vipname " . "-user=$user -group=$grp"; } my @out = system_cmd_capture($cmd); my $rc = shift(@out); if (0 == $rc) { trace("Successfully configured the specified application VIP"); } else { writeCkpt($ckptName, CKPTFAIL); die(dieformat(570)); } # Start the specified application VIP if (! start_resource($vipname)) { writeCkpt($ckptName, CKPTFAIL); die(dieformat(214, $vipname)); } writeCkpt($ckptName, CKPTSUC); $CFG->wipCkptName("ROOTCRS_STACK"); } return SUCCESS; } sub getHostVIP #--------------------------------------------------------------------- # Function: Get Host's VIP from CLUSTER_NEW_VIPS # Args : [0] Hostname # Returns : Host's VIP #--------------------------------------------------------------------- { my $hostname = $_[0]; my @new_hosts = split (/,/, $CFG->params('CLUSTER_NEW_HOST_NAMES')); my @new_vips = split (/,/, $CFG->params('CLUSTER_NEW_VIPS')); my $nbr_of_hosts = scalar(@new_hosts); my $nbr_of_vips = scalar(@new_vips); my $srvctl = crs_exec_path('srvctl'); my $ix = 0; my ($hostVIP, $netmask, $if, $prefixlen6); if (($CFG->params('CRS_DHCP_ENABLED') ne 'true') && ($nbr_of_hosts != $nbr_of_vips)) { die(dieformat(274)); } my $run_as_owner = FALSE; my ($rc, @output); $rc = srvctl_capture($run_as_owner, \@output, "config nodeapps -S 1"); if (($rc !=0) && ($rc !=2)) { print_lines(@output); print_error(180, "srvctl config nodeapps -S 1"); } my @viplist = grep(/netmask=/, @output); trace("viplist = '@viplist'"); if (scalar(@viplist) > 0) { trace ("viplist='$viplist[0]'"); # get new VIP $ix = 0; foreach my $host (@new_hosts) { chomp $host; if ($hostname =~ /$host$/i) { last; } $ix++; } # append netmask/if to new vip # For IPV4, netmask is pouplated and prefixlen6 is empty. # For IPV6, netmask is emtpy but we have prefixlen6 pouplated. my @list = split(/} +/, $viplist[0]); foreach (@list) { trace("IP list=$_"); if ($_ =~ /netmask=/) { $netmask = parseText ($_); } elsif ($_ =~ /interfaces=/) { $if = parseText ($_); } elsif ($_ =~ /prefixlen6=/) { $prefixlen6 = parseText($_); } } trace("netmask = $netmask"); trace("interface = $if"); trace("prefixlen6 = $prefixlen6"); } # append netmask/if to new vip if ((! $netmask) && $prefixlen6) { $netmask = $prefixlen6; } if ($netmask) { $hostVIP = $new_vips[$ix] . "/" . $netmask; if ($if) { # translate / replace ":" with "|" in the interface string $if =~ tr/[:]/[|]/; $hostVIP = $hostVIP . "/" . $if; } } sub parseText { # extract netmask and interface my $line = $_[0]; $line =~ s/{//g; $line =~ s/}//g; my ($dummy, $text) = split (/=/, $line); chomp $text; return $text; } trace("hostVIP = $hostVIP"); return $hostVIP; } sub start_asm { my $run_as_oracle_owner = TRUE; my $status = srvctl($run_as_oracle_owner, "start asm"); if ($status) { trace ("start asm ... success"); } else { print_error(113); return FALSE; } return TRUE; } sub stop_asm { my $run_as_oracle_owner = TRUE; my $status = srvctl($run_as_oracle_owner, "stop asm -f"); if ($status) { trace ("stop asm ... success"); } else { print_error(114); return FALSE; } return TRUE; } sub configureCvuRpm #------------------------------------------------------------------------------ # Function: Install cvuqdisk rpm on Linux # Args : none #------------------------------------------------------------------------------- { if ($CFG->platform_family eq "unix") { if (s_configureCvuRpm()) { trace("cvuqdisk rpm installed successfully"); } else { print_error(646); } } } sub precheck_siha { if (isPrereqIgnored()) { print_info(363); } } sub isCRSAlreadyConfigured #------------------------------------------------------------------------------- # Function: Check if CRS is already configured on this node # Args : none # Return : TRUE if CRS is already configured # FALSE if CRS is not already configured #------------------------------------------------------------------------------- { my $crshome; my $olr_exists = FALSE; my $localOCR_exists = FALSE; my $oraocr = $CFG->compOCR; my $crs_exists = s_check_CRSConfig($CFG->HOST, $CFG->params('ORACLE_OWNER')); if ($CFG->platform_family eq "windows") { $crshome = s_get_olr_file ("crs_home"); if ($crshome) { $olr_exists = TRUE; } } else { if (-e $CFG->params('OLRCONFIG')) { $crshome = s_get_olr_file ("crs_home"); if ($crshome) { $olr_exists = TRUE; } } } if ($CFG->platform_family eq "windows") { $localOCR_exists = $oraocr->localonlyOCR_exists(); } else { if (-e $CFG->params('OCRCONFIG')) { $localOCR_exists = $oraocr->localonlyOCR_exists(); } } if ($olr_exists && $crs_exists) { print_error(350); print_error(352, $crshome); trace ("Please deconfigure before proceeding with the " . "configuration of new home. "); return TRUE; } elsif ((! $olr_exists) && (! $crs_exists)) { trace ("CRS is not yet configured. Hence, will proceed to configure CRS"); return FALSE; } elsif ($CFG->UPGRADE && (! $olr_exists)) { return FALSE; } elsif (!$CFG->UPGRADE && (! $olr_exists) && ($localOCR_exists)) { return FALSE; } else { my $rootscript = "root.sh"; my $rootdeconfig = "rootcrs.pl"; if ($CFG->platform_family eq "windows") { $rootscript = "gridconfig.bat"; } if ($CFG->SIHA) { $rootdeconfig = "roothas.pl"; } print_error(351); trace ("Deconfigure the existing cluster configuration before starting"); trace ("to configure a new Clusterware"); print_error(353, $CFG->params('ORACLE_HOME'), $rootdeconfig, $rootscript); return TRUE; } } sub start_siha_ohasd { my $status = start_service("ohasd", $CFG->HAS_USER); if (! $status) { if (is_dev_env() && $CFG->UPGRADE) { trace("This is a dev env for SIHA upgrade"); my $av; my $retry = 0; my $OCRDUMPBIN = catfile($CFG->ORA_CRS_HOME, 'bin', 'ocrdump'); my @output; while ($retry++ < 60) { open (OCRDUMP, "$OCRDUMPBIN -local -noheader -stdout -keyname ". "SYSTEM.version.activeversion |"); @output = ; close(OCRDUMP); trace("ocrdump output for active version is @output"); my @txt = grep(/ORATEXT/, @output); if (scalar(@txt) > 0) { my ($key, $ver) = split(/:/, $txt[0]); $av = trim($ver); trace("The active version is $av"); } if (-1 == versionComparison($av, "12.1.0.0.0")) { trace("Waiting for AV to become new"); sleep(10); } else { last; } } my $success; if (-1 != versionComparison($av, "12.1.0.0.0")) { trace("Resource and type conversion completed. Restart ohasd"); my $CRSCTL = catfile($CFG->ORA_CRS_HOME, "bin", "crsctl"); @output = system_cmd_capture($CRSCTL, 'start', 'has'); $status = shift @output; if ((0 == $status) || (scalar(grep/4640/, @output) > 0)) { $success = TRUE; trace("Oracle High Availability Services is up now"); } else { print_lines(@output); trace("\"$CRSCTL start has\" failed with status $status"); } } if (! $success) { die(dieformat(318)); } } else { die(dieformat(318)); } } trace("Successfully started ohasd for SIHA"); } sub local_only_stack_active { $ENV{'ORACLE_HOME'} = $CFG->oldconfig('DB_HOME'); my $restart_css = FALSE; # check if older version SI CSS is running my $OLD_CRSCTL = catfile ($CFG->oldconfig('DB_HOME'), "bin", "crsctl"); my @output = system_cmd_capture ("$OLD_CRSCTL check css"); my $status = shift @output; if (0 == $status && (scalar(grep(/4529/, @output)) > 0)) { # set flag to restart SIHA CSS before we're done $restart_css = TRUE; } $ENV{'ORACLE_HOME'} = $CFG->params('ORACLE_HOME'); return $restart_css; } sub stop_local_only_stack { my $OLD_SIHOME = $CFG->oldconfig('DB_HOME'); my $stack_stopped = SUCCESS; my $status; #Bug 8280425. Take a backup of ocr.loc and local.ocr #before invoking localconfig -delete my $local_ocr = catfile($OLD_SIHOME, 'cdata', 'localhost', 'local.ocr'); my $local_ocr_save = catfile($OLD_SIHOME, 'cdata', 'localhost', 'local.ocr.save'); my ($ocr_loc, $ocr_loc_save); if ($CFG->platform_family eq "windows") { $ocr_loc = $CFG->params('OCRLOC'); $ocr_loc_save = $CFG->params('OCRLOC') . '.save'; trace("backing up $ocr_loc registry"); s_copyRegKey($ocr_loc, $ocr_loc_save); } else { $ocr_loc = catfile ($CFG->params('OCRCONFIGDIR'), 'ocr.loc'); $ocr_loc_save = catfile ($CFG->params('OCRCONFIGDIR'), 'ocr.loc.save'); trace("backing up $ocr_loc"); if (copy_file ($ocr_loc, $ocr_loc_save) != SUCCESS) { print_error(165, $ocr_loc); } } # backing up local_ocr trace("backing up $local_ocr"); if (copy_file ($local_ocr, $local_ocr_save) != SUCCESS) { print_error(165, $local_ocr); } if ($CFG->platform_family eq "windows") { s_stopDeltOldASM(); s_stopService("OracleCSService"); if (s_isServiceRunning("OracleCSService")) { s_stopService("OracleCSService"); } s_deltService("OracleCSService") } # stop old SI CSS trace ("Stopping older version SI CSS"); my $OLD_LOCALCONFIGBIN = catfile ($CFG->oldconfig('DB_HOME'), "bin", "localconfig"); $status = system ("$OLD_LOCALCONFIGBIN delete"); if ($status == 0) { trace ("Older version SI CSS successfully stopped/deconfigured"); } else { $stack_stopped = FAILED; print_error(166); } # Bug 8280425 'localconfig -delete' removes the ocr.loc and local.ocr # restore the same. if ($CFG->platform_family eq "windows") { trace("restoring $ocr_loc registry"); s_copyRegKey($ocr_loc_save, $ocr_loc); } else { trace("restoring $ocr_loc"); if (copy_file ($ocr_loc_save, $ocr_loc) != SUCCESS) { print_error(167, $ocr_loc); } } # restoring local_ocr trace("restoring $local_ocr"); if (copy_file ($local_ocr_save, $local_ocr ) != SUCCESS) { print_error(167, $local_ocr); } if ($CFG->platform_family eq "unix") { s_set_ownergroup($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_DBA_GROUP'), $ocr_loc) || die(dieformat(152, $ocr_loc)); s_set_ownergroup($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_DBA_GROUP'), $local_ocr) || die(dieformat(152, $local_ocr)); } return $stack_stopped; } ####--------------------------------------------------------- #### Function name : migrate_dbhome_to_SIHA # ARGS 0: # This routine does the operations in the following sequence. # 1) Take a backup copy of older ocr file. # 2) Update the location of ocr.loc # 3) touch and change file permissions. # 4) Create necessary configuration with 'crsctl pin css' command. sub migrate_dbhome_to_SIHA { my ($db_home, $status); my $OCRCONFIGBIN = crs_exec_path("ocrconfig"); my $CRSCTLBIN = crs_exec_path("crsctl"); my $ocrcfg_loc = $CFG->oldconfig('OCRCONFIG'); my $copy_lococr = catfile($CFG->params('ORACLE_HOME'), 'cdata', 'localhost', 'localsiasm.ocr'); my $new_lococr = catfile($CFG->params('ORACLE_HOME'), 'cdata', 'localhost', 'local.ocr'); my $ret = FAILED; my $oraocr = $CFG->compOCR; $ENV{'NLS_LANG'} = $CFG->params('LANGUAGE_ID'); # copy over older local-only OCR to SIHA home if (defined $ocrcfg_loc) { if (copy_file ($ocrcfg_loc, $copy_lococr) != SUCCESS) { print_error(106); } } # Now touch, set owner and perm if (!(-e $new_lococr)) { if ($CFG->DEBUG) { trace ("Creating empty file $new_lococr");} # create an empty file open (FILEHDL, ">$new_lococr") or die(dieformat(255, $new_lococr, $!)); close (FILEHDL); } # Set ownership/group s_set_ownergroup ($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_DBA_GROUP'), $new_lococr) || die(dieformat(152, $new_lococr)); # Set permissions, if specified s_set_perms ("0640", $new_lococr) || die(dieformat(153, $new_lococr)); # update ocr.loc if (defined $ocrcfg_loc) { if (0 != system_cmd($OCRCONFIGBIN, '-repair', '-replace', $ocrcfg_loc, '-replacement', $new_lococr)) { print_error(155); } } # Create configuration needed for compatibility with older DBs (10.x, 11.1). $ret = $oraocr->configureSIHA(); if (!$ret) { print_error(156); trace ("Creating local-only OCR ... failed"); } else { trace ("Creating local-only OCR ... succeeded"); } return $ret; } sub forceCheck { my $isForce = $CFG->FORCE; my $isUpgrade = $CFG->UPGRADE; my $isFirst = $CFG->FIRST; my $localNodeName = tolower_host(); my $installNode = getInstallNode(); my $isInstallerNode = ($localNodeName eq $installNode); my $ckptState; my $isFirstNodeCkptSuc = isCkptSuccess("ROOTCRS_FIRSTNODE", "-global"); # the node being made as the first node must be a hub node if($isFirst && (NODE_ROLE_RIM eq getLocalNodeRole())) { trace("The node being made as the first node must be a hub node."); die(dieformat(512,$localNodeName)); } my $isFirstNode = isForcedFirstNode(); trace("Start to check whether the '-first' and '-force' options are ". "correctly supplied."); trace(" Current Node: $localNodeName; \n Is First Node: $isFirstNode; \n". " '-force' Option Supplied: $isForce; \n Is Upgrade: $isUpgrade; \n". " '-first' Option Supplied: $isFirst; \n Is First Node Ckpt Success: ". "$isFirstNodeCkptSuc; \n Is Installer Node: $isInstallerNode."); # Check 1: # Following case prevents user from forcing first-node operations after # firstnode CKPT is written as SUCCESS in OCR. if ($isFirst && $isFirstNodeCkptSuc && !$isInstallerNode) { # If current node has successfully run the root script, it will be stopped # by create_starting_ckpt_entry() with local checkpoint. trace("The first-node operations have been done. Failed to force current ". "node: $localNodeName to do the first-node operations. Run root ". "script without '-first -force' options."); die(dieformat(526, $localNodeName)); } # Check 2: # Following three cases prevent user from forcing any node to do last-node # operations during fresh install, or during upgrade before first-node # operations have been done. if ($isForce && !$isFirst && !$isUpgrade && $isFirstNodeCkptSuc && !$isInstallerNode) { # Firstnode CKPT is SUCCESS, and current node is not the installer node. It # cannot be forced as neither first-node nor last-node during fresh install. trace("Failed to force current node: $localNodeName to do the last-node ". "operations during fresh install. Run root script without '-force'". " options."); die(dieformat(527, $localNodeName)); } if ($isForce && !$isFirst && !$isFirstNodeCkptSuc && $isInstallerNode) { # Firstnode CKPT is not SUCCESS and current node is the installer node. It # need to finish the first-node operations wihout "-first -force" options. # Because the installer node is alive, only the installer node can do the # first-node operations. Hence, current node has not successfully run the # root script. trace("Failed to force current node: $localNodeName to do the last-node ". "operations during fresh install, or during upgrade before ". "first-node operations have been done. Run root script without ". "'-force' options."); (!$isUpgrade) ? die(dieformat(527, $localNodeName)) : die(dieformat(528, $localNodeName)); } if ($isForce && !$isFirst && !$isFirstNodeCkptSuc && !$isInstallerNode) { # Firstnode CKPT is not SUCCESS and current node is not the installer # node. It need to finish the first-node operations with "-first -force" # options. # Installer node must be not alive. Otherwise, the root script will be # stopped with message 508 by Check 1 above. # Hence current node can only run root script with '-first -force' options # to do the first node operations. trace("Failed to force current node: $localNodeName to do the last-node ". "operations during fresh install, or during upgrade before ". "first-node operations have been done. Run root script with '-first ". "-force' options."); (!$isUpgrade) ? die(dieformat(529, $localNodeName)) : die(dieformat(530, $localNodeName)) } # Check 3: # Following case prevents user from running root script with '-first force' # options on installer node. if ($isFirst && $isInstallerNode) { # Installer node never needs the '-first -force' options to do the # first-node operations. trace("Failed to run root script with '-first force' options on installer". " node. Run root script with '-first -force' options."); die(dieformat(531,$localNodeName)); } } 1; __END__ =head2 =head3 Parameters =head3 Returns =head3 Usage =cut