#!/usr/local/bin/perl # # $Header: emdb/sysman/admin/scripts/db/sgastart.pl /stpl_db_11.2.0.1.0_gen/1 2009/09/23 23:18:48 pbhogara Exp $ # # sgastart.pl # # Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. # # NAME # sgastart.pl - Script to start SGA collector # # DESCRIPTION # This script is called by the Collections Manager to start the # SGA Collector # # NOTES # - # # MODIFIED (MM/DD/YY) # pbhogara 09/18/09 - Use native make for HPUX platforms # pbhogara 05/14/09 - Change permissions on advert_dir # pbhogara 01/30/09 - Check if rdbms group owner is set # jsoule 05/23/07 - use EMSTATE for ADVERTDIR, at times # jsoule 05/10/07 - use version 11 libraries # jsoule 11/30/06 - link nmccollector using target db binaries # jsoule 10/10/06 - version-specific linking # hopark 09/01/06 - relink nmccollector everytime, use libclntsh from # the target db # ysun 07/05/06 - move c code to emagent # hopark 03/06/06 - add libgeneric # hopark 02/27/06 - turn off SGA by default # hopark 06/27/05 - fix advert_dir permission # hopark 06/21/05 - put nmc.status under the same advert_dir as other files. # jsoule 06/06/05 - do not start collector in resume on NT. # jsoule 05/24/05 - use correct libserver10 # hopark 05/14/05 - Fix ownership and mode of the collection directory # hopark 05/09/05 - grabtrans 'hopark_bug-4258298' # add enable/disable collector # zsyed 04/17/05 - Changing to work in GRID_AGENT_VIEW # zsyed 02/07/05 - Removing inverted commas for NT # zsyed 11/22/04 - Removing references to emdw # zsyed 09/28/04 - Fixing Solaris collector startup problem # zsyed 08/23/04 - Creation # ######################### # Declare packages to use ######################### require "emd_common.pl"; require "semd_common.pl"; require "$ENV{EMDROOT}/sysman/admin/scripts/db/db_common.pl"; require "$ENV{EMDROOT}/sysman/admin/scripts/db/sgapid.pl"; use POSIX; use vars qw($NT); ######################## # Declare variables ######################## $debug = EMAGENT_isPerlDebugEnabled(); $collmode = trim($ARGV[0]); $connstr = trim($ARGV[1]); $machname = trim($ARGV[2]); $portname = trim($ARGV[3]); $sidname = trim($ARGV[4]); my %stdinArgs = get_stdinvars(); $username = $stdinArgs{"EM_TARGET_USERNAME"}; $password = $stdinArgs{"EM_TARGET_PASSWORD"}; $targetorahome = trim($ARGV[5]); $ENV{TARGETORACLE_HOME}=$targetorahome; $myorahome = trim($ENV{'ORACLE_HOME'}); $myversion = trim($ENV{'EM_TARGET_VERSION'}); $emdhome = trim($ENV{'EMDROOT'}); $cmd = ""; $resume = 0; $numArgs = $#ARGV + 1; if ($numArgs > 7) { $cmd = trim($ARGV[7]) ; $resume = ($cmd eq "resume"); } if($emdhome eq "") { $emdhome = $myorahome; } $msg_dir = $emdhome."/mesg/"; if (defined($ENV{EMSTATE})) { $nmcstate = $ENV{EMSTATE}; } else { $nmcstate = $emdhome; } if ($nmcstate ne $myorahome && $nmcstate =~ /_$sidname/) { ################################ # use EMSTATE if it is different from the agent's oracle home, but specific # to the instance sid of the target... ################################ chdir($nmcstate) || die "Cannot chdir $nmcstate: $!"; $advert_dir = $nmcstate."/"; } else { ################################ # otherwise create advert_dir under myorahome ################################ $firstdir = $machname."_".$sidname; chdir($myorahome) || die "Cannot chdir $myorahome: $!"; if(!(-d $firstdir)) { mkdir($firstdir, 0750) || die "Cannot mkdir $firstdir: $!"; } chdir($firstdir) || die "Cannot chdir $firstdir: $!"; $advert_dir = $myorahome."/".$firstdir."/"; } $seconddir = "sysman"; $thirddir = "log"; if(!(-d $seconddir)) { mkdir($seconddir, 0750) || die "Cannot mkdir $seconddir: $!"; } chdir($seconddir) || die "Cannot chdir $seconddir: $!"; if(!(-d $thirddir)) { mkdir($thirddir, 0750) || die "Cannot mkdir $thirddir: $!"; } chdir($thirddir) || die "Cannot chdir $thirddir: $!"; $advert_dir .= $seconddir."/".$thirddir."/"; # Check to see if nmccollector exists # If it doesn't, create it if($NT) { $groupname = 'ORA_DBA'; } else { $groupname = trim($ENV{'RDBMS_GROUP_OWNER'}); if($groupname eq '') { # If RDBMS_GROUP_OWNER is not set by the user then # set the group name to 'dba' by default. $groupname = 'dba'; } $uid = POSIX::getuid(); $gid = getgrnam($groupname); if (!chown ($uid, $gid, $advert_dir)) { EMAGENT_PERL_WARN("couldn't chown $advert_dir."); } # Originally, the permissions on the advert_dir were set with # write permissions for the group. This should not be # necessary: an agent --installed as another user in the same # group-- which shares a running nmccollector should not be # writing to the advert_dir. # Note: in testing this fix, it was discovered that this sharing # is not happening (GC 10.2.0.5 agent trying to share the # nmccollector of a DBC 11.2 agent) due to insufficient access # privileges on the shared memory segment when the agent is a # different user (in the same group) from the one of the # nmccollector. This needs to be investigated further. if (!chmod (0750, $advert_dir)) { EMAGENT_PERL_WARN("couldn't chmod $advert_dir."); } } $tracefile = $advert_dir . "sgastart.trc"; $ttfile = $advert_dir . "nmc.debug"; if (-e $ttfile){ $debug = 1; } TRACE("------ sgastart ".$cmd); TRACE("ARG0 : ".$ARGV[0]); TRACE("ARG1 : ".$ARGV[1]); TRACE("ARG2 : ".$ARGV[2]); TRACE("ARG3 : ".$ARGV[3]); TRACE("ARG4 : ".$ARGV[4]); TRACE("ARG5 : ".$ARGV[5]); TRACE("ARG6 : ".$ARGV[6]); TRACE("ORACLE_HOME : ".$ENV{'ORACLE_HOME'}); TRACE("EMDROOT : ".$ENV{'EMDROOT'}); TRACE("advert_dir : $advert_dir"); #################################################### # Check to see if the collector is disabled #################################################### $statusfile = $advert_dir . "nmc.status"; TRACE("statusfile : $statusfile"); ################################ ## This status setting is ignored. ################################ $status = "disable"; if ($resume == 0) { EMAGENT_PERL_DEBUG("using status from $statusfile"); open(SFP, $statusfile); $status = ; close(SFP); } else { ################################ ## resume: (== enable:) ################################ EMAGENT_PERL_DEBUG("resuming SGA metric collection"); $status = "enable"; } if ($status eq "stopped") { # The collector has been stopped by other process, # but failed to kill the process. EMAGENT_PERL_DEBUG("Collector was stopped, killing running process..."); $rpidval = getsgapid($emdhome, $connstr); $result = killCollector($rpidval, $statusfile); $status = "disable"; } if($status =~ m/ERROR/ || $status eq "") { # This is the default behavior $status = "disable"; EMAGENT_PERL_DEBUG("falling back to default status: $status"); } TRACE("status = ". $status); EMAGENT_PERL_INFO("status = $status"); if ($cmd eq "status") { ################################ ## status: ################################ TRACE("em_result = ". $status); print "em_result="; print $status; EMAGENT_PERL_DEBUG("requesting status only; exiting."); exit; } #################################################### # Check to see if someone is monitoring DB already # If so, exit #################################################### $rpidval = getsgapid($emdhome, $connstr); if ($cmd eq "stop") { ################################ ## stop: ################################ EMAGENT_PERL_DEBUG("stopping nmccollector..."); $res = killCollector($rpidval, $statusfile); if ($res == -1) { EMAGENT_PERL_DEBUG("no nmccollector process"); $result = "no nmccollector process"; } elsif ($res == 0) { EMAGENT_PERL_DEBUG("failed to kill nmccollector [pid=$rpid]"); $result = "failed to kill nmccollector pid=" . $rpid; } elsif ($res == 1){ EMAGENT_PERL_DEBUG("killed nmccollector [pid=$rpid]"); $result = "killed nmccollector pid=" . $rpid; } TRACE("em_result=".$result); print "em_result="; print $result; EMAGENT_PERL_DEBUG("nmccollector stopped; exiting."); exit; } if ($status eq "disable") { ################################ ## disable: ################################ $result = "collector is disabled."; TRACE("em_result=".$result); print "em_result="; print $result; EMAGENT_PERL_DEBUG("nmccollector disabled; exiting."); exit; } ################################ ## enable: ################################ writeStatus($statusfile, "enable"); if (!($rpidval eq "")) { ################################ ## nmccollector process found; don't restart it. ################################ $result = "collector has already started. pid=".$rpidval; TRACE("em_result=".$result); print "em_result="; print $result; EMAGENT_PERL_DEBUG("nmccollector is alread running [pid=$rpidval]; exiting."); exit; } if($NT) { if ($resume) { TRACE("collector will start in next sga_start."); $result = "enabled."; TRACE("em_result=".$result); print "em_result="; print $result; exit; } } ############################################################### # If process not found, then collector ought to be (re)started ############################################################### TRACE("collector not found. restarting it."); EMAGENT_PERL_INFO("nmccollector not found; restarting it..."); chdir($advert_dir) || die "Cannot chdir $advert_dir: $!"; EMAGENT_PERL_DEBUG("current working directory: $advert_dir"); if($NT) { $binhome = $emdhome."/bin/nmccollector ".$collmode." ".$connstr." ".$advert_dir." ".$advert_dir." ".$msg_dir; } else { # In order to support database upgrade, relink it everytime this script # is invoked. my $makefilename; my $libserverloc = $targetorahome; my $makedestloc = $myorahome; my $makebinary; my $uname = `uname`; chomp ($uname); if($uname =~ m/HP-UX/) { $makebinary = '/usr/ccs/bin/make'; } else { $makebinary = 'make'; } EMAGENT_PERL_INFO("nmccollector does not exist; relinking..."); TRACE("nmccollector does not exist. building..."); $makefilename1 = $myorahome."/sysman/lib/ins_emagent.mk"; $makefilename2 = $myorahome."/emagent/lib/ins_emagent2.mk"; TRACE("looking for $makefilename1"); TRACE("looking for $makefilename2"); if(-e $makefilename1) { TRACE("makefile $makefilename1"); $makefilename = $makefilename1; $libserverloc .= "/lib/"; $makedestloc .= "/bin/"; } elsif(-e $makefilename2) { TRACE("makefile $makefilename2"); $makefilename = $makefilename2; $libserverloc .= "/rdbms/lib/"; $makedestloc .= "/emagent/bin/"; } else { EMAGENT_PERL_ERROR("cannot find emagent install makefiles in $makefilename1 or $makefilename2; exiting."); die "Cannot find ins_emagentx makefiles in $makefilename1 or $makefilename2"; } my $libclientline; my $libversion; if ($myversion ne "10gR203") { ################################ ## For 11g and later, we need to link with the 11g client library ## and with LD_LIBRARY_PATH set specially. ################################ my $oldlibpath = trim($ENV{'LD_LIBRARY_PATH'}); $ENV{'LD_LIBRARY_PATH'} = $targetorahome."/lib:".$oldlibpath; $libclientline = " \"LIBCLNTSH=".$targetorahome."/lib/libclntsh.so\" "; $libversion = "11"; } else { $libclientline = ""; $libversion = "10"; } $dsgaline = " \"DSGALIB=".$targetorahome."/rdbms/lib/libdsga$libversion.a\" "; $libserverline = " \"LIBSERVER=".$libserverloc."libserver$libversion.a\" "; $linkline = " \"RDBMSLIBHOME=".$targetorahome."/lib/\" ". " \"RDBMSORACLELIB=-L".$targetorahome."/lib/\" "; $makecommand = "$makebinary -f ".$makefilename." collector ".$libclientline.$dsgaline.$libserverline.$linkline; EMAGENT_PERL_DEBUG("issuing make command [$makecommand]"); EMAGENT_PERL_DEBUG('$ORACLE_HOME: '.$ENV{'ORACLE_HOME'}); EMAGENT_PERL_DEBUG('$ORA_SID: '.$ENV{'ORA_SID'}); EMAGENT_PERL_DEBUG('$ORACLE_SID: '.$ENV{'ORACLE_SID'}); EMAGENT_PERL_DEBUG('$LD_LIBRARY_PATH: '.$ENV{'LD_LIBRARY_PATH'}); if (system($makecommand)) { EMAGENT_PERL_ERROR("nmccollector relinking failed!"); } else { $movecommand = "mv ".$makedestloc."nmccollector nmccollector"; EMAGENT_PERL_DEBUG("issuing mv command [$movecommand]"); system($movecommand); } my $nmcbinary = "./nmccollector"; if (!(-e $nmcbinary)) { ################################ ## There is no nmccollector binary to run. Might as well exit. ################################ EMAGENT_PERL_ERROR("nmccollector does not exist"); exit; } $binhome = $nmcbinary." ".$collmode." \'".$connstr."\' ".$advert_dir." ".$advert_dir." ".$msg_dir; $ENV{'ORACLE_HOME'} = $targetorahome; $ENV{'ORA_SID'} = $sidname; $ENV{'ORACLE_SID'} = $sidname; $oldlibpath = trim($ENV{'LD_LIBRARY_PATH'}); $newlibpath = $targetorahome."/lib:".$oldlibpath; $ENV{'LD_LIBRARY_PATH'} = $newlibpath; } ################################ ## We haven't aborted or exited normally so far. That must mean that the ## nmccollector should be started up. ################################ TRACE($binhome); if(!$NT) { EMAGENT_PERL_DEBUG("spawning nmccollector"); if (!defined($child_pid = fork())) { die "cannot fork: $!"; } elsif ($child_pid) { ################################ ## Note: This is not the nmccollector process. Rather, it's the process ## that spawns the nmccollector process below. ################################ EMAGENT_PERL_DEBUG("nmccollector spawner process [pid=$child_pid] spawned; parent process exiting."); TRACE("em_result=$child_pid"); print "em_result="; exit; } else { ################################ ## This is the spawned child. ################################ sleep 10; POSIX::setsid() or die "Can't start a new session: $!"; umask(027); close STDIN or die "Can't close STDIN"; close STDOUT or die "Can't close STDOUT"; close STDERR or die "Can't close STDERR"; $ENV{'ORACLE_HOME'} = $targetorahome; $ENV{'ORA_SID'} = $sidname; $ENV{'ORACLE_SID'} = $sidname; EMAGENT_PERL_DEBUG("execing nmccollector [$binhome]..."); EMAGENT_PERL_DEBUG('$ORACLE_HOME: '.$ENV{'ORACLE_HOME'}); EMAGENT_PERL_DEBUG('$ORA_SID: '.$ENV{'ORA_SID'}); EMAGENT_PERL_DEBUG('$ORACLE_SID: '.$ENV{'ORACLE_SID'}); EMAGENT_PERL_DEBUG('$LD_LIBRARY_PATH: '.$ENV{'LD_LIBRARY_PATH'}); my $nmcpid = open(PROCWRITE, "| ".$binhome); if (!defined($nmcpid)) { EMAGENT_PERL_ERROR("could not exec nmccollector; exiting."); die "Could not start collector"; } elsif ($nmcpid) { ################################ ## Note: Just because we got here doesn't mean necessarily that the ## exec-ed process will run properly. ## But if it does, this trace line tells us the pid. ################################ EMAGENT_PERL_DEBUG("nmccollector exec-ed [pid=$nmcpid]"); print PROCWRITE $username." ".$password." "; } close(PROCWRITE); } } else { require Win32::Process; close STDIN or die "Can't close STDIN"; close STDERR or die "Can't close STDERR"; pipe(READ, WRITE); select(WRITE); $| = 1; select(READ); $| = 1; open(STDIN, "<&READ") or die "Can't redirect STDIN: $!"; open(BLAH, ">BLAH.TXT"); print BLAH $binhome; print BLAH $emdhome; close(BLAH); Win32::Process::Create($Process, $emdhome."/bin/nmccollector.exe", $binhome, 1, NORMAL_PRIORITY_CLASS, "."); print WRITE "$username $password "; print WRITE "\n"; close READ or die "Can't close pipe READ: $!"; close WRITE or die "Can't close pipe WRITE: $!"; close STDOUT or die "Can't close STDOUT"; } sub killCollector { my $rpid = $_[0]; my $sfile = $_[1]; EMAGENT_PERL_DEBUG("killing collector $rpid"); $res = -1; if ($rpid != "") { $res = kill 9, $rpid; } if ($res) { EMAGENT_PERL_DEBUG("nmccollector stopped and killed"); writeStatus($sfile, "disable"); } else { EMAGENT_PERL_DEBUG("nmccollector stopped but not killed"); writeStatus($sfile, "stopped"); } return $res; } sub writeStatus { my $sfile = $_[0]; my $s = $_[1]; TRACE("writing ". $s ." in statusfile $sfile"); open(SFP, ">$sfile"); print SFP $s; close(SFP); }