#!/usr/local/bin/perl # # $Header: dbAdrUtil.pl 28-sep-2007.14:33:42 jsoule Exp $ # # dbAdrUtil.pl # # Copyright (c) 2006, 2008, Oracle. All rights reserved. # # NAME # dbAdrUtil.pl - database ADR utilities # # DESCRIPTION # Utilities for accessing ADR for database # # NOTES # # # MODIFIED (MM/DD/YY) # dchakumk 03/10/08 - XbranchMerge dchakumk_6752_xbmsrc from # st_emdbsa_11.1 # jsoule 09/28/07 - add ASM sid routine # loliu 02/19/07 - Creation require "emd_common.pl"; use strict; use DBI; # Return the value for a given key in the v$diag_info table for # the database diagnostic framework sub get_diag_info_from_db { # the key for which to look up information from v$diag_info my ($param_key) = @_; my $param_value = undef; # For TESTING: comment out stdin args my %stdinArgs = get_stdinvars(); my $username = $stdinArgs{"EM_TARGET_USERNAME"}; my $password = $stdinArgs{"EM_TARGET_PASSWORD"}; my $address = $ENV{EM_TARGET_ADDRESS}; my $role = $ENV{EM_TARGET_ROLE}; # For TESTING: un-comment for manual testing and fill in the values # my $username = ""; # my $password = ""; # my $address = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=))(CONNECT_DATA=(SID=)))"; # my $role = ""; my $mode = 0; if($role =~ /SYSDBA/i) { $mode = 2; } elsif($role =~ /SYSOPER/i) { $mode = 4; } # -------------------------------------------------------------------- # +++ Establish Target DB Connection # -------------------------------------------------------------------- my $dbh = DBI->connect('dbi:Oracle:', "$username@".$address, "$password", {ora_session_mode => $mode, PrintError => 0, RaiseError => 0, AutoCommit => 0}); if (!$dbh) { EMD_PERL_WARN("get_diag_info_from_db: Could not connect to $username/$address: $DBI::errstr"); return $param_value; } register_metric_call($dbh); # Since v$diag_info contains information for the database instance we # are connecting to, we don't need to select on INST_ID, which is needed # if we were joining gv$diag_info and v$instance my $sql = "select VALUE from v\$diag_info where NAME=?"; my $sth = $dbh->prepare($sql); if (!$sth) { EMD_PERL_WARN("get_diag_info_from_db: prepare($sql) failed: $DBI::errstr"); return $param_value; } my $rc = $sth->execute($param_key); if (!$rc) { EMD_PERL_WARN("get_diag_info_from_db: execute($param_key) failed: $DBI::errstr"); return $param_value; } my @fetched_rows; @fetched_rows = $sth->fetchrow_array(); if (@fetched_rows != 1) { EMD_PERL_WARN("get_diag_info_from_db: @fetched_rows rows are returned"); } $param_value = $fetched_rows[0]; EMD_PERL_DEBUG("get_diag_info_from_db: diag_info $param_key=$param_value"); $sth->finish(); $dbh->disconnect; return $param_value; } # # Function: get_asm_sid_from_db # # Return: the value for the instance name of the ASM for which this database # is an asm_client -- (empty string for 'not a client') # sub get_asm_sid_from_db { my $asm_sid = ""; my %stdinArgs = get_stdinvars(); my $username = $stdinArgs{"EM_TARGET_USERNAME"}; my $password = $stdinArgs{"EM_TARGET_PASSWORD"}; my $address = $ENV{EM_TARGET_ADDRESS}; my $role = $ENV{EM_TARGET_ROLE}; my $mode = 0; if ($role =~ /SYSDBA/i) { $mode = 2; } elsif ($role =~ /SYSOPER/i) { $mode = 4; } # -------------------------------------------------------------------- # +++ Establish Target DB Connection # -------------------------------------------------------------------- my $dbh = DBI->connect('dbi:Oracle:', "$username@".$address, "$password", { ora_session_mode => $mode, PrintError => 0, RaiseError => 0, AutoCommit => 0}); if (!$dbh) { EMD_PERL_WARN("get_asm_sid_from_db: ". "Could not connect to $username/$address: ". $DBI::errstr); return $asm_sid; } register_metric_call($dbh); # (We don't have to deal with empty v$asm_client view specially.) my $sql = "select instance_name from v\$asm_client where rownum <= 1"; my $sth = $dbh->prepare($sql); if ($sth) { my $rc = $sth->execute; if ($rc) { my @fetched_row; @fetched_row = $sth->fetchrow_array(); if (@fetched_row > 0) { $asm_sid = $fetched_row[0]; } elsif ($sth->err) { EMD_PERL_WARN("get_asm_sid_from_db: ". "fetch failed: ". $DBI::errstr); } } else { EMD_PERL_WARN("get_asm_sid_from_db: ". "execute failed: ". $DBI::errstr); } } else { EMD_PERL_WARN("get_asm_sid_from_db: ". "prepare($sql) failed: ". $DBI::errstr); } EMD_PERL_DEBUG("get_asm_sid_from_db: asm_client instance_name=$asm_sid"); $sth->finish(); $dbh->disconnect; return $asm_sid; } # Return the name of the state file using the given suffix sub get_state_file_name { my ($suffix) = @_; my $target_guid = $ENV{EM_TARGET_GUID}; my $state_root = $ENV{EM_AGENT_STATE_DIR}; # build the fully qualify state file path my $separator = $^O =~ m/MSWin32/ ? "\\" : "\/"; # location of the state file is # $EMDROOT/sysman/emd/state/adr/. my $adrStateDir = $state_root.$separator."sysman".$separator."emd".$separator."state".$separator."adr"; # create ADR state directory if directory does not exist # OK to "die" here since the user needs to fix the file permission if (!(-e $adrStateDir)) { mkdir $adrStateDir or die "em_error=Cannot create $adrStateDir"; } my $state_file = $adrStateDir.$separator."$target_guid.$suffix"; EMD_PERL_DEBUG("get_state_file_name: $state_file"); return $state_file; } # If the state value is defined, save it in a state file using the given # file name suffix. Otherwise, read the previous state value from the state # file and return it. # # Arguments: $_[0] - the state to save # $_[1] - the file name suffix # $_[2] - (optional) flag to indicate state is not a directory # default value is false (is a directory) sub read_or_save_state { my ($state, $suffix, $nondir) = @_; my $state_file = get_state_file_name($suffix); my $new_state = $state; # save state if defined if (($nondir && $state) || -d $state) { # open state file and write out the state if (open (STATE, "+> $state_file")) { print STATE "$state\n"; close STATE; EMAGENT_PERL_DEBUG("saved $state to $state_file"); } } # read state from state file else { if (open(STATE, "< $state_file")) { while () { chomp; $new_state = $_; } close STATE; EMAGENT_PERL_DEBUG("read \'$new_state\' from $state_file"); } } return $new_state; } 1;