# $Header: ecmPatchOneOff.pl 31-jan-2005.05:29:53 shgangul Exp $ # # Copyright (c) 2001, 2005, Oracle. All rights reserved. # # DESCRIPTION # ECM script to patch Oracle RDBMS server using ST one-off patches # # USAGE # ecmPatchOneOff.pl # # # NOTES # # # MODIFIED (MM/DD/YY) # shgangul 01/31/05 - bug 3845819: MAC OS port # mbhoopat 03/10/04 - linux port # nsharma 01/21/04 - Change nawk to awk on linux # xxu 06/25/02 - remove /usr/local/bin/perl # mgoodric 11/09/01 - Create a new PatchOneOff job type # mgoodric 11/09/01 - Create a new PatchOneOff job type # # # --- Set up necessary variables for proper running of this environment --- use strict; use FileHandle; use File::Basename; use Config; my $OSNAME = $Config{'osname'}; my $IsWin32 = ($OSNAME eq 'MSWin32'); # ------ Initialize global variables ------------------------------------- my $EMDROOT = $ENV{EMDROOT}; my $OPERATION = $ARGV[0]; # checkTarget | installPatch my $PATCH_ID = $ARGV[1]; # 1390304 my $ORACLE_HOME = $ARGV[2]; # /private/OraHome1 my $ORACLE_SID = $ARGV[3]; # mjgdb817 my $PATCH_PATH = $ARGV[4]; # ecmdepot/patches/1390304 my $PATCH_FILE = $ARGV[5]; # p1390304_8170_SOLARIS.zip # --------------------- Subroutines ------------------------------------- # # err # # Display a formatted error message # sub err { my ($ERROR_NUMBER,$ERROR_TEXT) = @_; printf "---------- Error Message ----------\n"; printf "PAT-%03d:\n",$ERROR_NUMBER; printf "%s\n",$ERROR_TEXT; printf "----------- End Message -----------\n"; } # # err # # Display a formatted warning message # sub warn { my ($WARNING_NUMBER,$WARNING_TEXT) = @_; printf "--------- Warning Message ---------\n"; printf "PAT-%03d:\n",$WARNING_NUMBER; printf "%s\n",$WARNING_TEXT; printf "----------- End Message -----------\n"; } # # abort # # Display a formatted error and exit with error status # sub abort { my ($NUMBER,$TEXT) = @_; if ($NUMBER == 0) { $NUMBER = 1; } err($NUMBER,$TEXT); printf "\n$OPERATION command failed\n"; exit $NUMBER; } # # checkTarget # # - Verify ORACLE_HOME # - Create depot directory to store patch # sub checkTarget { my ($PATCH_ID,$PATCH_PATH) = @_; my $_status_ = -1; my $ORACLE_HOME = $ENV{'ORACLE_HOME'}; my $ORACLE_SID = $ENV{'ORACLE_SID'}; chdir $ORACLE_HOME or abort($? >>8,"Could not cd to >$ORACLE_HOME<: $!"); my $dir = "$ORACLE_HOME/$PATCH_PATH"; if (! -e $dir) { system("/bin/mkdir -p $dir") == 0 or abort($? >>8,"Could not mkdir >$dir<: $!"); } chdir $dir or abort($? >>8,"Could not cd to >$dir<: $!"); system('/bin/ls -1R | /bin/egrep -s \'^undo_pre[0-9]*\\.sh$\'') != 0 or abort(1,"$PATCH_ID already applied"); my $_tempfile_ = '_test_'; open (OUTPUT,'>',$_tempfile_) or abort($? >>8,"Could not open file $_tempfile_ to write: $!"); close (OUTPUT); unlink $_tempfile_; } # # installPatch # # - Unzip the patch # - Stop the database if running # - run the patch.sh script # - restart the database if it was running # sub installPatch { my ($PATCH_ID,$PATCH_PATH,$PATCH_FILE) = @_; my $_status_ = -1; my $ORACLE_HOME = $ENV{'ORACLE_HOME'}; my $ORACLE_SID = $ENV{'ORACLE_SID'}; my $dir = "$ORACLE_HOME/$PATCH_PATH"; chdir $dir or abort($? >>8,"Could not cd to >$dir<: $!"); my $unziputil = "/bin/unzip"; if ($^O eq "darwin") { $unziputil = "/usr/bin/unzip"; } system("$unziputil -o $PATCH_FILE") == 0 or abort($? >>8,"Could not unzip $PATCH_FILE"); my $awkutil = "/bin/nawk"; if ($^O eq "linux") { $awkutil = "/bin/awk"; } elsif ($^O eq "darwin") { $awkutil = "/usr/bin/awk"; } my $_patchhome_ = `/bin/ls -1p | $awkutil '{if (substr(\$0,length(\$0)) == "/") {printf "%s",\$0; exit}}'`; chdir $_patchhome_ or abort($? >>8,"Could not cd to >$_patchhome_<: $!"); my $_tempfile_ = ''; system("/bin/ps -ef | /bin/egrep -s \' ora_pmon_$ORACLE_SID\$\'"); if ($? == 0) { $_tempfile_ = "/tmp/$ENV{'LOGNAME'}_sqlplus_$$.sql"; open (OUTPUT,'>',$_tempfile_) or abort($? >>8,"Could not open file $_tempfile_ to write: $!"); print OUTPUT "CONNECT / AS SYSDBA;\n"; print OUTPUT "SHUTDOWN IMMEDIATE\n"; print OUTPUT "EXIT\n"; close (OUTPUT); my $_errstatus_ = system("$ORACLE_HOME/bin/sqlplus /nolog \@$_tempfile_"); unlink $_tempfile_; ($_errstatus_ == 0) or abort($_errstatus_ >>8,"Could not shutdown database"); system("/bin/ps -ef | /bin/egrep -s \' ora_pmon_$ORACLE_SID\$\'") != 0 or abort(1,"Could not shutdown database"); } my $_orapatch_ = 'patch.sh'; if (! -e $_orapatch_) { chmod 0777,$_orapatch_ or abort($? >>8,"Could not chmod >$_orapatch_<: $!"); } $_status_ = system("./$_orapatch_ ',$_tempfile_) or abort($? >>8,"Could not open file $_tempfile_ to write: $!"); print OUTPUT "CONNECT / AS SYSDBA;\n"; print OUTPUT "STARTUP FORCE\n"; print OUTPUT "EXIT\n"; close (OUTPUT); my $_errstatus_ = system("$ORACLE_HOME/bin/sqlplus /nolog \@$_tempfile_"); unlink $_tempfile_; ($_errstatus_ == 0) or abort($_errstatus_ >>8,"Could not startup database"); system("/bin/ps -ef | /bin/egrep -s \' ora_pmon_$ORACLE_SID\$\'") == 0 or abort(1,"Could not startup database"); } ($_status_ == 0) or abort($_status_ >>8,"Patch failed"); } # --------------------- Main program ------------------------------------- $| = 1; # set OUTPUT_AUTOFLUSH printf "Running: '$0' - #ARGV: $#ARGV\n"; printf "Perl version = $]\n"; printf "Hostname = %s",`hostname`; printf "Operating system = $^O\n"; printf "Time = %s\n\n",scalar(localtime()); # # Set ORACLE_HOME environment if present # if ($#ARGV >= 3) { if ($ENV{'ORACLE_HOME'} ne $ORACLE_HOME) { $ENV{'ORACLE_HOME'} = $ORACLE_HOME; $ENV{'ORACLE_SID'} = $ORACLE_SID; $ENV{'PATH'} = "$ORACLE_HOME/bin:/usr/bin:/usr/ccs/bin:/usr/ucb:$ENV{'PATH'}"; $ENV{'LD_LIBRARY_PATH'} = "$ORACLE_HOME/lib:$ENV{'LD_LIBRARY_PATH'}"; } } # # Execute the operation requested # if ($OPERATION eq 'checkTarget') { if ($#ARGV < 4) { abort(3,"Missing args: $#ARGV < 4"); } checkTarget($PATCH_ID,$PATCH_PATH); } elsif ($OPERATION eq 'installPatch') { if ($#ARGV < 5) { abort(3,"Missing args: $#ARGV < 5"); } installPatch($PATCH_ID,$PATCH_PATH,$PATCH_FILE); } else { abort(5,"Unrecognized operation: $OPERATION"); } # # Indicate a successful operation exit with success status # printf "\n$OPERATION command successful\n"; exit 0;