# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # # NAME # s_crsutils.pm # # DESCRIPTION # This module contains common OSD functions for root scripts # # NOTES # # # MODIFIED (MM/DD/YY) # xyuan 10/31/16 - Backport xyuan_bug-24692493 from main # xyuan 10/17/16 - Fix bug 24692493 # xyuan 09/30/16 - Fix bug 24656800 # rdasari 08/12/16 - make haip unsupported on all Exadata # luoli 08/10/16 - XbranchMerge luoli_bug-24296972 from main # muhe 07/25/16 - Fix bug 24322465 # luoli 07/25/16 - Fix bug 24296972 # muhe 06/21/16 - Fix bug 23568289 # xyuan 05/04/16 - Fix bug 23227845 # xyuan 04/21/16 - ODA Lite/SIP/IaaS # bbeelamk 04/13/16 - Fix bug 23095140 # luoli 03/04/16 - Fix bug 22810833 # muhe 12/23/15 - Fix bug 22454227 # ptarikop 11/23/15 - bug 21804085:export module s_isSUSELinux # xyuan 11/18/15 - Fix bug 22223328 # xyuan 10/14/15 - Fix bug 21150477 # csivanan 08/13/15 - bug/17315733 # shullur 06/26/15 - For CHM migration modules to new rootscript changes # xyuan 05/07/15 - Fix bug 20389713 # xyuan 05/04/15 - Fix bug 21023562 # bbeelamk 04/14/15 - Fix bug 20874539 # rsreekum 03/01/15 - Fix for Bug 19343551 - OEL7. Disable few exit fatal # upon error cases for dev env # muhe 02/04/15 - Fix bug 20388247 # jmarcias 01/30/15 - Fix bug 20441873 # luoli 12/30/14 - rsc modeling for downgrade/deconfig # sbezawad 12/23/14 - Bug 20019354: Migrate OCR and OLR to new framework # luoli 11/13/14 - Fix bug 19955755 # rdasari 10/21/14 - rsc modeling # muhe 10/14/14 - Fix bug 19513650 # tthathac 10/02/14 - Bug : 19680763 # ssprasad 09/29/14 - AFD SLES: call install_initd for AFD init script # luoli 09/03/14 - Fix bug 19513351 # xyuan 06/03/14 - Remove the use of message 47 because it no longer # exists at all # xyuan 05/15/14 - Fix bug 18415237 # xyuan 05/08/14 - Fix bug 18370031 - support OL7 # xyuan 03/25/14 - Fix lrg problem 11555703 # muhe 03/11/14 - Fix bug 18373231 # ssprasad 03/11/14 - Move s_update_afd_conf to oraafd.pm # ssprasad 02/21/14 - Move s_update_afd_conf to oraafd.pm:installAFDriver # xyuan 02/18/14 - Fix bug 18233693 # ssprasad 01/15/14 - Handle SLES in s_copy_afdinit_init() # ssprasad 01/09/14 - Add s_update_afd_conf # shiyer 12/16/13 - #17953942:s_crsconfig__env.txt privs # xyuan 10/16/13 - Fix bug 17608793 # siyarlag 10/09/13 - export s_is_Exadata # shiyer 09/05/13 - #17301761:limits in s_createConfigEnvFile # minzhu 08/23/13 - No HAIP if Exadata with solaris 511 # xyuan 08/22/13 - Remove compilation warnings # shmubeen 07/30/13 - Write asm_diskstring to afd.conf # xyuan 07/29/13 - Return FALSE on failure in sub s_copyOCRLoc # shmubeen 07/08/13 - remove afd if it exists. # xyuan 06/30/13 - Fix bug 16989919. # shullur 06/13/13 - For fixing bug 16055418 # xyuan 04/25/13 - Fix bug 16636361 # xyuan 04/09/13 - Add s_restoreocrloc and s_backupocrloc # xyuan 03/10/13 - Fix bug 16086210 # xyuan 03/01/13 - Changes as part of fix for bug 16274133 # sidshank 11/15/12 - fix bug 15843792 # sidshank 11/11/12 - fix bug 14202806 # gmaldona 10/25/12 - XbranchMerge gmaldona_bug-14492893 from # st_has_12.1plbeta2_gen # minzhu 09/07/12 - add an env-var: SUPPORT_HAIP # jmunozn 08/23/12 - Remove s_run_as_user3 and add s_get_qosctl_path # gmaldona 08/23/12 - create temporary file in OS TEMP directory # ssprasad 07/23/12 - Skip oka files in s_set_ownergroup if they # don't exist. # rdasari 07/20/12 - fix bug 14340774 # shmubeen 07/18/12 - add routines for AFD installation # sidshank 07/06/12 - fix 14283643 . # nkorehis 06/20/12 - redo fix for bug-12610689 # sidshank 05/03/12 - remove s_redirect/restore output subroutines # xyuan 03/09/12 - Fix bug 13827767 # sidshank 03/08/12 - Remove dummy routine s_first_node_tasks # nkorehis 03/01/12 - bug-12610689: # anjiwaji 02/15/12 - Skip acfs files in s_set_onwnergroup if they don't # exist. # xyuan 02/02/12 - Modified s_restoreolrloc & s_checkolrbackup # xesquive 01/24/12 - Function s_isSUSELinux verifies if is Linux OS # gmaldona 01/16/12 - add a method with bidirectional communication # xyuan 01/08/12 - Add OSD functions for downgrade # xyuan 01/05/12 - Export s_install_initd # xyuan 12/25/11 - Use 'crsctl stop crs' for 10.2 & above # in s_stop_OldCrsStack # bmanry 12/16/11 - Bug 13506877: Do not unset ORACLE_BASE. # gnagiah 11/15/11 - Bug 13058611, keepdg deletes the dg in upgarded env # xyuan 08/03/11 - XbranchMerge xyuan_bug-12698968 from # st_has_11.2.0.3.0 # smatpadi 07/14/11 - Bug/12583050:inittab/upstart error message # rdasari 07/06/11 - add EXTSHM=OFF for aix # smatpadi 05/20/11 - Fix OEL6 ade startup issue # dpham 03/28/11 - Creation for 12c # package s_crsutils; use strict; use English; use File::Copy; use File::Path; use File::Find; use File::Basename; use File::Spec::Functions; use File::Temp qw/ tempfile /; use Sys::Hostname; use Carp; use Socket; use Env qw(NLS_LANG); use Env qw(SRVM_TRACE); use Fcntl ':mode'; use POSIX qw(tmpnam); use Cwd; # root script modules use crsutils; # export vars and functions use Exporter; use vars qw(@ISA @EXPORT @EXPORT_OK); @ISA = qw(Exporter); my @exp_func = qw(s_check_SuperUser s_set_ownergroup s_reset_crshome s_reset_crshome1 s_set_perms s_osd_setup s_check_CRSConfig s_get_olr_file s_reset_srvconfig s_register_service s_unregister_service s_check_service s_start_service s_run_as_user s_run_as_user2 s_init_scr s_get_config_key s_isLink s_get_platform_family s_getOldCrsHome s_redirect_souterr s_restore_souterr s_stop_OldCrsStack s_RemoveInitResources s_CleanTempFiles s_setParentDirOwner s_resetParentDirOwner s_checkOracleCM s_ResetVotedisks s_createConfigEnvFile s_isRAC_appropriate s_is92ConfigExists s_configureCvuRpm s_removeCvuRpm s_remove_file s_getAbsLink s_removeGPnPprofile s_update_ohasd_service s_is_HAIP_supported s_is_HAIP_NonFatal s_CheckNetworkConfig s_houseCleaning s_NSCleanUp s_install_initd s_restoreInitScripts s_restoreASMFiles s_get_qosctl_path s_rm_afdinit_init s_rm_afdinit_rclevel s_copy_afdinit_init s_is_Exadata s_SocketFiles_InUse s_getRemoteCrsHome s_verify_PID s_afd_install_initd s_afd_remove_initd s_getFSType s_isSUSELinux s_is_ODA_BMIaaS ); push @EXPORT, @exp_func; my ($ARCHIVE, $INITD, $ENVMT, $NETSTAT, $NETSTAT_SOCKET_OPTIONS); my @ns_dir = ("/var/tmp/.oracle","/tmp/.oracle"); my @ns_files = ("CSS","CRS","EVM","PROC","css","crs","evm","proc", "gipc","OHASD","ohasd","mdnsd"); my $dev_null = "/dev/null"; my $FSSEP = "/"; my $oelNetworkConfig = "/etc/sysconfig/network"; my $suseNetworkConfig = "/etc/sysconfig/network/config"; my $checkNetworkTemp = ".orcl.tmp.$$"; my $checkNetworkSave = ".orcl.$$"; # Linux Upstart definitions and globals my $UPSTART_OHASD_SERVICE = "oracle-ohasd"; my $UPSTART_OHASD_CONF_FILE = "oracle-ohasd.conf"; my $SYSTEMD_OHASD_SERVICE_FILE = "oracle-ohasd.service"; my $RESTORECON = "/sbin/restorecon"; my $UPSTART_USED = -1; my $SYSTEMD_USED = -1; if ($OSNAME eq 'linux') { $INITD = '/etc/init.d'; $ARCHIVE = '/usr/bin/ar'; $ENVMT = '/usr/bin/env'; $NETSTAT = '/bin/netstat'; $NETSTAT_SOCKET_OPTIONS = '-a -A unix'; } elsif ($OSNAME eq 'solaris') { $INITD = '/etc/init.d'; $ARCHIVE = '/usr/ccs/bin/ar'; $ENVMT = '/usr/bin/env'; $NETSTAT = '/usr/bin/netstat'; $NETSTAT_SOCKET_OPTIONS = '-a -f unix'; } elsif ($OSNAME eq 'hpux') { $INITD = '/sbin/init.d'; $ARCHIVE = '/usr/ccs/bin/ar'; $ENVMT = "/bin/env"; $NETSTAT = '/usr/bin/netstat'; $NETSTAT_SOCKET_OPTIONS = '-a -f unix'; } elsif ($OSNAME eq 'aix') { $INITD = '/etc'; $ARCHIVE = '/usr/ccs/bin/ar -X64'; $ENVMT = '/usr/bin/env'; $NETSTAT = '/usr/bin/netstat'; $NETSTAT_SOCKET_OPTIONS = '-a -f unix'; } elsif ($OSNAME eq 'dec_osf') { $INITD = '/sbin/init.d'; $ARCHIVE = '/usr/bin/ar'; $ENVMT = '/usr/bin/env'; } ####--------------------------------------------------------- #### Function for checking and returning Super User name # ARGS : 0 sub s_check_SuperUser { my $superUser = "root"; my $program = "this script"; # get user-name my $usrname = getpwuid ($<); my $uid = getpwnam ($usrname); if (($usrname ne $superUser) || ($uid ne "0")) { trace ("You must be logged in as $superUser with its UID being '0' " . "to run $program."); return ""; } return $superUser; } ####--------------------------------------------------------- #### Function for setting user and group on a specified path # ARGS : 3 # ARG1 : Oracle owner # ARG2 : Oracle group # ARG3 : file sub s_set_ownergroup { my ($owner, $group, $file) = @_; if (!$owner) { print_error(40); return FAILED; } if (!$group) { print_error(41); return FAILED; } if (!$file) { print_error(42); return FAILED; } if (!(-e $file)) { # Skip missing ACFS files if ( $file=~ m/.*acfs.*/ ) { return SUCCESS; } elsif ( $file=~ m/.*oka.*/ ) { # Skip missing OKA files return SUCCESS; } elsif ( $file=~ m/.*afd.*/ ) { return SUCCESS; } else { print_error(46, $file); return FAILED; } } my $uid = getpwnam ($owner); my $gid = getgrnam ($group); if ($CFG->DEBUG) { trace("Setting owner ($owner:$uid) and group ($group:$gid) on file $file"); } if (! chown ($uid, $gid, $file)) { print_error(152, $file); trace ("Can't change ownership of $file: $!"); return FAILED; } return SUCCESS; } ####--------------------------------------------------------- #### Function for resetting owner and permissions of CRS home dirs/files # ARGS : 4 # ARG1 : Oracle owner # ARG2 : Oracle group # ARG3 : perms # ARG4 : directory path sub s_reset_crshome { my ($owner, $group, $perms, $basedir) = @_; my $exclfile = catfile($CFG->ORA_CRS_HOME, 'crs', 'install', 'install.excl'); s_reset_crshome1($owner, $group, $perms, $basedir, $exclfile); } ####--------------------------------------------------------- #### Function for resetting owner and permissions of CRS home dirs/files # ARGS : 5 # ARG1 : Oracle owner # ARG2 : Oracle group # ARG3 : perms # ARG4 : directory path # ARG5 : exclude file path sub s_reset_crshome1 { if (is_dev_env()) { return SUCCESS; } my ($owner, $group, $perms, $basedir, $exclfile) = @_; if (!$owner) { print_error(40); return FAILED; } if (!$group) { print_error(41); return FAILED; } my $userid = getpwnam ($owner); my $groupid = getgrnam ($group); my @excl_dir = (); # Use inner anoymous subs to solve the old warnings: (Variable ... # will not stay shared) my $SetPerms = sub { if (! $CFG->UNLOCK) { return TRUE; } # if UNLOCK, bypass files that are in exclude dir my $setperms = TRUE; foreach my $dir (@excl_dir) { chomp ($dir); next if ($dir =~ /^#|^\s*$/); # skip blanks and comments # do not set perms if file is on execluded dir if ($File::Find::dir =~ /$dir/) { $setperms = FALSE; } } return $setperms; }; my $reset_perms = sub { #Just give write permissions to grid owner for all files #during reset and exclude links . if (! -l $_) { my ($dev,$ino,$mode) = lstat($_); $perms = S_IMODE($mode); my $origperm = sprintf "%04o", $perms; $perms = $perms | 128; my $newperm = sprintf "%04o", $perms; if (&$SetPerms()) { if ($CFG->DEBUG) { trace("orig perm for $_ is $origperm, setting file perm to $newperm"); } chown ($userid, $groupid, $_); chmod (oct ($newperm), $_); } } }; if (-e $exclfile) { @excl_dir = read_file (catfile($exclfile)); } # reset owner/group of directory/file name of basedir # and its parent dir to ORACLE_OWNER/DBA finddepth ($reset_perms, $basedir); my @parent; $parent[0]=dirname($basedir); foreach(@parent) { &$reset_perms; } return SUCCESS; } ####--------------------------------------------------------- #### Function for setting permissions on a specified path # ARGS : 2 # ARG1 : permissions # ARG3 : file/dir sub s_set_perms { my ($perms, $file) = @_; if (!$perms) { print_error(43); return FAILED; } if (!$file) { print_error(42); return FAILED; } if (!(-e $file)) { print_error(46, $file); return FAILED; } if ($CFG->DEBUG) { trace ("Setting permissions ($perms) on file/dir $file"); } if ($CFG->SIHA) { if (is_dev_env()) { if (! chmod (oct($perms), $file)) { print_error(153, $file); trace("Can't change permissions of $file: $!"); return FAILED; } } elsif (! chmod (((oct($perms)) & oct(4770)), $file)) { print_error(153, $file); trace("Can't change permissions of $file: $!"); return FAILED; } } elsif (! chmod (oct($perms), $file)) { print_error(153, $file); trace("Can't change permissions of $file: $!"); return FAILED; } return SUCCESS; } ####--------------------------------------------------------- #### Functions for copying script to init directory # ARGS : 2 # ARG1 : init script name # ARG2 : destination file sub s_copy_to_initdir { my $sourcefile = $_[0]; my $destfile = $_[1]; if (!$sourcefile) { print_error(44); return FAILED; } if (!(-f $sourcefile)) { print_error(45, $sourcefile); return FAILED; } trace ("init file = " . $sourcefile); trace ("Copying file " . $sourcefile . " to " . $CFG->params('ID') . " directory"); copy ($sourcefile, catfile ($CFG->params('ID'), $destfile)) || return FAILED; trace ("Setting " . $destfile . " permission in " . $CFG->params('ID') . " directory"); s_set_perms ("0755", catfile ($CFG->params('ID'), $destfile)) || return FAILED; return SUCCESS; } ####--------------------------------------------------------- #### Functions for copying script to init directory # ARGS : 1 # ARG1 : init script name # ARG1 : dest name sub s_copy_to_rcdirs { my $sourcefile = $_[0]; my $destfile = $_[1]; if (!$sourcefile) { print_error(44); return FAILED; } if (!(-f $sourcefile)) { print_error(45, $sourcefile); return FAILED; } trace ("init file = " . $sourcefile); # Copy to init dir trace ("Copying file " . $sourcefile . " to " . $CFG->params('ID') . " directory"); copy ($sourcefile, catfile ($CFG->params('ID'), $destfile)) || return FAILED; trace ("Setting " . $destfile . " permission in " . $CFG->params('ID') . " directory"); s_set_perms ("0755", catfile ($CFG->params('ID'), $destfile)) || return FAILED; if (s_isSUSELinux()) { # for SUSE Linux, do not create link to the file in the init dir return SUCCESS; } # Create a link to the file in the init dir my @RCSDIRLIST = split (/ /, $CFG->params('RCSDIR')); my $RC_START = $CFG->params('RC_START'); foreach my $rc (@RCSDIRLIST) { trace ("Removing \"" . $rc . "/" . $RC_START . $destfile . "\""); s_remove_file ("$rc/$RC_START$destfile"); trace ("Creating a link \"" . catfile ($rc, "$RC_START$destfile") . "\" pointing to " . catfile ($CFG->params('ID'), $destfile)); symlink (catfile($CFG->params('ID'), $destfile), catfile($rc, "$RC_START$destfile")) || return FAILED; } my @RCKDIRLIST = split (/ /, $CFG->params('RCKDIR')); my $RC_KILL = $CFG->params('RC_KILL'); foreach my $rc (@RCKDIRLIST) { trace ("Removing \"" . $rc . "/" . $RC_KILL . $destfile . "\""); s_remove_file ("$rc/$RC_KILL$destfile"); trace ("Creating a link \"" . catfile ($rc, "$RC_KILL$destfile") . "\" pointing to " . catfile ($CFG->params('ID'), $destfile)); symlink(catfile($CFG->params('ID'), $destfile), catfile($rc, "$RC_KILL$destfile")) || return FAILED; } trace ("The file " . $destfile . " has been successfully linked to the RC directories"); return SUCCESS; } sub s_NSCleanUp { trace ("Cleaning up Network socket directories"); foreach my $nsdir (@ns_dir) { foreach my $file (<$nsdir/*>) { foreach my $ns (@ns_files) { if ($file =~ $ns) { trace("Unlinking file : $file"); unlink($file); } } } } } ####--------------------------------------------------------- #### Functions for removing script from rc directories # ARGS : 1 # ARG1 : init script name sub s_clean_rcdirs { my $file = $_[0]; if (!$file) { print_error(44); trace ("Null value passed for init script file name"); return FAILED; } trace ("Init file = " . $file); trace ("Removing \"" . $file . "\" from RC dirs"); #remove old ones if ($CFG->params('RCALLDIR')) { my ($rc, $rcStartFile, $rcKillFile, $rcKillOldFile, $rcKillOld2File); my @RCALLDIRLIST = split (/ /, $CFG->params('RCALLDIR')); foreach $rc (@RCALLDIRLIST) { if ($CFG->params('RC_START')) { $rcStartFile = catfile ($rc, $CFG->params('RC_START') . $file); s_remove_file ("$rcStartFile"); } if ($CFG->params('RC_KILL')) { $rcKillFile = catfile ($rc, $CFG->params('RC_KILL') . $file); s_remove_file ("$rcKillFile"); } if ($CFG->params('RC_KILL_OLD')) { $rcKillOldFile = catfile ($rc, $CFG->params('RC_KILL_OLD') . $file); s_remove_file ("$rcKillOldFile"); } if ($CFG->defined_param('RC_KILL_OLD2')) { $rcKillOld2File = catfile ($rc, $CFG->params('RC_KILL_OLD2') . $file); s_remove_file ("$rcKillOld2File"); } } } } ####--------------------------------------------------------- #### Function for adding CRS entries to inittab # ARGS : 0 sub s_add_itab { # If upstart is being used, then add the upstart conf file. if (s_is_Linux_Upstart()) { return (s_add_upstart_conf()); } # If systemd is being used, then add the systemd unit file. if (s_is_Linux_Systemd()) { return s_add_systemd_conf(); } my $INITTAB_CH = catfile ($CFG->ORA_CRS_HOME, "crs", "install", "inittab"); if (-e $INITTAB_CH) { my $IT = $CFG->params('IT'); unless (open (ITAB, "<$IT")) { print_error(206, $IT, $!); return FAILED; } unless (open (ITABNOCRS, ">$IT.no_crs")) { print_error(207, "$IT.no_crs", $!); return FAILED; } # Remove init.ohasd entry and all empty lines prior to it from inittab my $itLines = join("", ); $itLines =~ s{\n*([^\n]+)init\.ohasd.+\n}{\n}g; # Remove multiple empty lines prior to init.tfa entry my $tfaline; if ($itLines =~ /\n(.+init\.tfa.+)\n/) { $tfaline = $1; } $itLines =~ s{\n*([^\n]+)init\.tfa.+\n}{\n\n$tfaline}g; print ITABNOCRS $itLines; close (ITABNOCRS); close (ITAB); trace("Created backup $IT.no_crs"); unless (copy ("$IT.no_crs", "$IT.tmp")) { print_error(105, "$IT.no_crs", "$IT.tmp", $!); return FAILED; } unless (open (CRSITAB, "<$INITTAB_CH")) { print_error(206, $INITTAB_CH, $!); return FAILED; } unless (open (ITABTMP, ">>$IT.tmp")) { print_error(208, "$IT.tmp", $!); return FAILED; } print ITABTMP "\n"; trace ("Appending to $IT.tmp:"); while () { print ITABTMP "$_"; trace ("$_"); } close (ITABTMP); close (CRSITAB); trace ("Done updating $IT.tmp"); unless (copy ("$IT.tmp", "$IT.crs")) { print_error(105, "$IT.tmp", "$IT.crs", $!); return FAILED; } trace("Saved $IT.crs"); unless (move ("$IT.tmp", $IT)) { print_error(209, "$IT.tmp", $IT, $!); return FAILED; } trace("Installed new $IT"); } else { print_error(13, $INITTAB_CH); return FAILED; } return SUCCESS; } ####--------------------------------------------------------- #### Function for removing CRS entries from inittab # ARGS : 1 - match pattern for inittab entries sub s_remove_itab { my $match_pattern = $_[0]; my $IT = $CFG->params('IT'); trace ("itab entries=$match_pattern"); # If upstart is being used, then remove the conf files if (s_is_Linux_Upstart()) { return (s_remove_upstart_conf($match_pattern)); } # If systemd is being used, then remove the systemd unit files. if (s_is_Linux_Systemd()) { return s_remove_systemd_conf($match_pattern); } unless (open (ITAB, "<$IT")) { print_error(206, $IT, $!); return FAILED; } unless (open (ITABTMP, ">$IT.tmp")) { print_error(207, $IT, $!); return FAILED; } trace("Remove init.$match_pattern from $IT"); my $itLines = join("", ); $itLines =~ s{\n*([^\n]+)init\.($match_pattern).*\n}{\n}g; print ITABTMP $itLines; close (ITABTMP); close (ITAB); unless (copy ("$IT.tmp", "$IT.no_crs")) { print_error(105, "$IT.tmp", "$IT.no_crs", $!); return FAILED; } trace("Move $IT.tmp to $IT"); unless (move ("$IT.tmp", $IT)) { print_error(209, "$IT.tmp", $IT, $!); return FAILED; } return SUCCESS; } ####----------------------------------------------------------------------- #### Function for checking if CRS is already configured # ARGS: 2 # ARG1: hostname # ARG2: crs user sub s_check_CRSConfig { my $hostname = $_[0]; my $crsuser = $_[1]; my $FATALFILE = catfile($CFG->params('SCRBASE'), $hostname, $crsuser, "cssfatal"); if ((-f $FATALFILE) && (-f $CFG->params('OCRCONFIG'))) { trace ("Oracle CRS stack is already configured and will be " . "running under init \(1M\)"); return TRUE; } else { trace ("Oracle CRS stack is not configured yet"); return FALSE; } } sub s_get_olr_file #------------------------------------------------------------------------------- # Function: Get key from olr.loc # Args : 1 - key # Returns : Key's value #------------------------------------------------------------------------------- { my $key = $_[0]; my $ret = ""; my $OLRCONFIG = $CFG->params('OLRCONFIG'); if (!(-r $OLRCONFIG)) { # Don't show up a NLS error message here because we also # call this function when upgrade from 10.2, and the $OLRCONFIG is # not there in this scenario. trace ("Either " . $OLRCONFIG . " does not exist or is not readable"); trace ("Make sure the file exists and it has read and execute access"); return $ret; } open (OLRCFGFILE, "<$OLRCONFIG") || return $ret; while () { if (/^$key=(\S+)/) { $ret = $1; last; } } close (OLRCFGFILE); return $ret; } ####--------------------------------------------------------- #### Function for registering daemon/service with init # ARGS: 1 # ARG1: daemon to be registered sub s_register_service { my $srv = $_[0]; # Setup init scripts my $INITDIR = catfile ($CFG->params('ORACLE_HOME'), "crs", "init"); my $INITDIR_INITSRV; my $INITDIR_SRV; #if SUSE linux, copy the ohasd.sles to the rcdirs if (! s_isSUSELinux()) { $INITDIR_SRV = catfile ($INITDIR, $srv); $INITDIR_INITSRV = catfile ($INITDIR, "init.$srv"); } else { $INITDIR_SRV = catfile ($INITDIR, "$srv.sles"); $INITDIR_INITSRV = catfile ($INITDIR, "init.$srv.sles"); } s_copy_to_initdir($INITDIR_INITSRV, "init.$srv") || return FAILED; s_copy_to_rcdirs ($INITDIR_SRV, $srv) || return FAILED; return SUCCESS; } #### Function for starting daemon/service # ARGS: 3 # ARG1: daemon to be started # ARG2: user under whom daemon/service needs to be started sub s_start_service { my $srv = $_[0]; my $user = $_[1]; my $crsctl = crs_exec_path('crsctl'); my ($status, $grep_val); my @output; my @cmdout; # Check to see if the service is OHASD if (($srv eq "ohasd") || ($srv eq "crsexcl")) { # Create the autorun file and its directory my $dir = catdir ($CFG->params('SCRBASE'), $CFG->HOST, $CFG->HAS_USER); create_dir($dir); my $AUTORUNFILE = catfile ($dir, "ohasdrun"); open (AUTORUN, ">$AUTORUNFILE") || die(dieformat(207, $AUTORUNFILE, $!)); print AUTORUN "stop\n"; close (AUTORUN); s_set_ownergroup($CFG->HAS_USER, $CFG->HAS_GROUP, $AUTORUNFILE) || die(dieformat(152, $AUTORUNFILE)); s_set_perms ("0644", $AUTORUNFILE) || die(dieformat(153, $AUTORUNFILE)); my $INIT_FILE; if (s_is_Linux_Upstart()) { trace("This is a Linux Upstart environment"); $INIT_FILE = "$UPSTART_OHASD_CONF_FILE"; } elsif (s_is_Linux_Systemd()) { trace("This is a Linux Systemd environment"); $INIT_FILE = "$SYSTEMD_OHASD_SERVICE_FILE"; } else { trace("This is a Linux SysVinit environment"); $INIT_FILE = $CFG->params('IT'); } trace("INIT file: $INIT_FILE"); # Add OHASD to inittab/upstart/systemd if ($CFG->DOWNGRADE) { print_error(328, $INIT_FILE); } elsif($CFG->UPGRADE) { print_error(329, $INIT_FILE); } else { print_error(330, $INIT_FILE); } s_remove_itab ("cssd|evmd|crsd|ohasd") || return FAILED; if ((! s_is_Linux_Upstart()) && (! s_is_Linux_Systemd())) { $status = system ($CFG->params('INIT') . " q"); if (0 != $status) { print_error(213, $INIT_FILE, $!); return FAILED; } } sleep (5); s_add_itab() || return FAILED; if (s_is_Linux_Upstart()) { my $INITCTL = $CFG->params('INITCTL'); ($status, @output) = system_cmd_capture("$INITCTL start $UPSTART_OHASD_SERVICE"); if (0 != $status) { # Failed to start $UPSTART_OHASD_SERVICE print_error(213, $INIT_FILE, $!); return FAILED; } } elsif (s_is_Linux_Systemd()) { if (FAILED == s_systemctl_start_service($SYSTEMD_OHASD_SERVICE_FILE)) { print_error(213, $INIT_FILE, $!); # OEL7 specific for devenv. Bug 19343551. do not abort fatal for dev env return FAILED if (! is_dev_env()); } } else { $status = system ($CFG->params('INIT') . " q"); if (0 != $status) { print_error(213, $INIT_FILE, $!); return FAILED; } } if ($srv eq "ohasd") { # Start OHASD $grep_val = "4640"; @output = system_cmd_capture ($crsctl, 'start', 'has'); $status = shift @output; # call $CFG->params('ID')/ohasd install (bug 9133502) if (! is_dev_env()) { my @cmd = (catfile($CFG->params('ID'), 'ohasd'), 'install'); system (@cmd); } } else { # Start CRS if it's crsexcl @output = system_cmd_capture ($crsctl, 'start', 'crs', '-excl'); $status = shift @output; } } else { my $SRVBIN = catfile ($CFG->params('ORACLE_HOME'), "bin", $srv); $status = s_run_as_user ("$SRVBIN &", $user); } if ($grep_val) { @cmdout = grep(/$grep_val/, @output); } # for OHASD if (0 == $status) { trace ("$srv is starting"); } elsif ($grep_val && scalar(@cmdout) > 0) { trace("$srv is already active"); } else { print_error(214, $srv); trace ("$srv failed to start"); my $host = tolower_host(); my $alertlog = catfile ($CFG->params('ORACLE_HOME'), 'log', $host, "alert${host}.log"); trace ("Alert log is $alertlog"); print "Failed to start the Clusterware. Last 20 lines of the alert " . "log follow: \n"; if (-e $alertlog) { open(ALERTLOG, "< $alertlog"); my @lines = reverse ; my @reversed_lines = reverse(@lines[0..19]); my $line; foreach $line (@reversed_lines) { print $line; } } print "\n"; return FAILED; } return SUCCESS; } ####--------------------------------------------------------- #### Function for updating the OHASD service file # Args: none # Returns: SUCCESS or FAILED sub s_update_ohasd_service { my $status; my @output; my $INIT_FILE; if (s_is_Linux_Upstart()) { trace("This is a Linux Upstart environment"); $INIT_FILE = "$UPSTART_OHASD_CONF_FILE"; } elsif (s_is_Linux_Systemd()) { trace("This is a Linux Systemd environment"); $INIT_FILE = "$SYSTEMD_OHASD_SERVICE_FILE"; } else { trace("This is a Linux SysVinit environment"); $INIT_FILE = $CFG->params('IT'); } trace("INIT file: $INIT_FILE"); print_info(329, $INIT_FILE); s_remove_itab ("ohasd") || return FAILED; if ((! s_is_Linux_Upstart()) && (! s_is_Linux_Systemd())) { $status = system ($CFG->params('INIT') . " q"); if (0 != $status) { print_error(213, $INIT_FILE, $!); return FAILED; } sleep(5); } s_add_itab() || return FAILED; if (s_is_Linux_Upstart()) { my $INITCTL = $CFG->params('INITCTL'); ($status, @output) = system_cmd_capture("$INITCTL start $UPSTART_OHASD_SERVICE"); if (0 != $status) { print_error(213, $INIT_FILE, $!); return FAILED; } } elsif (s_is_Linux_Systemd()) { if (FAILED == s_systemctl_start_service($SYSTEMD_OHASD_SERVICE_FILE)) { print_error(213, $INIT_FILE, $!); return FAILED if (! is_dev_env()); } } else { $status = system ($CFG->params('INIT') . " q"); if (0 != $status) { print_error(213, $INIT_FILE, $!); return FAILED; } } return SUCCESS; } ####--------------------------------------------------------- #### Function for checking daemon # ARGS: 2 # ARG1: daemon to be checked # ARG2: is daemon running? sub s_check_service { my ($srv, $isRunning) = @_; if (($srv eq "ohasd") && ($isRunning) && (-e $CFG->params('SCRBASE'))) { my $AUTOSTARTFILE = catfile($CFG->params('SCRBASE'), $CFG->HOST, $CFG->HAS_USER, "ohasdstr"); open (AUTOSTART, ">$AUTOSTARTFILE") || die(dieformat(207, $AUTOSTARTFILE, $!)); print AUTOSTART "enable\n"; close (AUTOSTART); s_set_ownergroup ($CFG->HAS_USER, $CFG->HAS_GROUP, $AUTOSTARTFILE) || die(dieformat(152, $AUTOSTARTFILE)); s_set_perms ("0644", $AUTOSTARTFILE) || die(dieformat(153, $AUTOSTARTFILE)); } } ####--------------------------------------------------------- #### Function for initializing SCR settings # Note: this function will be a no-op on NT # ARGS: 0 sub s_init_scr { my $crsctl = crs_exec_path('crsctl'); my $status = system($crsctl, 'create', 'scr', $CFG->params('ORACLE_OWNER')); if (0 != $status) { print_error(331, catfile($CFG->params('SCRBASE'), $CFG->HOST)); exit 1; } } ####--------------------------------------------------------- #### Function for resolving output captured from s_run_as_user2 # ARGS: 1 # ARG1: An array of output lines sub s_resolveCapout { my @capout = @_; if ( scalar(grep(/CLSRSC_START/, @capout)) == 1 ) { my $capout_string = join("", @capout); if ( $capout_string =~ /CLSRSC_START(.*)/s ) { my $realoutput_string = $1; @capout = (); @capout = split(//, $realoutput_string); shift @capout; } } return @capout; } ####--------------------------------------------------------- #### Function for running a command as given user # ARGS: 2 # ARG1: cmd to be executed # ARG2: user name sub s_run_as_user { my $user = $_[1]; my $cmd; if ($user) { my $SU = "/bin/su"; $cmd = "$SU $user -c \"$_[0]\""; trace (" Invoking \"$_[0]\" as user \"$user\""); } else { $cmd = $_[0]; trace (" Invoking \"$_[0]\""); } return system_cmd($cmd); } ####--------------------------------------------------------- #### Function for running a command as given user, returning back #### stdout/stderra output # ARGS: 3 # ARG1: ref to cmdlist argv list to be executed # ARG2: user name, can be undef # ARG3: ref to resulting array of stderr/out, can be undef sub s_run_as_user2 { my $cmdlistref = $_[0]; my $user = $_[1]; my $capoutref = $_[2]; my $rc = -1; my $SU = "/bin/su"; my @cmdlist; # cmd expression: echo CLSRSC_START; unshift(@$cmdlistref, "echo CLSRSC_START;"); if ($user) { @cmdlist = ( $SU, $user, '-c \'', @{$cmdlistref}, '\'' ); } else { @cmdlist = @{$cmdlistref}; } my $cmd = join( ' ', @cmdlist ); # capture stdout/stderr, if requested if (defined($capoutref)) { @{$capoutref} = (); my $cmdout; (undef, $cmdout) = tempfile(); trace ("s_run_as_user2: Running $cmd"); my @tmp_capout = (); # system() with stdout/stderr capture. # Note that this is a portable notation in perl # see http://perldoc.perl.org/perlfaq8.html # see also # http://www.perlmonks.org/?node_id=597613 open (CMDEXE, "$cmd 2>&1 |" ) or die(dieformat(180, $cmd, $!)); open (CMDOUT, ">>$cmdout" ) or die(dieformat(208, $cmdout, $!)); while () { push(@tmp_capout, $_); print CMDOUT $_; } @{$capoutref} = s_resolveCapout(@tmp_capout); close (CMDEXE); # to get $? $rc = $?; close (CMDOUT); s_remove_file ("$cmdout"); trace("pipe exit code: $rc"); if ($rc == 0) { trace ("$cmdlist[0] successfully executed\n"); } elsif ($rc == -1) { trace ("$cmdlist[0] failed to execute\n"); } elsif ($rc & 127) { my $sig = $rc & 127; my $core = ($rc & 128) ? 'with' : 'without'; trace ("$cmdlist[0] died with signal $sig, $core coredump\n"); } else { $rc = $rc >> 8; trace ("$cmdlist[0] exited with rc=$rc\n"); } } else # regular system() call { $rc = s_run_as_user( $cmd, $user ); } return $rc; } ####--------------------------------------------------------- #### Function for getting value corresponding to a key in ocr.loc or olr.loc # ARGS: 2 # ARG1: ocr/olr # ARG2: key sub s_get_config_key { my $src = $_[0]; my $key = $_[1]; $src =~ tr/a-z/A-Z/; my ($val, $cfgfile); if ($src eq 'OCR') { $cfgfile = $CFG->params('OCRCONFIG'); } elsif ($src eq 'OLR') { $cfgfile = $CFG->params('OLRCONFIG'); } elsif ($src eq 'SRV') { $cfgfile = $CFG->params('SRVCONFIG'); } # open OCRCONFIG/OLRCONFIG/SRVCONFIG as appropriate trace("Opening file $cfgfile"); open (CFGFL, "<$cfgfile") or return $val; while () { if (/^$key=(\S+)/) { $val = $1; last; } } close (CFGFL); trace("Value ($val) is set for key=$key"); return $val; } ####--------------------------------------------------------- #### Function for getting platform family # ARGS: 0 sub s_get_platform_family { return "unix"; } ####--------------------------------------------------------- #### Function for checking if a path is a symlink, and if so, return the #### target path # ARGS: 1 # ARG1: file/dir path sub s_isLink { my $path = $_[0]; my $target = ""; if (-l $path) { $target = readlink ($path) or die(dieformat(323, $!)); } return $target; } ####--------------------------------------------------------- #### Function for getting the old CRS Home # ARGS: 0 sub s_getOldCrsHome { my ($oldHome, $Name); my $CRS_HOME_ENV = "ORA_CRS_HOME"; my $INITD = s_getInitd(); my $OLD_INIT_CSSD = catfile ($INITD, "init.cssd"); open(FOHM, $OLD_INIT_CSSD) || die(dieformat(324)); my @buffer = grep(/$CRS_HOME_ENV/, ()); close FOHM; chomp @buffer; if (scalar(@buffer) != 0) { ($Name, $oldHome) = split(/=/, $buffer[0]); } return $oldHome; } ####--------------------------------------------------------- ##### Function for getting the CRS Home of remote node ## ARGS : [0] remote node name sub s_getRemoteCrsHome { my $remoteNode = $_[0]; my $localNode = tolower_host(); my $remoteCrsHome; my $sourceLoc; my $crshome = $CFG->ORA_CRS_HOME; # Fix bug 24296972 # LRG uses 'olr.loc.hostname' while shiphome uses olr.loc as OLRCONFIG if (is_dev_env()) { my $remote_olr_loc = "olr.loc." . $remoteNode; $sourceLoc = catfile($CFG->params('OLRCONFIGDIR'),$remote_olr_loc); } else { $sourceLoc = $CFG->params('OLRCONFIG'); } my $fnameTemplate = $remoteNode.'_XXXX'; my ($fh, $destLoc) = tempfile($fnameTemplate, SUFFIX => '.loc', DIR => File::Spec->tmpdir() ); close($fh); s_set_ownergroup($CFG->params('ORACLE_OWNER'), $CFG->params('ORA_DBA_GROUP'), $destLoc) or die(dieformat(152, $destLoc)); s_set_perms("0750", $destLoc) or die(dieformat(153, $destLoc)); trace("Start to copy $sourceLoc from $remoteNode to ". "$destLoc of $localNode"); my @program = ('-copy', '-sourcefile', $sourceLoc, '-sourcenode', $remoteNode, '-destfile', $destLoc, '-nodelist', $localNode); my $args_str = join(' ', @program); my $run_as_user = TRUE; my ($rc , @capout) = cluutil($run_as_user, $args_str, $crshome); trace(@capout); if (0 != $rc) { trace("\"cluutil $args_str\" failed with status $rc"); print_lines(@capout); trace("Fail to copy $sourceLoc from $remoteNode to $localNode $destLoc"); die(dieformat(180, "cluutil $args_str", $rc)); } else { trace("Successfully copy $sourceLoc from $remoteNode to ". "$localNode $destLoc"); } my @filecontent = read_file ($destLoc); foreach my $line (@filecontent) { # skip blanks and comments if ($line !~ /^#|^\s*$/) { if ($line =~ /crs_home=(.+)/) { $remoteCrsHome = $1; trace("The CRS home of node: $remoteNode is $remoteCrsHome."); last; } } } trace("Remove $destLoc"); s_remove_file("$destLoc"); return $remoteCrsHome; } ####--------------------------------------------------------- #### Function for stopping the services from OldCrsHome # ARGS: 1 sub s_stop_OldCrsStack { my $old_crshome = $_[0]; my @old_version = @{$CFG->oldconfig('ORA_CRS_VERSION')}; my @output; my $status; if ($old_version[0] eq "10" && $old_version[1] eq "1") { my $initd = s_getInitd(); my $old_init_crs = catfile ($initd, "init.crs"); @output = system_cmd_capture($old_init_crs, 'stop'); $status = shift @output; trace ("status=$status"); } else { my $crsctl = catfile($old_crshome, 'bin', 'crsctl'); @output = system_cmd_capture($crsctl, 'stop', 'crs'); $status = shift @output; trace("status=$status"); } return $status; } ####--------------------------------------------------------- #### Function for getting the Initd locations # ARGS: 0 sub s_getInitd { return $INITD; } sub s_RemoveInitResources #------------------------------------------------------------------------------- # Function: Removing init resources # Args : 0 #------------------------------------------------------------------------------- { trace ("Remove init resources"); my @crs_init_scripts = ('init.evmd', 'init.crsd', 'init.cssd', 'init.crs', 'init.ohasd'); s_remove_itab ("cssd|evmd|crsd|ohasd"); if ((! s_is_Linux_Upstart()) && (! s_is_Linux_Systemd())) { system ($CFG->params('INIT') . " q"); sleep (5); } trace ("Removing script for Oracle Cluster Ready services"); my ($file, $serv); foreach $serv (@crs_init_scripts) { trace ("Removing " . $CFG->params('ID') . "/$serv file"); $file = catfile($CFG->params('ID'),$serv); s_remove_file ("$file"); } s_clean_rcdirs ("ohasd"); s_clean_rcdirs ("init.crs"); } sub s_setParentDirOwner #------------------------------------------------------------------------------- # Function: Set $current_dir and its parent directories to $owner/DBA # Args : [0] Owner # [1] Directory #------------------------------------------------------------------------------- { my $current_owner = $_[0]; my $current_dir = $_[1]; my $dir = dirname($current_dir); if ((-c $current_dir) || (-b $current_dir)) { trace("The '$dir' is parent directory of a character/block device. " ."Skip the action ..."); return; } #Save the existing ACLs for parent dir trace("saving current owner/permisssios of parent dir of $dir\n"); s_saveParentDirinfo($dir); while ($dir ne "/" && $dir ne ".") { s_set_ownergroup($current_owner, $CFG->params('ORA_DBA_GROUP'), $dir) || die(dieformat(152, $dir)); s_set_perms ("0755", $dir); $dir = dirname($dir); } } sub s_resetParentDirOwner #------------------------------------------------------------------------------- # Function: Set $current_dir and its parent directories to $owner/DBA # Args : [0] Directory #------------------------------------------------------------------------------- { my $current_dir = $_[0]; my $dir = dirname($current_dir); my $savepermfile = catfile ($CFG->ORA_CRS_HOME, "crs", "install", "ParentDirPerm_" . $CFG->HOST . ".txt"); if (-e $savepermfile) { trace("reset ACLs of parent dir of grid home\n"); my ($fname, $fuser, $fgroup, $fperm); open (PFILE, $savepermfile) || print_error(215, $savepermfile, $!); while() { ($fname, $fuser, $fgroup, $fperm) = split(/:/, $_); trace("Got $fname:$fuser:$fgroup:$fperm from $savepermfile"); s_set_ownergroup ($fuser, $fgroup, $fname); s_reset_perms ($fperm, $fname); } close (PFILE); s_remove_file($savepermfile); } } ####--------------------------------------------------------- #### Function for resetting permissions on a specified path #### to the input permissions value. # ARGS : 2 # ARG1 : permissions # ARG3 : file/dir sub s_reset_perms { my ($perms, $file) = @_; if (!$perms) { print_error(43); return FAILED; } if (!$file) { print_error(42); return FAILED; } if (!(-e $file)) { print_error(46, $file); return "FAILED"; } if ($CFG->DEBUG) { trace ("Setting permissions ($perms) on file/dir $file"); } if (! chmod (oct($perms), $file)) { print_error(153, $file); trace("Can't change permissions of $file: $!"); return FAILED; } return SUCCESS; } sub s_ResetVotedisks #------------------------------------------------------------------------------- # Function: Reset voting disks # Args : [0] list of voting disks #------------------------------------------------------------------------------- { trace ("Reset voting disks"); my @votedisk_list = @_; foreach my $vdisk (@votedisk_list) { if (-f $vdisk) { trace("Removing voting disk: $vdisk"); s_remove_file ("$vdisk"); } elsif (! isOCRonASM()) { trace ("Removing contents from voting disk: $vdisk"); my $bin_dd = "/bin/dd"; system ("$bin_dd if=/dev/zero skip=25 bs=4k count=2560 of=$vdisk > $dev_null"); } } } #----------------------------------------------------------------------------- # Function: Check if socket files are still in use # Args : Socket files directory # Returns : Two boolean values: $error & $InUse #----------------------------------------------------------------------------- sub s_SocketFiles_InUse { my ($error, $InUse); my @cmd = ($NETSTAT, $NETSTAT_SOCKET_OPTIONS); my ($rc, @output) = system_cmd_capture_noprint(@cmd); $error = ($rc != 0); if ($error) { trace("Failed to execute the command \"@cmd\" (rc=$rc), ". "with the message:\n".join("\n", @output)."\n"); $InUse = FALSE; } else { $InUse = scalar( grep(/@_/, @output) ) > 0; } return ($error,$InUse); } sub s_CleanTempFiles #------------------------------------------------------------------------------- # Function: Remove misc files and directories # Args : none #------------------------------------------------------------------------------- { my ($dir, $file, $error, $inUse); # call $CFG->params('ID')/ohasd deinstall (bug 9133502) if (! is_dev_env()) { my @cmd = (catfile($CFG->params('ID'), 'ohasd'), 'deinstall'); system (@cmd); } # remove /etc/init.d/ohasd my $initd = s_getInitd(); $file = (catfile ($initd, "ohasd")); s_remove_file ("$file"); # remove /var/tmp/.oracle $dir = catdir ("/var", "tmp", ".oracle"); if (-e $dir) { ( $error, $inUse ) = s_SocketFiles_InUse($dir); if ( !$error && !$inUse ) { trace ("Remove $dir"); rmtree ($dir); } } # remove /ect/inittab.crs $file = catfile ("/etc", "inittab.crs"); s_remove_file ("$file"); # remove /tmp/.oracle $dir = catdir ("/tmp", ".oracle"); if (-e $dir) { ( $error, $inUse ) = s_SocketFiles_InUse($dir); if ( !$error && !$inUse ) { trace ("Remove $dir"); rmtree ($dir); } } # remove /ect/oracle/lastgasp if ($CFG->defined_param('OLASTGASPDIR')) { $dir = $CFG->params('OLASTGASPDIR'); if (-e $dir) { trace ("Remove $dir"); rmtree ($dir); } } # remove /ect/oratab if (! $CFG->SIHA) { if ($CFG->defined_param('HOME_TYPE')) { $file = catfile ("/etc", "oratab"); s_remove_file ("$file"); } } # remove /etc/oracle if empty if (-e $CFG->params('OCRCONFIGDIR')) { # remove backup ocr.loc.orig and olr.loc.orig files $file = ($CFG->params('OCRCONFIG') . ".orig"); s_remove_file ("$file"); $file = ($CFG->params('OLRCONFIG') . ".orig"); s_remove_file ("$file"); # check if it's empty opendir (DIR, $CFG->params('OCRCONFIGDIR')); my @files = readdir(DIR); close DIR; if (scalar(@files) == 2) { trace ("Remove " . $CFG->params('OCRCONFIGDIR')); rmtree $CFG->params('OCRCONFIGDIR'); } } } sub s_checkOracleCM #------------------------------------------------------------------------------- # Function: Check for OracleCM by checking libskgxn on unix. # Args : none # Return : TRUE - if found #------------------------------------------------------------------------------- { my $false = 0; my $true = 1; my $libskgxnBase_lib = catfile('/etc', 'ORCLcluster', 'oracm', 'lib', 'libskgxn2.so'); my $libskgxn_lib = catfile('/opt', 'ORCLcluster', 'lib', 'libskgxn2.so'); trace("libskgxnBase_lib = $libskgxnBase_lib"); trace("libskgxn_lib = $libskgxn_lib"); if ((-e $libskgxn_lib) || (-e $libskgxnBase_lib)) { # no SKGXN; trace("SKGXN library file exists"); return $true; } trace("SKGXN library file does not exists"); return $false; } sub s_createConfigEnvFile #------------------------------------------------------------------------------- # Function: Create s_crsconfig_$HOST_env.txt file for Time Zone # Args : none # Notes : Valid format # (Please keep this in sync with has/utl/crswrapexec.pl) # * Empty lines: lines with all white space # * Comments: line starts with #. # * = # * is all non-whitespace characters on the left of the # first "=" character. # * is everything on the right of the first "=" character # (including whitespaces). # * Surrounding double-quote (") won't be stripped. # * Key with blank ('') will be undefined. # (e.g: Hello=, Hello will be undefined) #------------------------------------------------------------------------------- { my $env_file = catfile($CFG->ORA_CRS_HOME, 'crs', 'install', 's_crsconfig_' . $CFG->HOST . '_env.txt'); open (ENVFILE, ">$env_file") or die(dieformat(255, $env_file, $!)); #!!!!NOTE NOTE : This file is sourced in the ohasd wrapper script. Hence #needs to confirm to shell syntax. Only lines starting with '#' and #lines of the form x=y are permitted. print ENVFILE "" . "#########################################################################" . "\n#This file can be used to set values for the NLS_LANG and TZ environment" . "\n#variables and to set resource limits for Oracle Clusterware and" . "\n#Database processes." . "\n#1. The NLS_LANG environment variable determines the language and" . "\n# characterset used for messages. For example, a new value can be" . "\n# configured by setting NLS_LANG=JAPANESE_JAPAN.UTF8" . "\n#2. The Time zone setting can be changed by setting the TZ entry to" . "\n# the appropriate time zone name. For example, TZ=America/New_York" . "\n#3. Resource limits for stack size, open files and number of processes" . "\n# can be specified by modifying the appropriate entries." . "\n#" . "\n#Do not modify this file except as documented above or under the" . "\n#direction of Oracle Support Services.\n" . "#########################################################################\n"; # get TZ if ($CFG->defined_param('TZ')) { my $tz = $CFG->params('TZ'); $tz =~ s/'//g; # remove single quotes print ENVFILE "TZ=" . $tz . "\n"; } # get NLS_LANG if ($CFG->defined_param('LANGUAGE_ID')) { my $nls_lang = $CFG->params('LANGUAGE_ID'); $nls_lang =~ s/'//g; # remove single quotes print ENVFILE "NLS_LANG=" . $nls_lang . "\n"; } #17301761 print ENVFILE "CRS_LIMIT_STACK=2048\n"; print ENVFILE "CRS_LIMIT_OPENFILE=65536\n"; print ENVFILE "CRS_LIMIT_NPROC=65536\n"; # Set RT_GRQ to force real-time processes onto global run-queue for AIX # NOTE - ONLY FOR AIX, DOES NOT MAKE SENSE FOR OTHER PLATFORMS # See IBM AIX documentation on RT_GRQ parameter for more information if ($OSNAME eq 'aix') { print ENVFILE "RT_GRQ=ON\n"; print ENVFILE "EXTSHM=OFF\n"; } # Make sure that env var TNS_ADMIN will be unset. print ENVFILE "TNS_ADMIN=\n"; # Bug 13506877: Do not unset ORACLE_BASE; CLSB and ADR need it now. # print ENVFILE "ORACLE_BASE=\n"; close (ENVFILE); s_set_ownergroup ($CFG->SUPERUSER, $CFG->params('ORA_DBA_GROUP'), $env_file) || die(dieformat(152, $env_file)); #17953942:this file is source'd by ohasd/crsctl, hence need world r+,x+ s_set_perms ("0755", $env_file) || die(dieformat(153, $env_file)); } sub s_isRAC_appropriate #------------------------------------------------------------------------------- # Function: Check if rac_on/rac_off on Unix # Args : none # Returns : TRUE if rac_on/rac_off needs to be set # FALSE if rac_on/rac_off not needs to be set #------------------------------------------------------------------------------- { my $rdbms_lib = catfile($CFG->ORA_CRS_HOME, "rdbms", "lib"); my $success = TRUE; # save current dir my $save_dir = getcwd; # check for rac_on chdir $rdbms_lib; my $cmd = "$ARCHIVE -tv libknlopt.a | grep kcsm"; open ON, "$cmd |"; my @kcsm = (); close ON; if (scalar(@kcsm) == 0) { if (! $CFG->SIHA) { $success = FALSE; print " \n"; print "The oracle binary is currently linked with RAC disabled.\n"; print "Please execute the following steps to relink oracle binary\n"; print "as the oracle user and rerun the command with RAC enabled: \n"; print " setenv ORACLE_HOME \n"; print " cd /rdbms/lib \n"; print " make -f ins_rdbms.mk rac_on ioracle \n"; } } elsif ($CFG->SIHA) { $success = FALSE; print " \n"; print "The oracle binary is currently linked with RAC enabled.\n"; print "Please execute the following steps to relink oracle binary\n"; print "as the oracle user and rerun the command with RAC disabled: \n"; print " setenv ORACLE_HOME \n"; print " cd /rdbms/lib \n"; print " make -f ins_rdbms.mk rac_off ioracle \n"; } # restore save_dir chdir $save_dir; return $success; } sub s_configureCvuRpm #------------------------------------------------------------------------------ # Function: Install cvuqdisk rpm on Linux # Args : none #------------------------------------------------------------------------------- { my $uname =`uname`; chomp($uname); if ($uname=~/Linux/) { trace ("Install cvuqdisk rpm on Linux..."); my $rmpexe = "/bin/rpm"; my $install_cvuqdisk=FALSE; my $rpm_pkg_dir; my $rpm_file; if (is_dev_env()) { $rpm_pkg_dir=catfile($CFG->ORA_CRS_HOME,'opsm','cv','remenv'); } else { $rpm_pkg_dir=catfile($CFG->ORA_CRS_HOME,'cv', 'rpm'); } opendir (DIR, $rpm_pkg_dir); foreach (sort grep(/cvuqdisk/,readdir(DIR))) { $rpm_file = $_; } closedir DIR; my $new_rpm_file = $rpm_pkg_dir . "/" . $rpm_file; trace ("New package to install is $new_rpm_file"); trace ("Invoking \"$rmpexe -q cvuqdisk\" command"); my $curr_rpm_version = `$rmpexe -q cvuqdisk --queryformat '%{VERSION}'`; my $status = $?; if ($status == 0) { my $curr_rpm_release = `$rmpexe -q cvuqdisk --queryformat '%{RELEASE}'`; trace ("Invoking \"$rmpexe -qp $new_rpm_file\" command"); my $new_rpm_version = `$rmpexe -qp $new_rpm_file --queryformat '%{VERSION}'`; my $new_rpm_release = `$rmpexe -qp $new_rpm_file --queryformat '%{RELEASE}'`; chomp ($curr_rpm_version); chomp ($new_rpm_version); chomp ($curr_rpm_release); chomp ($new_rpm_release); if ($curr_rpm_version eq "package cvuqdisk is not installed") { trace ("package is not installed"); $install_cvuqdisk = TRUE; } else { trace ("check package versions new = [$new_rpm_version];old=[$curr_rpm_version] "); my $i; my @currPkgArr = split(/\./, $curr_rpm_version); my @newPkgArr = split(/\./, $new_rpm_version); my $loopMax = (scalar @currPkgArr <= scalar @newPkgArr)?scalar @currPkgArr:scalar @newPkgArr; my $currentConfigGood = FALSE; for ($i=0;$i<$loopMax;$i++) { if ($currPkgArr[$i] == $newPkgArr[$i]) { next; } if ($currPkgArr[$i] > $newPkgArr[$i]) { $currentConfigGood = TRUE; last; } trace ("install new package for version"); $install_cvuqdisk = TRUE; last; } if (!$currentConfigGood && !$install_cvuqdisk && ($curr_rpm_release lt $new_rpm_release)) { trace ("install new package for release"); $install_cvuqdisk = TRUE; } } } else { trace ("no existing cvuqdisk found"); $install_cvuqdisk = TRUE; } if ($install_cvuqdisk) { my $orauser = $CFG->params('ORACLE_OWNER'); my $CVUQDISK_GRP=`id -gn $orauser`; chomp($CVUQDISK_GRP); $ENV{'CVUQDISK_GRP'} = $CVUQDISK_GRP; trace ("removing old rpm"); my @args = ($rmpexe, "-e", "--allmatches", "cvuqdisk"); my @out = system_cmd_capture (@args); my $rc = shift @out; if ( $rc == 1) { trace ("Older version cvuqdisk not uninstalled"); } trace ("installing/upgrading new rpm"); my @rpmInstOutput = system_cmd_capture("$rmpexe -Uv $new_rpm_file"); my $rpmInstRc = shift(@rpmInstOutput); if (0 != $rpmInstRc) { trace("Installing/upgrading new rpm failed,"); trace("output is: @rpmInstOutput"); return FAILED; } } } return SUCCESS; } sub s_removeCvuRpm #--------------------------------------------------------------------- # Function: Remove cvuqdisk rpm # Args : None #--------------------------------------------------------------------- { my $uname =`uname`; chomp($uname); if ($uname=~/Linux/) { trace ("removing cvuqdisk rpm"); system ("/bin/rpm -e --allmatches cvuqdisk"); } return TRUE; } sub s_houseCleaning #------------------------------------------------------------------------------- # Function: Remove entries from inittab and misc files # Args : none #------------------------------------------------------------------------------- { # remove cssd/evmd/crsd entries from inittab s_remove_itab ("cssd|evmd|crsd"); # remove /etc/init.d/init.crs my $file = catfile ($CFG->params("ID"), 'init.crs'); if (-f $file) { trace ("remove $file"); s_remove_file ("$file"); } # remove /etc/init.d/init.crsd $file = catfile ($CFG->params("ID"), 'init.crsd'); if (-f $file) { trace ("remove $file"); s_remove_file ("$file"); } # remove /etc/init.d/init.cssd $file = catfile ($CFG->params("ID"), 'init.cssd'); if (-f $file) { trace ("remove $file"); s_remove_file ("$file"); } # remove /etc/init.d/init.evmd $file = catfile ($CFG->params("ID"), 'init.evmd'); if (-f $file) { trace ("remove $file"); s_remove_file ("$file"); } # remove S96init.crs files my $search_dir = catdir ('/etc', 'rc.d'); my $delete_file = "s96init.crs"; my $remove_file = sub { if (/\b$delete_file\b/i) { trace ("remove $File::Find::name"); s_remove_file ("$_"); } }; finddepth ($remove_file, $search_dir); # remove K96init.crs files $delete_file = "k96init.crs"; finddepth ($remove_file, $search_dir); # remove K19init.crs files $delete_file = "k19init.crs"; finddepth ($remove_file, $search_dir); } sub s_is92ConfigExists #------------------------------------------------------------------------------- # Function: Check if config exists in 9.2 # Args : none # Returns : TRUE if exists # FALSE if not exists #------------------------------------------------------------------------------- { my $srvconfig_loc; trace("SRVCONFIG=" . $CFG->params('SRVCONFIG')); if (-f $CFG->params('SRVCONFIG')) { trace ("Checking repository used for 9i installations"); $srvconfig_loc = s_get_config_key ("srv", "srvconfig_loc"); trace("srvconfig location=<$srvconfig_loc>"); if ($srvconfig_loc eq '/dev/null') { trace("srvconfig location=<$srvconfig_loc>"); trace("Oracle 92 configuration and SKGXN library does exists"); return TRUE; } } trace("Oracle 92 configuration and SKGXN library does not exists"); return FALSE; } sub s_removeGPnPprofile #------------------------------------------------------------------------------- # Function: Remove all contents under $crshome/gpnp dir # Args : none #------------------------------------------------------------------------------- { my $dir = catdir($CFG->ORA_CRS_HOME, 'gpnp'); # read dir contents opendir (DIR, $dir); my @files = readdir(DIR); close DIR; my $file; foreach $file (@files) { if ($file eq '.' || $file eq '..') { next; } elsif (-f "$dir/$file") { trace ("remove file=$dir/$file"); s_remove_file ("$dir/$file"); } elsif (-d "$dir/$file") { trace ("rmtree dir=$dir/$file"); rmtree ("$dir/$file"); } } } sub s_remove_file { my $remfile = $_[0]; if (-e $remfile || -l $remfile) { my @args = ("rm", $remfile); trace("Removing file $remfile"); my @out = s_system_cmd_capture2(@args); my $rc = shift @out; if ($rc == 0) { trace("Successfully removed file: $remfile"); } else { trace("Failed to remove file: $remfile"); return FAILED; } } return SUCCESS; } sub s_system_cmd_capture2 { my $rc = 0; my @output; @output = `@_ 2>&1`; $rc = $? >> 8; if (($rc != 1) && ($rc & 127)) { # program returned error code my $sig = $rc & 127; trace("Failure with return code $sig from command: @_"); } elsif ($rc) { trace("Failure with return code $rc from command @_"); } if ($CFG->DEBUG) { trace("@output"); } return ($rc, @output); } sub s_getAbsLink #------------------------------------------------------------------------------- # Function: Get absolute link # Args : file_loc # Returns : link_loc #------------------------------------------------------------------------------- { my $file_loc = $_[0]; my $link_loc = readlink($file_loc); my $count = 0; $count++ while ($link_loc =~ /\.\./g); if ($count > 0) { trace("symbolic link is not absolute link: $link_loc"); my @ocr_dir = split(/\//, $file_loc); my @link_dir = split(/\.\./, $link_loc); my $ocr_dir_cntr = scalar @ocr_dir; my $abs_link = '/'; my $limit = $ocr_dir_cntr - $count - 1; my $i; for ($i = 0; $i < $limit; $i++) { $abs_link = catdir($abs_link, $ocr_dir[$i]); } $link_loc = catfile($abs_link, $link_dir[$count]); trace("absolute link is $link_loc"); } return $link_loc; } sub s_is_primeCluster { my $status; my $checksc = "/usr/bin/cftool"; if (! (-e $checksc)) { trace ("$checksc not found"); return FALSE; } $status = system("$checksc -l"); if ($status == 0) { return TRUE; } else { return FALSE; } } sub s_is_sunCluster { my $status; my $checksc = "/usr/sbin/clinfo"; if (! (-e $checksc)) { trace ("$checksc not found"); return FALSE; } $status = system("$checksc"); if ($status == 0) { return TRUE; } else { return FALSE; } } sub s_is_Exadata { my $status; my $checksc = "/etc/oracle/cell/network-config/cellip.ora"; if (! (-e $checksc)) { trace ("$checksc not found"); return FALSE; } return TRUE; } # /opt/oracle.cellos/imageinfo |grep 5.11 sub s_is_solaris511 { if ($OSNAME ne "solaris") { return FALSE; } my ($rc, @grepout, @cmdout); ($rc, @cmdout) = system_cmd_capture("/opt/oracle.cellos/imageinfo"); if ( $rc != 0) { return FALSE; } @grepout = grep(/5.11/, @cmdout); if (scalar(@grepout) > 0) { return TRUE; } return FALSE; } # we cannot support solaris 5.11 ipmp interfaces sub s_is_sun_ipmp { my $ifconfig = "/usr/sbin/ifconfig"; my ($net, $inf, $sub, $type, $tmp, $rc, @out); # split apart the network keys and search foreach $net (split(/,/, $CFG->params('NETWORKS'))) { ($inf, $tmp) = split(/\//, $net); my @array = split(/:/, $tmp); $type = $array[-1]; # we only care about cluster_interconnect keys next if( $type !~ /cluster_interconnect/ ); # lets call ifconfig to figure out information about this interface ($rc, @out) = system_cmd_capture($ifconfig, $inf); # skip any interfaces on which we had errors next if( $rc != 0 ); # if we find any cluster_interconnect keys that have IPMP flag set # on their interface description, then we are done trace("The output line to be checked: $out[0]"); if( $out[0] =~ /IPMP/ ) { trace("IPMP interface is configured."); return TRUE; } } # made it all the way out without finding any IPMP private trace("No IPMP interface is configured."); return FALSE; } # we only create the HAIP resources for CRS installs and for now only on # linux, hpux, solaris, aix but eventually this should be for all unix. # NO HAIP if this is sun cluster or solaris 5.11 with IPMP as private # NO HAIP if env-var HAIP_UNSUPPORTED is set for all platforms # NO HAIP if Exadata with solaris511 sub s_is_HAIP_supported { if((($OSNAME eq "linux") || ($OSNAME eq "hpux") || ($OSNAME eq "aix") || (($OSNAME eq "solaris") && (!s_is_sunCluster()) && (!s_is_primeCluster()) && (!s_is_sun_ipmp()) && (!s_is_Exadata() || !s_is_solaris511()))) && (!$ENV{'HAIP_UNSUPPORTED'})) { trace("HAIP is supported."); return TRUE; } else { trace("HAIP is not supported."); return FALSE; } } # On some platforms we will install the HAIP resource, but we won't worry # about it's failure to come up but continue on regardless sub s_is_HAIP_NonFatal { if( ($OSNAME eq "hpux") || ($OSNAME eq "aix") ) { trace("HAIP is not fatal on this OS $OSNAME"); return TRUE; } else { trace("HAIP is fatal on this OS $OSNAME"); return FALSE; } } # In Linux, there are three startup mechanisms so far. # 1. SysVinit 2. upstart 3. systemd # # This routine will check if upstart is being used or not. # returns TRUE if upstart is being used for the init sub s_is_Linux_Upstart { # Check not cached, check if it is upstart if ( $UPSTART_USED == -1 ) { $UPSTART_USED = s_checkLinuxInitMethod("upstart"); } # return the cached value return $UPSTART_USED; } # This routine will check if systemd is being used or not. # returns TRUE if systemd is being used for the init sub s_is_Linux_Systemd { if (-1 == $SYSTEMD_USED) { $SYSTEMD_USED = s_checkLinuxInitMethod("systemd"); } return $SYSTEMD_USED; } sub s_checkLinuxInitMethod { my $initMethod = $_[0]; trace("Check if the startup mechanism $initMethod is being used"); if ($OSNAME eq 'linux') { my $rpm = '/bin/rpm'; my @cmd = ($rpm, '-qf', '/sbin/init'); my ($rc, @grepout, @cmdout); # Check if rpm is present if (! (-e $rpm)) { die(dieformat(46, $rpm)); } # Run the rpm command ($rc, @cmdout) = system_cmd_capture(@cmd); if ($rc != 0) { die(dieformat(180, join(' ', @cmd), $rc)); } # check for upstart in rpm output @grepout = grep(/^$initMethod-/i, @cmdout); if (scalar(@grepout) > 0) { return TRUE; } } trace("Not using the Linux startup method: $initMethod"); return FALSE; } # Add the oracle-ohasd conf file from CRSHOME to /etc/init sub s_add_upstart_conf { my ($status, @output); my $UPSTART_INIT_DIR = $CFG->params('UPSTART_INIT_DIR'); my $UPSTART_OHASD_CONF_CH = catfile($CFG->ORA_CRS_HOME, 'crs', 'install', $UPSTART_OHASD_CONF_FILE); my $UPSTART_OHASD_CONF = catfile ($UPSTART_INIT_DIR, $UPSTART_OHASD_CONF_FILE); if ( -e $UPSTART_OHASD_CONF_CH ) { # Copy $UPSTART_OHASD_CONF_CH to /etc/init/ unless (copy ("$UPSTART_OHASD_CONF_CH", "$UPSTART_OHASD_CONF")) { print_error(105, "$UPSTART_OHASD_CONF_CH", "$UPSTART_OHASD_CONF", $!); return FAILED; } } else { print_error(46, $UPSTART_OHASD_CONF_CH); return FAILED; } # Restore the default SELinux security context if ( -e $RESTORECON ) { ($status, @output) = system_cmd_capture ("$RESTORECON -iF $UPSTART_OHASD_CONF"); } return SUCCESS; } # Add the OHASD service file from crs/install to /etc/systemd/system sub s_add_systemd_conf { my $SYSTEMD_SYSTEM_DIR = $CFG->params('SYSTEMD_SYSTEM_DIR'); my $SYSTEMD_OHASD_SERVICE_FILE_SRC = catfile($CFG->ORA_CRS_HOME, 'crs', 'install', $SYSTEMD_OHASD_SERVICE_FILE); my $SYSTEMD_OHASD_SERVICE_FILE_DST = catfile($SYSTEMD_SYSTEM_DIR, $SYSTEMD_OHASD_SERVICE_FILE); if (-e $SYSTEMD_OHASD_SERVICE_FILE_SRC) { trace("SYSTEMD: Copying $SYSTEMD_OHASD_SERVICE_FILE_SRC to " . "$SYSTEMD_OHASD_SERVICE_FILE_DST"); unless (copy("$SYSTEMD_OHASD_SERVICE_FILE_SRC", "$SYSTEMD_OHASD_SERVICE_FILE_DST")) { print_error(105, "$SYSTEMD_OHASD_SERVICE_FILE_SRC", "$SYSTEMD_OHASD_SERVICE_FILE_DST", $!); return FAILED; } } else { print_error(46, $SYSTEMD_OHASD_SERVICE_FILE_SRC); return FAILED; } return SUCCESS; } # Enable/activate the given systemd service sub s_systemctl_start_service { my $service = $_[0]; my $SYSTEMCTL = $CFG->params('SYSTEMCTL'); my @output = system_cmd_capture($SYSTEMCTL, "daemon-reload"); my $rc = shift(@output); if (0 != $rc) { trace("failed to reload systemd for scanning for changed units"); return FAILED; } @output = system_cmd_capture($SYSTEMCTL, "enable", $service); $rc = shift(@output); if (0 != $rc) { trace("failed to enable $service to be started on bootup"); return FAILED; } @output = system_cmd_capture($SYSTEMCTL, "start", $service); $rc = shift(@output); if (0 != $rc) { trace("failed to activate $service"); return FAILED; } return SUCCESS; } #### Function for removing the Oracle service files from /etc/systmed/system # ARGS : 1 - match pattern for the Oracle service files # NOTE : Oracle service files will be of the format : oracle-{name}.service # like oracle-ohasd.service sub s_remove_systemd_conf { my $match_pattern = $_[0]; my $SYSTEMCTL = $CFG->params('SYSTEMCTL'); my $SYSTEMD_SYSTEM_DIR = $CFG->params('SYSTEMD_SYSTEM_DIR'); my @svc_pattern = split(/\|/, $match_pattern); trace("remove systemd conf for services: [@svc_pattern]"); foreach my $svc (@svc_pattern) { my $service = "oracle-$svc.service"; trace("attempt to deconfigure $service"); my @output = system_cmd_capture($SYSTEMCTL, "status", $service); my $rc = shift(@output); if (0 != $rc) { trace("The unit $service may not be installed"); } my $isRunning = (scalar(grep(/Active:\s+active/, @output)) > 0) ? TRUE : FALSE; my $isEnabled = (scalar(grep(/\benabled\b/, @output)) > 0) ? TRUE : FALSE; trace("isRunning: $isRunning; isEnabled: $isEnabled"); if ($isRunning) { @output = system_cmd_capture($SYSTEMCTL, "stop", $service); $rc = shift(@output); if (0 != $rc) { trace("failed to deactivate $service"); return FAILED; } } if ($isEnabled) { @output = system_cmd_capture($SYSTEMCTL, "disable", $service); $rc = shift(@output); if (0 != $rc) { trace("failed to disable $service to not start during bootup"); # OEL7 specific for devenv. Bug 19343551. do not abort fatal for dev env return FAILED if (! is_dev_env()); } } # Remove the unit file my $svc_file = catfile($SYSTEMD_SYSTEM_DIR, $service); trace("remove service file: $svc_file"); s_remove_file($svc_file); } return SUCCESS; } #### Function for removing the Oracle conf files from /etc/init # ARGS : 1 - match pattern for the Oracle conf file pattern # NOTE : Oracle conf files will be of the format : oracle-{name}.conf like oracle-ohasd.conf sub s_remove_upstart_conf { my $INITCTL = $CFG->params('INITCTL'); my $UPSTART_INIT_DIR = $CFG->params('UPSTART_INIT_DIR'); my ($status, @output, @initctl_list, @file_list, $file, $service, $service_name); my $match_pattern = $_[0]; # # Construct service and then stop it # # Get list of registered services in the system ($status, @output) = system_cmd_capture ("$INITCTL list"); if(0 != $status) { # Failed to list INITCTL print_error(218, $!); return FAILED; } # Filter the pattern of services interested from the initctl list @initctl_list = grep(/$match_pattern/i, @output); # Stop any running services from the list foreach $service(@initctl_list) { # Check if it is in running state and stop it if (scalar(grep(/running/, $service)) > 0) { ($service_name) = split(/ /, $service); trace("Service [$service_name] running.\n"); ($status, @output) = system_cmd_capture ("$INITCTL stop $service_name"); if(0 != $status) { my $initctlGet = "initctl: Method \"Get\" with signature \"ss\""; if (scalar(grep(/$initctlGet.+doesn't exist/, @output)) > 0) { # The service has been terminated although the exit status # of 'initctl stop' isn't ZERO, so we let the rootscript # go ahead trace("The configuration file of service '$service_name' is " . "missing, but the running service has still been stopped "); next; } else { # Failed to stop service print_error(218, $!); } return FAILED; } } } # # Remove the corresponding conf files # # Construct the file path pattern for the upstart conf files # for ($match_pattern) { # Replace the | with space of the match_pattern s-\|- -g; # Convert pattern "ohasd cssd" to "/etc/init/oracle-*ohasd*.conf /etc/init/oracle-*cssd*.conf " s-^-${UPSTART_INIT_DIR}/oracle\-*-g; s- - ${UPSTART_INIT_DIR}/oracle\-*-g; s- -*.conf -g; s-$-*.conf -g; } # Get the file list for the pattern (@file_list) = glob ($match_pattern); trace ("Glob file list = @file_list"); # Remove the conf file foreach $file(@file_list) { s_remove_file("$file"); } return SUCCESS; } sub s_getfileinfo { my $file = $_[0]; my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks); my $user; my $group; my $permissions; trace("Getting file permissions for $file\n"); if (($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = lstat($file)) { $user = getpwuid($uid); $group = getgrgid($gid); $permissions = sprintf "%04o", S_IMODE($mode); return($file, $user , $group, $permissions); } } sub s_saveParentDirinfo #------------------------------------------------------------------------------- # Function: save $current_dir and its parent directories ACL # Args : [0] Directory #------------------------------------------------------------------------------- { my $dir = $_[0]; my $savepermfile = catfile ($CFG->ORA_CRS_HOME, "crs", "install", "ParentDirPerm_" . $CFG->HOST . ".txt"); my ($fname, $fuser, $fgroup, $fperm, @perm_table); trace("saving parent dir ACLs in $savepermfile\n"); if (-e $savepermfile) { # load into @perm_table trace("loading... $savepermfile\n"); @perm_table = read_file ($savepermfile); } my $save_entries = scalar(@perm_table); while ($dir ne "/" && $dir ne ".") { ($fname, $fuser, $fgroup, $fperm) = s_getfileinfo($dir); my $text = "$fname:$fuser:$fgroup:$fperm"; my $search_str = $fname . ':'; # check if it exists my $found = FALSE; foreach my $rec (@perm_table) { chomp($rec); if ($rec =~ m/^$search_str/) { $found = TRUE; } } if (! $found) { push @perm_table, $text; } $dir = dirname($dir); } # if new record is added to the @perm_table, create new perm file if (scalar(@perm_table) != $save_entries) { if (s_remove_file($savepermfile)) { open (SFILE, ">$savepermfile") or print_error(217, $savepermfile, $!); foreach my $dir (@perm_table) { trace("writing $dir to $savepermfile"); print SFILE "$dir\n"; } close SFILE; } } s_set_ownergroup ($CFG->SUPERUSER, $CFG->params('ORA_DBA_GROUP'), $savepermfile); s_set_perms ("0644", $savepermfile) ; } sub s_install_initd { #Would skip this install in dev environment if (s_isSUSELinux() && ! is_dev_env()) { my $ohasd = catfile($CFG->params('ID'), 'ohasd'); my $initd = catfile('/usr', 'lib', 'lsb', 'install_initd'); my @out = system_cmd_capture($initd, $ohasd); my $status = shift @out; if ($status != 0) { print_error(218, $!); return FAILED; } } return SUCCESS; } sub s_remove_initd { # remove initd if it's SUSE Linux if (s_isSUSELinux()) { my $ohasd = catfile($CFG->params('ID'), 'ohasd'); my $initd = catfile('/usr', 'lib', 'lsb', 'remove_initd'); my @out = system_cmd_capture($initd, $ohasd); my $status = shift @out; if ($status != 0) { trace ("Failed to remove initd"); } } } sub s_is_ODA_BMIaaS { my $clfile = catfile('/proc', 'cmdline'); if (! (-e $clfile)) { return FALSE; } my @fileCont = read_file($clfile); foreach my $line (@fileCont) { if ($line =~ /TYPE=.*IAAS/) { trace("This is ODA Lite/BMIaaS"); return TRUE; } } return FALSE; } sub s_isSUSELinux { if ($OSNAME eq 'linux') { my @cmd = (catfile('/bin', 'rpm'), '-q', 'sles-release'); my @out = system_cmd_capture(@cmd); my $rc = shift @out; if ($rc == 0) { return TRUE; } else { return FALSE; } }else{ return FALSE; } } sub s_afd_install_initd { #Would skip this install in dev environment if (s_isSUSELinux() && ! is_dev_env()) { my $afd = catfile($CFG->params('ID'), 'afd'); my $initd = catfile('/usr', 'lib', 'lsb', 'install_initd'); my @out = system_cmd_capture($initd, $afd); my $status = shift @out; if ($status != 0) { trace ("Failed at install_initd for AFD"); } } } sub s_afd_remove_initd { # remove initd if it's SUSE Linux if (s_isSUSELinux() && ! is_dev_env()) { my $afd = catfile($CFG->params('ID'), 'afd'); my $initd = catfile('/usr', 'lib', 'lsb', 'remove_initd'); my @out = system_cmd_capture($initd, $afd); my $status = shift @out; if ($status != 0) { trace ("Failed at remove_initd for AFD"); } } } #------------------------------------------------------------------------------ # Function: check if network configuration files need to be updated to # disable 169.254/16 route usage (ZEROCONF) #------------------------------------------------------------------------------ sub s_CheckNetworkConfig { my $fixed = TRUE; my $base; my $temp; my $save; # network configuration modifications only valid for linux if( !($OSNAME eq "linux") ) { return; } if( is_dev_env() ) { trace("Skipping network configuration checks due to DEV env"); return; } if ( -e $suseNetworkConfig && -f $suseNetworkConfig ) { $base = $suseNetworkConfig; $fixed = s_suseCheckNetworkConfig($base); } elsif( -e $oelNetworkConfig && -f $oelNetworkConfig ) { $base = $oelNetworkConfig; $fixed = s_oelCheckNetworkConfig($base); } # if we dont need to do any more work then just leave if( ! $fixed ) { return; } # otherwise lets swap the temporary files with the new ones $save = $base . $checkNetworkSave; $temp = $base . $checkNetworkTemp; # cleanup any original files unlink $save; # move the original base file to a temporary name rename $base, $save; # then move the temporary file to this new name rename $temp, $base; # and let the world know what we have done trace("Disabled LinkLocal Address manipulation"); } #------------------------------------------------------------------------------ # Function: check if network configuration files need to be updated to # disable 169.254/16 route usage (ZEROCONF) # # Args : [0] Base path to OEL configuration files #------------------------------------------------------------------------------ sub s_oelCheckNetworkConfig { my $baseFile = $_[0]; my $tempFile = $_[0] . $checkNetworkTemp; my $numFound = 0; my $found = FALSE; my $line; unlink $tempFile; open BASEFILE, "<$baseFile"; open TEMPFILE, ">$tempFile"; foreach $line () { chomp $line; if ( $line !~ /NOZEROCONF=\S*/ || $line =~ /^\s*#/ ) { print TEMPFILE "$line\n"; next; } # track that we found at least one occurrence # but dont output it to the file yet $numFound++; } # if we found exactly one occurrence then we are fine if( 1 == $numFound ) { $found = TRUE; } # if we didnt find any or we found more than one then force just one else { $found = FALSE; # and output the one good line to the end of the file print TEMPFILE "NOZEROCONF=yes\n"; } close BASEFILE; close TEMPFILE; # if we found the setting, then we can just throw away this temp file if( $found ) { unlink $tempFile; } return ! $found; } #------------------------------------------------------------------------------ # Function: check if network configuration files need to be updated to # disable 169.254/16 route usage (ZEROCONF) # # Args : [0] Base path to suse network configuration files #------------------------------------------------------------------------------ sub s_suseCheckNetworkConfig { my $found = FALSE; my $baseFile = $_[0]; my $tempFile = $_[0] . $checkNetworkTemp; my $line; unlink $tempFile; open BASEFILE, "<$baseFile"; open TEMPFILE, ">$tempFile"; foreach $line () { chomp $line; if ( $line !~ /LINKLOCAL_INTERFACES=\S*/ || $line =~ /^\s*#/ ) { print TEMPFILE "$line\n"; next; } # output to the file the same line but stick a comment '#' at the front print TEMPFILE "#${line}\n"; # track that we found at least one occurrence # but dont output it to the file yet $found = TRUE; } # if we did not find any broken lines, then we throw away this temp file if( ! $found ) { unlink $tempFile; } return $found; } ####--------------------------------------------------------- #### Restore init scripts from old CRS home # ARGS : [0] old CRS home sub s_restoreInitScripts { my $oldcrshome = $_[0]; trace("restore init scripts"); my $initOhasd = 'init.ohasd'; my $ohasd = 'ohasd'; my $oldInitOhasd = catfile ($oldcrshome, 'crs', 'init', $initOhasd); my $oldOhasd = catfile ($oldcrshome, 'crs', 'init', $ohasd); my $newInitOhasd = catfile ($CFG->params('ID'), $initOhasd); my $newOhasd = catfile ($CFG->params('ID'), $ohasd); # restore the init scripts from the old home copy_file($oldInitOhasd, $newInitOhasd); copy_file($oldOhasd, $newOhasd); } ####--------------------------------------------------------- #### Function for restoring ASM files during the downgrade #### from 12c to 11201/2 # ARGS : 0 sub s_restoreASMFiles { my $optorcldir = $CFG->params('EXTERNAL_ORACLE'); my $optorclbindir = $CFG->params('EXTERNAL_ORACLE_BIN'); my $asmgidfile = catfile($optorclbindir, 'setasmgid'); my $asmgidorg = catfile($CFG->OLD_CRS_HOME, 'bin', 'setasmgid'); my $ORA_DBA_GROUP = $CFG->params('ORA_DBA_GROUP'); trace("Re-creating the directory '$optorclbindir'"); if (-d $optorcldir) { mkpath($optorclbindir); } if (!(-d $optorclbindir)) { error("Failed to re-create $optorclbindir"); return FAILED; } else { if (FAILED == s_set_ownergroup($CFG->SUPERUSER, $ORA_DBA_GROUP, $optorclbindir)) { error("Failed to change the ownership of $optorclbindir"); return FAILED; } if (FAILED == s_set_perms("0750", $optorclbindir)) { error("Failed to change the permissions of $optorclbindir"); return FAILED; } } trace("Restoring $asmgidfile"); if (FAILED == copy_file($asmgidorg, $asmgidfile, $CFG->SUPERUSER, $ORA_DBA_GROUP)) { error("Failed to restore $asmgidfile"); return FAILED; } if (FAILED == s_set_perms("4710", $asmgidfile)) { error("Failed to change permissions on $asmgidfile"); return FAILED; } trace("Setting the ownership and permissions of $optorcldir " ."to the original"); if (-d $optorcldir) { s_set_ownergroup($CFG->SUPERUSER, $ORA_DBA_GROUP, $optorcldir); s_set_perms("0750", $optorcldir); } # Remove /etc/oracle/setasmgid from higher version my $file = catfile($CFG->params('OCRCONFIGDIR'), 'setasmgid'); if (-f $file) { trace("Remove $file"); s_remove_file("$file"); } return SUCCESS; } # copy afd file to init.d and to rc levels sub s_copy_afdinit_init { my $INITDIR = catfile ($CFG->params('ORACLE_HOME'), "crs", "init"); my $srv = "afd"; my $INITDIR_SRV = catfile ($INITDIR, $srv); #if SUSE linux, copy the afd.sles to the rcdirs if ( s_isSUSELinux()) { $INITDIR_SRV = catfile ($INITDIR, "$srv.sles"); } s_copy_to_rcdirs ($INITDIR_SRV, "afd") || return FAILED; s_afd_install_initd(); return SUCCESS; } sub s_rm_afdinit_init { my $afdfile = catfile($INITD, "afd"); if(-e $afdfile) { s_afd_remove_initd(); trace("Removing /etc/init.d/afd"); unlink($afdfile); } return SUCCESS; } sub s_rm_afdinit_rclevel { s_clean_rcdirs ("afd"); return SUCCESS; } sub s_osd_setup { # Copy init scripts to init directory only if AFD is supported if(oraafd::isAFDSupported()) { # Setup afd init files s_copy_afdinit_init(); } return SUCCESS; } sub s_unregister_service { # TBD return SUCCESS; } sub s_redirect_souterr { # no-op on Linux as we don't want to redirect output return SUCCESS; } sub s_restore_souterr { ### no-op on Linux return SUCCESS; } #------------------------------------------------------------------------------- # Function: Returns the path to the qosctl script # Args : none # Returns : Path to the qosctl script #------------------------------------------------------------------------------- sub s_get_qosctl_path { my $execPath = catfile( $CFG->ORA_CRS_HOME, 'bin', 'qosctl' ); if ( !( -x "${execPath}" ) ) { die(dieformat(1008, $execPath)); } return $execPath; } #------------------------------------------------------------------------------- ## Function: Verify whether the process with the given PID is the same process # recorded by the given PID file # The process can change if the PID is recycled. ## Args : [0] PID # [1] PID File ## Returns : TRUE/FALSE ##------------------------------------------------------------------------------- sub s_verify_PID { my $pid = $_[0]; my $pidFile = $_[1]; my $procName; # get the process name if ($pidFile =~ /([^\/]+)\.pid$/) { $procName = $1; # remove the prefix and suffix of the process name, # such as: ohasd_cssdmonitor_root.pid -> cssdmonitor $procName = $1 if ($procName =~ /_([^_]+)_/); } my @output = system_cmd_capture ('ps', '-ef', '|', 'grep', $procName, '|', 'grep', '-v', 'grep'); my $rc = shift @output; trace("rc: $rc"); foreach my $line (@output) { chomp($line); my @word = split(/\s+/, $line); return TRUE if ($word[1] eq $pid); } return FALSE; } #----------------------------------------------------------------------------- ## Function : Get the file system type for a specific file system or directory. ## Args : [0] a specific file system or directory ## Returns : the file system type #----------------------------------------------------------------------------- sub s_getFSType { my $dir = $_[0]; my $fstype; my $cmd; my @output; my $rc; if ($OSNAME eq 'linux') { $cmd = "df -T ".$dir; @output = system_cmd_capture($cmd); $rc = shift @output; if ($rc == 0) { # the output is like: # Filesystem Type 1K-blocks Used Available Use% Mounted on # /dev/cciss/c0d0p2 # ext3 968912664 182085768 736814948 20% / # when the filesystem string is too long, the type would be on line 3. my @line2 = split(/\s+/, $output[1]); if ($line2[1]) { $fstype = $line2[1]; } else { my @line3 = split(/\s+/, $output[2]); $fstype = $line3[1]; } } else { trace("Failed to get the file system type for $dir."); return ""; } } if ($OSNAME eq 'solaris' || $OSNAME eq "hpux") { $cmd = "df -n ".$dir; @output = system_cmd_capture($cmd); $rc = shift @output; if ($rc == 0) { # the output is like: # /scratch (/dev/vgvm01/lvol10 ) : vxfs my @elems = split(/:/, $output[0]); $fstype = trim($elems[1]); } else { trace("Failed to get the file system type for $dir."); return ""; } } if ($OSNAME eq "aix") { $cmd = "lsfs ".$dir; @output = system_cmd_capture($cmd); $rc = shift @output; if ($rc == 0) { # the ouput is like: # Name Nodename Mount Pt VFS Size Options Auto Accounting # /dev/hd4 -- / jfs 4194304 rw yes no my @elemsaix = split(/\s+/, $output[1]); $fstype = $elemsaix[3]; } else { trace("Failed to get the file system type for $dir."); return ""; } } trace("The file system type for $dir: $fstype"); return $fstype; } ### TO DO #- merge s_reset_crshome & s_reset_crshome1 #- dup s_CheckNetworkConfig, s_oelCheckNetworkConfig # missing # my @exp_osd = qw( # s_deltOldServ # s_removeSCR s_removeFenceServ # s_copyRegKey s_stopDeltOldASM # ); 1;