# # $Header: has/install/crsconfig/orasrvm.pm /st_has_12.2.0.1.0/1 2016/11/02 13:04:11 xyuan Exp $ # # orasrvm.pm # # Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. # # NAME # orasrvm.pm - Implements interfaces defined in oraClusterwareComp.pm, which configures # and upgrades CRSD managed resources # # DESCRIPTION # An SRVM component to manage the CRSD resources like CVU, and to # do 'srvctl upgrade model', etc. # # NOTES # # # MODIFIED (MM/DD/YY) # xyuan 10/31/16 - Backport xyuan_bug-24692493 from main # luoli 10/21/16 - Add and start RHP client on Member Cluster # xyuan 07/21/16 - Fix bug 24314345 # yilhu 06/23/16 - Fix bug 19585275 # xyuan 04/21/16 - ODA Lite/SIP/IaaS # bbeelamk 03/08/16 - Fix srvctl error # lluis 02/23/16 - Call crskeytoolctl to create root certificate. # luoli 02/17/16 - configFirstNode() will always add asm in 12.2 # except on ASM client cluster # rtamezd 02/05/16 - Bug 22668961: Fix pre-12.1.0.2 check for RHP # rtamezd 02/02/16 - Don't check for RHP in pre-12 # rtamezd 01/14/16 - Run config & stop RHP from old home # rtamezd 12/16/15 - RHP repos upgrade changes # xyuan 12/07/15 - Fix bug 22318441 # muhe 11/26/15 - Fix bug 22083830 # xyuan 11/18/15 - Fix bug 22223328 # muhe 10/20/15 - Remove upgrade_option for add_Nodeapps() since it's # only used for upgrade from pre-11.2 # akhaladk 10/12/15 - ONS wallet should only be configured on first node. # gmaldona 10/06/15 - Remove references to crsoc4j.pm. # Add upgrade_credstore() to postUpgradeLastNode(). # Start ora.qosmserver in configFirstNode(). # akhaladk 09/29/15 - more places to configure wallets. # akhaladk 09/16/15 - Add ons wallet # bbeelamk 09/15/15 - Changing srvctl method # jmarcias 07/08/15 - Fix bug 21378016 # jmarcias 06/11/15 - Fix bug 21242118 # bbeelamk 06/04/15 - Fix bug 20558793 # xyuan 05/22/15 - Fix bug 21126418 # xyuan 05/20/15 - Cleanup # espgarci 05/06/15 - Add support for qosmserver resource # xyuan 04/28/15 - Fix bug 20961590 # muhe 04/14/15 - Add interface functions body for upgrade and patch # jmarcias 04/14/15 - Fix bug 20871314 # xyuan 03/21/15 - Changes for upgrading std ASM # jmarcias 03/20/15 - Fix bug 20734170 # muhe 03/18/15 - Fix bug 20726559 # luoli 03/04/15 - Fix bug 20598131 # xyuan 02/28/15 - Fix bug 20614945 # jmarcias 02/26/15 - Fix bug 20599745 # jmarcias 01/13/15 - RHP Repository upgrade # bbeelamk 12/16/14 - upgrade from std cluster # xyuan 12/15/14 - Fix bug 20206616 # luoli 12/01/14 - Fix bug 20125312 # xyuan 11/30/14 - Application Cluster # xyuan 11/03/14 - Creation # package oraClusterwareComp::orasrvm; use parent 'oraClusterwareComp'; use strict; use English; use Carp; use File::Copy; use File::Path; use File::Find; use File::Basename; use File::Spec::Functions; use constant FIRST_NODE => "first"; use constant LAST_NODE => "last"; use crsutils; use s_crsutils; use oraqosmserver; use oraons; use oraasm; sub new { my $class = shift; # Pass the component name into the constructor my $componentName = @_; my $self = $class->SUPER::new(@_); $self->_initialize(); return $self; } # Initialize SRVM component sub _initialize { my $self = shift; my $compName = $self->compName; trace("Perform initialization tasks before configuring $compName"); } # # Interface to be implemented # # Is SRVM supported based on platform and user input sub isSupported { # Supported on all platforms return TRUE; } # Which component does OCR depend on sub dependsOn { # No dependency return undef; } # Has the component already been configured sub isConfigured { #TODO return FALSE; } # # Methods for install flow # # Configure action on first node sub configureFirstNode { return SUCCESS; } # Configure action on every node other than first node sub configureNonFirstNode { return SUCCESS; } # Configure action on first node after the configured stack # has been started sub postConfigFirstNode { my $self = shift; trace("Configuring CRSD managed resources on first node ..."); if (isAppCluster()) { trace("Configuring CRS managed resources on an application cluster node"); return configAppClusterNode(); } trace("Configuring CRS managed resources on a database cluster node"); my $DHCP_flag = FALSE; my $success = FALSE; my @nodevip; my @nodes_to_add; my @nodes_to_start; collectNodeappsInfo(\$DHCP_flag, \@nodes_to_add, \@nodevip); if (! upgradeModelResType()) { return FAILED; } $success = add_Nodeapps(\@nodevip, $DHCP_flag, \@nodes_to_add, \@nodes_to_start); if ($success != TRUE) { print_error(286); return FAILED; } $success = configFirstNode($DHCP_flag, \@nodes_to_start); if ($success != SUCCESS) { print_error(287); return FAILED; } if (isOPCDomu() || isODASIP()) { startSCANandListenerWithNodeNum(); } return SUCCESS; } # Configure action on other nodes than the first node after # the configured stack has been started sub postConfigNonFirstNode { my $self = shift; trace("Configuring CRSD managed resources on non-first node ..."); if (isAppCluster()) { trace("Configuring CRS managed resources on an application cluster node"); return SUCCESS; } trace("Configuring CRS managed resources on a database cluster node"); my $DHCP_flag = FALSE; my $success = FALSE; my @nodevip; my @nodes_to_add; my @nodes_to_start; collectNodeappsInfo(\$DHCP_flag, \@nodes_to_add, \@nodevip); if ($DHCP_flag) { push @nodes_to_start, $nodes_to_add[0]; } else { $success = add_Nodeapps(\@nodevip, $DHCP_flag, \@nodes_to_add, \@nodes_to_start); if ($success != SUCCESS) { print_error(286); return FAILED; } } $success = start_Nodeapps($DHCP_flag, \@nodes_to_start); if ($success != SUCCESS) { print_error(288); return FAILED; } if (isOPCDomu() || isODASIP()) { startSCANandListenerWithNodeNum(); } return SUCCESS; } # # Methods for upgrade regarding SRVM component # The method for global checks related to SRVM component before upgrade # This method is called only on the first node when the stack is up. sub preUpgradeCheck { return SUCCESS; } # The method for local checks related to SRVM component before upgrading the first node sub upgradeCheckFirstNode { return SUCCESS; } # The method for local checks related to SRVM component before upgrading the middle node sub upgradeCheckMiddleNode { return SUCCESS; } # The method for local checks related to SRVM component before upgrading the last node sub upgradeCheckLastNode { return SUCCESS; } # Upgrade action on first node sub upgradeFirstNode { my $self = shift; my $old_home = $CFG->oldconfig('ORA_CRS_HOME'); if (!isOldVersionLT12102() && isRHPSConfigured($old_home) && (!stopRHP($old_home) || !exportRHPRepos())) { return FAILED; } return SUCCESS; } # Upgrade action on every node other than first and last node sub upgradeMiddleNode { # NOOP return SUCCESS; } # Upgrade action on last node sub upgradeLastNode { # NOOP return SUCCESS; } # Upgrade action on the first node after the higher version stack # has been started sub postUpgradeFirstNode { my $self = shift; print_info(474); if (! upgrademodel(FIRST_NODE)) { print_error(280); return FAILED; } print_info(475); if (isLegacyASM()) { startASMListeners(); } if (! generate_rootcert()) { trace("An error occurred generating the root certificate. SRVM resources" . " (qosmserver, rhpserver, rhpclient, etc) will fail to start with" . " TLS protocol support enabled."); return FAILED; } return SUCCESS; } # Upgrade action on every node other than first and last node # after the higher version stack has been started sub postUpgradeMiddleNode { if (isLegacyASM()) { startASMListeners(); } return SUCCESS; } # Upgrade action on the last node after the higher version stack # has been started sub postUpgradeLastNode { my $self = shift; my $status; if (isLegacyASM()) { startASMListeners(); } print_info(476); if (! upgrademodel(LAST_NODE)) { print_error(284); return FAILED; } print_info(477); # Update credentials for WLM if (! upgrade_credstore()) { return FAILED; } return SUCCESS; } # Whether or not the system reboot is needed after configuring SRVM sub rebootRequired { return FALSE; } sub postUpgradeSIHA { my $self = shift; trace("Calling 'srvctl upgrade model' for SIHA"); if (! upgrademodel(FIRST_NODE)) { die(dieformat(280)); } if (! upgrademodel(LAST_NODE)) { die(dieformat(284)); } return SUCCESS; } # # Private methods # # private methods called by above APIs sub startSCANandListenerWithNodeNum { my $host_name = $CFG->HOST; my $local_node_number = getLocalNodeNumber(); # Get the node number if ($local_node_number > 0) { trace("Starting SCAN and SCAN listener number $local_node_number in " . "node $host_name"); if (!start_scan($local_node_number) || !start_scan_listener($local_node_number)) { return FAILED; } } else { print_error(621, $host_name); return FAILED } } sub collectNodeappsInfo { my $isDHCP_ref = shift; my $nodes_to_add_ref = shift; my $nodevip_ref = shift; my $DHCP_flag = FALSE; trace("Collecting nodeapps info ..."); # Set DHCP_flag to TRUE if it's DHCP my $crs_nodevips = $CFG->params('CRS_NODEVIPS'); $crs_nodevips =~ s/'//g; # ' in comment to avoid confusion of editors. $crs_nodevips =~ s/"//g; # remove " on Windows $crs_nodevips =~ s/\/\*/\//g; # handle different interface case my @crs_nodevip_list = split (/\s*,\s*/, $crs_nodevips); if ($crs_nodevip_list[0] =~ /\bAUTO/) { $DHCP_flag = TRUE; } ${$isDHCP_ref} = $DHCP_flag; my @nodevip; my @nodes_to_add; my @node_list = split (',', $CFG->params('NODE_NAME_LIST')); my $ix = 0; foreach my $node (@node_list) { if ($CFG->HOST =~ /$node$/i) { push @nodevip, $crs_nodevip_list[$ix]; push @nodes_to_add, $node; last; # done for this node } else { $ix++; } } @{$nodes_to_add_ref} = @nodes_to_add; @{$nodevip_ref} = @nodevip; trace("isDHCP: ${$isDHCP_ref}"); trace("Nodes to be added: @{$nodes_to_add_ref}"); trace("Node VIPs: @{$nodevip_ref}"); return; } sub upgradeModelResType #------------------------------------------------------------------------------- # Function: Creates the resource types for all nodeapps and the crsd managed # resources. # Args : none # Returns : TRUE if 'srvctl upgrade model -restype' succeeds # FALSE if 'srvctl upgrade model -restype' fails #------------------------------------------------------------------------------- { my $run_as_owner = FALSE; my $success = TRUE; my $status = srvctl($run_as_owner, "upgrade model -restype"); if ($status) { trace ("srvctl upgrade model -restype ... passed"); } else { $success = FALSE; } return $success; } sub configFirstNode #--------------------------------------------------------------------- # Function: Configure first node # Args : [0] DHCP_flag # [1] nodes_to_start # Returns : TRUE if success # FALSE if failed #--------------------------------------------------------------------- { my $DHCP_flag = shift; my $nodes_to_start_ref = shift; my $run_as_owner = TRUE; trace ("Configuring CRSD resources on first node"); trace ("DHCP_flag=$DHCP_flag"); trace ("nodes_to_start=@$nodes_to_start_ref"); if (0 == scalar(@$nodes_to_start_ref)) { trace("nodes_to_start is null"); return FAILED; } #set the network interface - Bug 9243302 if (! isOPCDomu()) { setNetworkInterface() || return FAILED; } if ((! isAppCluster()) && (!((isODALite() || add_GNS()) && add_scan($DHCP_flag) && add_scan_listener() && generate_rootcert() && add_qosmserver() && add_rim_listener()))) { return FAILED; } if (isODALite()) { trace("Disable SCAN and SCAN listener in an ODA environment"); my $run_as_owner = TRUE; my $status = srvctl($run_as_owner, "disable scan_listener"); if ($status) { trace("Disabling SCAN listener ... succeeded"); $run_as_owner = FALSE; $status = srvctl($run_as_owner, "disable scan"); if ($status) { trace("Disabling SCAN ... succeeded"); } else { return FAILED; } } else { return FAILED; } } if (($CFG->params('MGMT_DB') =~ m/true/i) && (! isRemoteGIMR()) && (!add_mgmt_db_listener())) { return FAILED; } # Configure CHA only where CHA is supported if (isCHASupported()) { # Pass 'force' option. MGMTDB not configured yet. if (!add_cha('-force')) { print_error(2602); return FAILED; } } # Do not create asm or diskgroup resources on a ASM client cluster if (!isFarASM()) { trace("Invoking add asm, except for ASM client cluster"); add_ASM(); # add ora.asm if ($CFG->ASM_STORAGE_USED) { createDiskgroupRes() || return FAILED; # add disk group resource, if necessary # Set the ASM PWfile backup location to the attribute in ora.asm my $oraasm = $CFG->compASM; trace("Setting ASM PWfile backup attribute in install stage..."); my $attrsuccess = SUCCESS; $attrsuccess = $oraasm->setASMPWfileBackupAttr(); if ($attrsuccess != SUCCESS) { trace("Setting ASM PWfile backup location to the attribute " . "in ora.asm resouce failed..."); } } } add_CVU("0") || return FAILED; if (! isAppCluster()) { if (start_Nodeapps($DHCP_flag, \@$nodes_to_start_ref) && (isODALite() || start_GNS()) && (isODALite() || isODASIP() || isOPCDomu() || start_scan()) && (isODALite() || isODASIP() || isOPCDomu() || start_scan_listener())) { start_qosmserver() || return FAILED; } else { return FAILED; } } start_CVU() || return FAILED; # Start CHA only where CHA is supported if (isCHASupported()) { # Pass 'TRUE' option. Ignore error on start. MGMTDB not configured yet. if (!start_cha(TRUE, "")) { print_error(2604); return FAILED; } } return SUCCESS; } sub add_Nodeapps #------------------------------------------------------------------------------- # Function: Add nodeapps for static IP & DHCP # Nodeapps are added on each node # and started as each node is configured. # Args : [0] nodevip # [1] DHCP_flag # [2] nodes_to_add # [3] nodes_to_start # Returns : TRUE if success # FALSE if failed # nodes_to_start - list of nodes to start #------------------------------------------------------------------------------- { my $nodevip_ref = shift; my $isDHCP = shift; my $nodes_to_add_ref = shift; my $nodes_to_start_ref = shift; trace ("Adding nodeapps..."); trace ("nodevip=@$nodevip_ref"); trace ("DHCP_flag=$isDHCP"); trace ("nodes_to_add=@$nodes_to_add_ref"); if (0 == scalar(@$nodes_to_add_ref)) { trace("nodes_to_add is null"); return FALSE; } my $srvctl_func = \&srvctl; if ((($^O eq "linux") || ($^O eq "solaris")) && ($CFG->AUTO)) { trace("Call srvctl_tty"); $srvctl_func = \&srvctl_tty; } my $ons_client_data = ""; if (isFirstNodeToStart()) { create_ons_wallets(); $ons_client_data = " -clientdata " . $CFG->params('ONSWALLETDIR'); trace("Set ONS client data " . "$ons_client_data"); } my $success = TRUE; my $run_as_owner = FALSE; my @output; if ($isDHCP) { trace ("add nodeapps for DHCP"); my $node = $$nodes_to_add_ref[0]; push @$nodes_to_start_ref, $node; # Currently we don't support multiple public subnets. The installer should # be smart enough not to allow user to select more than 1 public subnet. my @subnets = getSubnets ($CFG->params('NETWORKS'), 'public'); my $subnet = shift (@subnets); my $nodevip = shift (@$nodevip_ref); # substitute AUTO w/ subnet $nodevip =~ s/AUTO/$subnet/; my $ping_targets = $CFG->params('PING_TARGETS'); my $cmd = "add nodeapps -S \"$nodevip\" "; if ($ping_targets ne undef) { $cmd = $cmd."-pingtarget \"$ping_targets\" "; } $cmd = $cmd."$ons_client_data"; my $status = srvctl($run_as_owner, $cmd); if ($status) { trace ("$cmd ... passed"); } else { $success = FALSE; } return $success; } # add nodeapps for STATIC IP trace("add nodeapps for static IP"); my $config_nodeapps = catfile ($CFG->ORA_CRS_HOME, "bin", "srvctl config nodeapps"); my $nodeapps_exist = FALSE; trace("Running srvctl config nodeapps to detect if nodeapps exist"); open OPUT, "$config_nodeapps |"; @output = grep(/(^PRKO-2331)/, ); # PRKO-2331 : ONS daemon does not exist. close OPUT; if (scalar(@output) == 0) { trace ("nodeapps exist"); $nodeapps_exist = TRUE; } else { trace ("output=@output"); } # Get NAT values for OPC clusters or ODA Lite/SIP/IaaS. # OPC or ODA Lite/SIP/IaaS does not support DHCP, so no NAT address if DHCP my $isOPCDomu = isOPCDomu(); foreach my $node (@$nodes_to_add_ref) { $node =~ tr/A-Z/a-z/; #convert to lowercase my $nodevip = shift (@$nodevip_ref) or die(dieformat(275)); my @txt = grep (/$node/, @output); my $status; my $cmd; my $nat_address_arg = ""; if (($isOPCDomu) || ((isODALite() || isODASIP() || isODAIaaS()) && ($CFG->params('OPC_NAT_ADDRESS'))) ) { my $opc_nat_address = getNatAddressForNode($node); if ($opc_nat_address) { $nat_address_arg = "-nataddress $opc_nat_address"; } else { die(die_format(620, $node)); } } if (scalar(@txt) == 0) { # nodeapps is not yet added on this node if ($nodeapps_exist) { # nodeapps already exist, only need to add vip $cmd = "add vip -n $node -k 1 -A \"$nodevip\" $nat_address_arg "; if (isBigCluster() && isRimNode()) { trace("No need to add vip on rim node"); $status = TRUE; } else { $status = &$srvctl_func($run_as_owner, $cmd); } } else { $nodeapps_exist = TRUE; $cmd = "add nodeapps -n $node -A \"$nodevip\" "; my $ping_targets = $CFG->params('PING_TARGETS'); if ($ping_targets ne undef) { $cmd = $cmd."-pingtarget \"$ping_targets\" "; } $cmd = $cmd."$nat_address_arg $ons_client_data"; $status = &$srvctl_func($run_as_owner, $cmd); } if (${status}) { push @$nodes_to_start_ref, $node; trace ("$cmd on node=$node ... passed"); } else { $success = FALSE; } } } trace ("nodes_to_start=@$nodes_to_start_ref"); return $success; } sub start_Nodeapps #------------------------------------------------------------------------------- # Function: Start nodeapps for static IP & DHCP # Args : [0] - DHCP_flag - TRUE if it's DHCP # [1] - nodes_to_start - list of nodes to be started # Returns : TRUE if success # FALSE if failed #------------------------------------------------------------------------------- { my $isDHCP = shift; my $nodes_to_start_ref = shift; trace ("Starting nodeapps..."); trace ("DHCP_flag=$isDHCP"); trace ("nodes_to_start=@$nodes_to_start_ref"); if (0 == scalar(@$nodes_to_start_ref)) { trace("nodes_to_start is null"); return FALSE; } my $success = TRUE; my @out; my @output; my $cmd; my $rc; if (isBigCluster() && isRimNode()) { trace("Cannot start vip on rim node"); return TRUE; } foreach my $node (@$nodes_to_start_ref) { if (($isDHCP) && (! isFirstNodeToStart())) { # wait for vip resource to exist before start vip my $vip_exists = waitForVipRes(); if (! $vip_exists) { print_error(10); return FALSE; } $cmd = "start vip -i $node"; } else { $cmd = "start nodeapps -n $node"; } $rc = srvctl_capture(FALSE, \@out, $cmd); if (($rc == 0) || ($rc == 2)) { @output=grep(!/(^PRKO-2419|^PRKO-242[0-3])/,@out); trace("output of startnodeapp after removing already started mesgs is @output"); if (scalar(@output) >= 1) { if (($CFG->UPGRADE) && (scalar(grep(/CRS-2546/, @output)) > 0)) { # Start nodeapp is invoked on the last node during uprade from pre-11.2 trace("Proceed with the upgrade if the target node is not online at this time"); } } trace ("srvctl $cmd ... passed"); } else { print_lines(@out); print_info(180, "srvctl $cmd"); $success = FALSE; } } return $success; } sub upgrademodel { my $nodeinfo = $_[0]; my $host = tolower_host(); my @old_version = @{$CFG->oldconfig('ORA_CRS_VERSION')}; my $srcver = join('.',@old_version); my $destver = getcursoftversion($host); my $success = TRUE; my $run_as_owner = FALSE; chomp $srcver; my $status = srvctl($run_as_owner, "upgrade model -s $srcver -d $destver -p $nodeinfo"); my $cmdStr = "srvctl upgrade model -s $srcver -d $destver -p $nodeinfo"; print_info(482, $cmdStr); if ($status) { trace ("srvctl upgrade model -$nodeinfo ... passed"); } else { $success = FALSE; } return $success; } sub configPubNetwork { my @subnets = getSubnets($CFG->params('NETWORKS'), 'public'); if (0 == scalar(@subnets)) { trace("No public network was found configured in the cluster"); return FAILED; } my $pnet = shift(@subnets); $pnet = trim($pnet); $pnet = expandIpv6($pnet) if(isIpv6($pnet)); my ($rc, @intfs) = get_oifcfg_info($CFG->ORA_CRS_HOME, 'iflist -p -n'); if (0 != $rc) { trace("Failed to get networks interface info with running 'oifcfg'"); return FAILED; } my $netmask; my $interface; foreach my $intf (@intfs) { my @iflist = split(/\s+/, $intf); my $ifnet = trim($iflist[1]); $ifnet = expandIpv6($ifnet) if(isIpv6($ifnet)); if ($pnet eq $ifnet) { $netmask = trim($iflist[3]); $interface = trim($iflist[0]); trace("Retrieving Public network info - subnet[$pnet], " ."netmask[$netmask], interface[$interface]"); last; } } if (($netmask eq "") || ($interface eq "")) { trace("Invalid network information retrieved"); print_error(568); return FAILED; } my $cmd; my $run_as_owner = FALSE; my $ping_targets = $CFG->params('PING_TARGETS'); if ($ping_targets) { $cmd = "add network -netnum 1 -subnet $pnet\/$netmask\/$interface " . "-pingtarget \"$ping_targets\""; } else { $cmd = "add network -netnum 1 -subnet $pnet\/$netmask\/$interface"; } if (! srvctl($run_as_owner, $cmd)) { trace("Failed to add a public network"); print_error(569); return FAILED; } return SUCCESS; } sub configAppClusterNode { trace("Configuring the first node in an application cluster"); upgradeModelResType(); # Add a network configuration as needed if ($CFG->params('APPLICATION_VIP')) { if (FAILED == configPubNetwork()) { trace("Failed to config the public network in an application cluster"); return FAILED; } } my @nodes_to_start; push(@nodes_to_start, $CFG->HOST); if (SUCCESS != configFirstNode(FALSE, \@nodes_to_start)) { print_error(287); return FAILED; } return SUCCESS; } sub startASMListeners { my $crsHome = $_[0]; my @asmLsnrs; my $srvctl; my @out; trace("Activate all ASM listeners configured on the local node"); my $rc = srvctl_capture(FALSE, \@out, "config listener -asmlistener -S 1", $crsHome); if ((0 == $rc) || (2 == $rc)) { foreach my $line (@out) { $line =~ /\s+res_name=\{ora\.(.+)\.lsnr\}\s+lsnr_type=/; push(@asmLsnrs, $1); } trace("Configured ASM listeners: [@asmLsnrs]"); my $run_as_owner = TRUE; my $node = $CFG->HOST; my @output; foreach my $lsnr (@asmLsnrs) { trace("Enable ASM listener $lsnr"); my $srvctl_args = "enable listener -listener $lsnr -node $node"; my $rc = srvctl_capture($run_as_owner, \@output, $srvctl_args); if (!(($rc == 0) || ($rc == 2))) { print_lines(@output); trace("srvctl $srvctl_args failed with status $rc"); die(dieformat(180, "srvctl $srvctl_args")); } trace("Start ASM listener $lsnr"); $srvctl_args = "start listener -listener $lsnr -node $node"; $rc = srvctl_capture($run_as_owner, \@output, $srvctl_args); if (!(($rc == 0) || ($rc == 2))) { print_lines(@output); trace("srvctl $srvctl_args failed with status $rc"); die(dieformat(180, "srvctl $srvctl_args")); } } } else { print_lines(@out); trace("srvctl config listener failed with status $rc"); die(dieformat(180, "srvctl config listener")); } return; } sub EnableASMProxy { my $run_as_owner = TRUE; my $node = $CFG->HOST; my $status = srvctl($run_as_owner, "enable asm -proxy -node $node"); if ($status) { trace("Enable ASM proxy on local node $node ... succeeded"); } else { die(dieformat(372)); } } sub isRHPSConfigured { my $run_as_owner = TRUE; my $is_configured = TRUE; my ($rc, @output); $rc = srvctl_capture($run_as_owner, \@output, 'config rhpserver', shift); if (0 != $rc) { if ((scalar(grep(/PRCR-1001/i, @output)) > 0) || (scalar(grep(/PRKZ-1068/i, @output)) > 0)) { # PRCR-1001 : Resource ora.ghs does not exist # PRKZ-1068 : rhpserver object is not supported on Windows $is_configured = FALSE; } else { print_lines(@output); my $srvctlbin = crs_exec_path('srvctl'); my $cmd = "${srvctlbin} config rhpserver"; trace (" \"$cmd\" failed with status $rc, output: @output"); die(dieformat(180, $cmd)); } } trace("isRHPSConfigured: $is_configured"); return $is_configured; } sub stopRHP { my $run_as_owner = FALSE; my $success = TRUE; unless (srvctl($run_as_owner, 'stop rhpserver', shift)) { print_error(600); $success = FALSE; } return $success; } sub exportRHPRepos { my $user = $CFG->params('ORACLE_OWNER'); my $old_home = $CFG->oldconfig('ORA_CRS_HOME'); my $rhprepos = catfile($CFG->ORA_CRS_HOME, 'bin', 'rhprepos'); my $cmd = "$rhprepos export -crshome $old_home"; my $success = TRUE; my @output; my $rc = run_as_user2($user, \@output, $cmd); if (0 != $rc) { print_trace_lines(@output); print_error(601); $success = FALSE; } return $success; } sub getNatAddressForNode { my $node_name = shift; my $opc_nat_addresses = $CFG->params('OPC_NAT_ADDRESS'); my $node_address = FALSE; foreach my $opc_nat_address (split(',', $opc_nat_addresses)) { my @opc_node_info = split(':', $opc_nat_address); my $opc_node_name = $opc_node_info[0]; my $opc_node_address = $opc_node_info[1]; if (lc($opc_node_name) eq lc($node_name)) { $node_address = $opc_node_address; last; } } return $node_address; } #------------------------------------------------------------------------------- # Function: Get the crskeytoolctl executable file path # # Args : None # # Returns : crskeytoolctl path #------------------------------------------------------------------------------- sub get_crskeytoolctl_path { my $crskeytoolctl = "crskeytoolctl"; my $platform = s_get_platform_family(); if ($platform eq 'windows') { $crskeytoolctl = "crskeytoolctl.bat"; } my $execPath = catfile($CFG->ORA_CRS_HOME, 'bin', $crskeytoolctl); if ( !( -x "${execPath}" ) ) { trace("The file ${execPath} either does not exist or is not executable"); } return $execPath; } sub generate_rootcert #------------------------------------------------------------------------------- # Function: Generate the cluster root certificate, a self-signed X.509 v3 # certificate, and store it into the OCR-CREDSTORE module under # 'SYSTEM.credentials.domains.root.rootcert' domain as a KEYPAIR type # entry identified with the cluster GUID. # This certificate is used to support TLS protocol. In 12.2, QOS and # RHP use it to support RMI over TLS. # Args : none # Returns : SUCCESS if a cluster root certificate was generated and stored # into the OCR-CREDSTORE module; FAILED otherwise. #------------------------------------------------------------------------------- { my $rc = FAILED; my $user = $CFG->params('ORACLE_OWNER'); my $crskeytoolctl = get_crskeytoolctl_path(); my $cmd = "$crskeytoolctl -genrootkey"; my @out; my $rf = run_as_user2($user, \@out, $cmd); if ($rf == 0) { trace("root certificate generated."); $rc = SUCCESS; } else { trace("error generating root certificate: " . join("\n", $rf, @out)); print_lines(@out); } return $rc; } sub add_rhpserver #--------------------------------------------------------- #FUNCTION : Configure RHP Server on Domanin Service Cluster #Args : None #Returns : SUCCESS or Die for FAILED #-------------------------------------------------------- { my $run_as_owner = FALSE; my $dgName; if ($CFG->params('CDATA_BACKUP_DISK_GROUP')) { $dgName = $CFG->params('CDATA_BACKUP_DISK_GROUP'); } else { $dgName = $CFG->params('CDATA_DISK_GROUP'); } my $cmd = "add rhpserver -diskgroup $dgName -storage /mnt/oracle/rhpimages -force"; my @output = (); my $status = srvctl_capture($run_as_owner, \@output, $cmd); trace("rc=$status"); if (($status != 0) && ($status != 2)) { print_lines(@output); die(dieformat(180, "srvctl $cmd")); } else { trace("srvctl $cmd succeeded"); } return SUCCESS; } sub add_rhpclient #--------------------------------------------------------- #FUNCTION : Configure RHP Client #Args : None #Returns : SUCCESS or Die for FAILED #-------------------------------------------------------- { my $run_as_owner = FALSE; my $manifest_file = $CFG->params('GIMR_CREDENTIALS'); my $cmd = "add rhpclient -clientdata $manifest_file"; my @output = (); my $status = srvctl_capture($run_as_owner, \@output, $cmd); trace("rc=$status"); if (($status == 0) || ($status == 2)) { trace("srvctl $cmd succeeded"); return SUCCESS; } elsif (scalar(grep(/PRCG-1060/, @output)) > 0) { trace("The provided credential file $manifest_file does not have the ". "RHP data"); return FAILED; } else { print_lines(@output); die(dieformat(180, "srvctl $cmd")); } } sub start_rhpclient #--------------------------------------------------------- #FUNCTION : Start RHP Client #Args : None #Returns : SUCCESS or FAILED #-------------------------------------------------------- { my $run_as_owner = FALSE; my $cmd = "start rhpclient"; my @output = (); my $status = srvctl_capture($run_as_owner, \@output, $cmd); trace("rc=$status"); if (($status != 0) && ($status != 2)) { trace(@output); trace("srvctl $cmd failed"); return FAILED; } else { trace("srvctl $cmd succeeded"); return SUCCESS; } } 1;