# Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. # # NAME # asmcmdafd - ASM CoMmanD line interface (AFD Module) # # DESCRIPTION # This module contains all the AFD(ASM Filter Driver) related commands. # # NOTES # usage: asmcmdcore [-p] [command] # # MODIFIED (MM/DD/YY) # prabbala 03/27/17 - 25825910: use asmcmdshare_runcmd in sub _isSUSELinux # siyarlag 07/12/16 - 23700550: no member cluster check if --init # siyarlag 06/21/16 - 23616155: check state of afd before command exec # siyarlag 05/31/16 - 23495544: trim domain from hostname # diguzman 05/30/16 - 19654070 Little change at _no_instance_cmd routine # siyarlag 05/16/16 - 23288546: setup log dirs # siyarlag 05/10/16 - 23129577: let afd_dsset run as root # ssprasad 04/13/16 - Bug/23100725 - Report AFD driver mismatch in afdstate # siyarlag 03/14/16 - disallow label operations on member cluster # siyarlag 02/15/16 - Bug/22472825 - run afd_dsset as GI user # jochoa 12/13/15 - Bug22238113: Make $dskpath have complete argument # without splitting on comma # siyarlag 12/18/15 - add -init option for label set/clear # siyarlag 11/09/15 - Bug/21511801: add afd_refresh and change owner # siyarlag 10/05/15 - afd_deconfigure with force # siyarlag 08/20/15 - Bug/21663398: sles fixes # siyarlag 08/03/15 - Bug/21544924: fix command mismatch # siyarlag 07/21/15 - Bug/21482687: fix afdconfigure # siyarlag 06/30/15 - Bug/21244596: miscellaneous fixes # ssprasad 06/22/15 - #21206502: DI not supported msg for Solaris # siyarlag 06/08/15 - srge dif issue - retrun true # siyarlag 05/20/15 - creation # siyarlag 05/11/15 - Bug/21116936: fix label set, disallow afd on exadata # siyarlag 04/02/15 - Bug/19700132: make afd commands clusterwide # ssprasad 03/09/15 - Change afd.conf to oracleafd.conf # siyarlag 01/08/15 - Bug/20307737: print msg based on return code # siyarlag 12/04/14 - Bug/18838998: display if no device to label # siyarlag 07/30/14 - Bug/19326908: use HAS commands for SIHA # alolau 06/10/14 - Add afd_di # siyarlag 06/24/14 - Bug/19035573: use afdtool always to update afd conf # siyarlag 05/29/14 - Bug/18865657: add afd_scan # pvenkatr 01/22/14 - Bug # 18136383 Added afd commands # siyarlag 05/21/14 - Bug/18812974: add afd_filter afd_lsdsk # siyarlag 04/16/14 - Bug/18430406: add afd_configure afd_deconfigure # afd_state # pvenkatr 01/22/14 - Bug # 18136383 Added AFD commands # afd_dsget/afd_dsset/afd_label/afd_unlabel # ############################################################################ # ############################ Functions List ################################# # ############################################################################# package asmcmdafd; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(asmcmdafd_init %asmcmdafd_cmds ); use strict; use DBI qw(:sql_types); use Getopt::Long qw(:config no_ignore_case bundling); use asmcmdglobal; use asmcmdshare; use asmcmdparser; use asmcmdbase; use List::Util qw[min max]; use File::Find; use File::Spec; use File::Spec::Functions; use File::Copy; use Sys::Hostname; ####################### ASMCMDAFD Global Constants ###################### our ($ASMCMDAFD_SQLPLUS) = "$ENV{'ORACLE_HOME'}/bin/sqlplus -S / as sysasm"; # SQLPLUS command with appropriage roles. our ($ASMCMDAFD_SQLPLUS_SYSASM) = "$ENV{'ORACLE_HOME'}/bin/sqlplus -S / as sysasm"; our ($ASMCMDAFD_SQLPLUS_SYSDBA) = "$ENV{'ORACLE_HOME'}/bin/sqlplus -S / as sysdba"; our ($ASMCMDAFD_SQLPLUS_SYSOPER) = "$ENV{'ORACLE_HOME'}/bin/sqlplus -S / as sysoper" ; ####################### ASMCMDAFD Global Variables ###################### our (%asmcmdafd_cmds) = (afd_configure => {}, afd_deconfigure => {}, afd_dsset => {}, afd_dsget => {}, afd_filter => {}, afd_label => {}, afd_lsdsk => {}, afd_lslbl => {}, afd_refresh => {}, afd_scan => {}, afd_unlabel => {}, afd_state => {}, afd_di => {} ); # init script constants our $INITD; our $RCSDIR; our $RCKDIR; our $RCALLDIR; our $RC_START; our $RC_KILL; our $RC_KILL_OLD; our $RC_KILL_OLD2; our $IT; our $INIT; our $OCRLOC; our $AFDDISKLOC; our $SU; if ($^O =~ /linux/i) { $INITD = "/etc/init.d"; $RCSDIR = "/etc/rc.d/rc3.d /etc/rc.d/rc5.d"; $RCKDIR = "/etc/rc.d/rc0.d /etc/rc.d/rc1.d /etc/rc.d/rc2.d /etc/rc.d/rc4.d"; $RCKDIR = $RCKDIR . " /etc/rc.d/rc6.d"; $RCALLDIR ="/etc/rc.d/rc0.d /etc/rc.d/rc1.d /etc/rc.d/rc2.d /etc/rc.d/rc3.d"; $RCALLDIR = $RCALLDIR . " /etc/rc.d/rc4.d /etc/rc.d/rc5.d /etc/rc.d/rc6.d"; $RC_START = "S96"; $RC_KILL = "K15"; $RC_KILL_OLD = "K96"; $RC_KILL_OLD2 = "K19"; $IT = "/etc/inittab"; $INIT = "/usr/sbin/init"; $OCRLOC = "/etc/oracle/ocr.loc"; $AFDDISKLOC = "/dev/oracleafd/disks"; $SU = "/bin/su"; } elsif ($^O =~ /solaris/i) { $INITD = "/etc/init.d"; $RCSDIR = "/etc/rc3.d"; $RCKDIR = "/etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rcS.d"; $RCALLDIR ="/etc/rc.d/rc0.d /etc/rc.d/rc1.d /etc/rc.d/rc2.d /etc/rc.d/rc3.d"; $RCALLDIR = $RCALLDIR ." /etc/rc.d/rcS.d"; $RC_START = "S96"; $RC_KILL = "K19"; $RC_KILL_OLD = "K96"; $IT = "/etc/inittab"; $INIT = "/sbin/init"; $OCRLOC = "/var/opt/oracle/ocr.loc"; $AFDDISKLOC = "/var/opt/oracle/oracleafd/disks"; $SU = "/usr/bin/su"; } elsif ($^O =~ /aix/i) { $INITD = "/etc"; $RCSDIR = "/etc/rc.d/rc2.d"; $RCKDIR = "/etc/rc.d/rc2.d"; $RCALLDIR = "/etc/rc.d/rc2.d"; $RC_START = "S96"; $RC_KILL = "K19"; $RC_KILL_OLD = "K96"; $IT = "/etc/inittab"; $INIT = "/usr/sbin/init"; $OCRLOC = "/var/opt/oracle/ocr.loc"; $AFDDISKLOC = "/var/opt/oracle/oracleafd/disks"; $SU = "/bin/su"; } elsif(!($^O =~ /win/i)) { $AFDDISKLOC = "\\\\.\\ORACLEAFD"; } sub is_asmcmd { return 1; } ######## # NAME # asmcmdafd_init # # DESCRIPTION # This function initializes the asmcmdafd module. For now it simply # registers its callbacks with the asmcmdglobal module. # # PARAMETERS # None # # RETURNS # Null # # NOTES # Only asmcmdcore_main() calls this routine. ######## sub init { # All of the arrays defined in the asmcmdglobal module must be # initialized here. Otherwise, an internal error will result. push (@asmcmdglobal_command_callbacks, \&asmcmdafd_process_cmd); push (@asmcmdglobal_help_callbacks, \&asmcmdafd_process_help); push (@asmcmdglobal_command_list_callbacks, \&asmcmdafd_get_asmcmd_cmds); push (@asmcmdglobal_is_command_callbacks, \&asmcmdafd_is_cmd); push (@asmcmdglobal_is_wildcard_callbacks, \&asmcmdafd_is_wildcard_cmd); push (@asmcmdglobal_syntax_error_callbacks, \&asmcmdafd_syntax_error); push (@asmcmdglobal_no_instance_callbacks, \&asmcmdafd_is_no_instance_cmd); %asmcmdglobal_cmds = (%asmcmdglobal_cmds, %asmcmdafd_cmds); #Perform ASMCMD consistency check if enabled if($asmcmdglobal_hash{'consistchk'} eq 'y') { if(!asmcmdshare_check_option_consistency(%asmcmdafd_cmds)) { exit 1; } } } ######## # NAME # asmcmdafd_process_cmd # # DESCRIPTION # This routine calls the appropriate routine to process the command # specified by $asmcmdglobal_hash{'cmd'}. # # PARAMETERS # dbh (IN) - initialized database handle, must be non-null. # # RETURNS # 1 if command is found in the asmcmdafd module; 0 if not. # # NOTES # Only asmcmdcore_shell() calls this routine. ######## sub asmcmdafd_process_cmd { my ($dbh) = @_; my ($succ) = 0; # Get current command from global value, which is set by # asmcmdafd_parse_asmcmd_args()and by asmcmdcore_shell(). my ($cmd) = $asmcmdglobal_hash{'cmd'}; # Declare and initialize hash of function pointers, each designating a # routine that processes an ASMCMDAFD command. my (%cmdhash) = ( afd_configure => \&asmcmdafd_process_afdconfigure, afd_deconfigure => \&asmcmdafd_process_afddeconfigure, afd_dsset => \&asmcmdafd_process_afddsset, afd_dsget => \&asmcmdafd_process_afddsget, afd_filter => \&asmcmdafd_process_afdfilter, afd_label => \&asmcmdafd_process_afdsetlabel, afd_lsdsk => \&asmcmdafd_process_afdlsdsk, afd_lslbl => \&asmcmdafd_process_afdlslbl, afd_refresh => \&asmcmdafd_process_afdrefresh, afd_scan => \&asmcmdafd_process_afdscan, afd_unlabel => \&asmcmdafd_process_afdclrlabel, afd_state => \&asmcmdafd_process_afdstate, afd_di => \&asmcmdafd_process_afddi); if (defined ( $cmdhash{ $cmd } )) { # If user specifies a known command, then call routine to process it. # $cmdhash{ $cmd }->($dbh); $succ = 1; } return $succ; } ######## # NAME # asmcmdafd_process_afdconfigure # # DESCRIPTION # To configure AFD on the local node # # PARAMETER # -d - disable AFD filtering mode # -e - enable AFD filtering mode # -f - force AFD configuration # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdconfigure { my ($dbh) = @_; my ($path); my ($ret); my (%args); my (@eargs); my ($buf); my ($asmlib); my ($asmlibexists) = 0; my ($efilter) = 0; my ($dfilter) = 0; my ($force) = 0; $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); $efilter = $args{'e'}; $dfilter = $args{'d'}; $force = $args{'f'}; if ($force) { asmcmdshare_trace(3, "NOTE: afd_configure 'force' option used", 'y', 'n'); } # Bug 21058846: AFD is not supported on Exadata if (asmcmdafd_is_exadata()) { #9520-"AFD is not '%s'" @eargs = "supported"; asmcmdshare_error_msg(9520, \@eargs); return; } # 0. Check for ASMLIB presence on Linux if (($^O =~ /linux/i)) { my $dir = "/opt/oracle/extapi"; if (-e "$dir") { open (ASMLIB, "find /opt/oracle/extapi/ | grep libasm.so |"); while ($asmlib = ) { $asmlibexists = 1; } close(ASMLIB); } open (ASMLIB, "/sbin/lsmod | grep oracleasm |"); while ($asmlib = ) { $asmlibexists = 1; } close(ASMLIB); if ($asmlibexists) { my $asm_dis; $asm_dis = asmcmdafd_get_asmdiskstr_fromprofile(); if ($asm_dis) { asmcmdshare_trace(3, "NOTE: ASMLib present; asm diskstring : $asm_dis", 'y', 'n'); #9519-"ASMLib is present; command requires blank ASM disk string" @eargs = ($asm_dis); asmcmdshare_error_msg(9519, \@eargs); return; } } } # 1. Check if AFD is supported and not loaded. # Skipping is_afd_supported on a system with asmlib exists. if ((!$asmlibexists) && (!asmcmdafd_is_afd("supported"))) { #9520-"AFD is not '%s'" @eargs = "supported"; asmcmdshare_error_msg(9520, \@eargs); return; } # 2. Verify that the command is run as 'root' and clusterware is down if (!asmcmdafd_am_root()) { #9522-"command requires Root access" asmcmdshare_error_msg(9522); return; } if (!asmcmdafd_is_cluster_down()) { #9523-"command cannot be used when Oracle Clusterware stack is up" asmcmdshare_error_msg(9523); return; } if ((!$force) && (asmcmdafd_is_afd("loaded"))) { # start OHASD if (!asmcmdafd_ohasd("start")) { #9524-"AFD configuration failed" @eargs = "ERROR: OHASD start failed"; asmcmdshare_error_msg(9524, \@eargs); return; } # Even if AFD is loaded on the node, check if its resource is present. if (asmcmdafd_afd_resource("status")) { #9527-"AFD is loaded, but resource ora.driver.afd does not exist" asmcmdshare_error_msg(9527); } else { #9521-"AFD is already configured" asmcmdshare_error_msg(9521); } # stop OHASD if (!asmcmdafd_ohasd("stop")) { #9524-"AFD configuration failed" @eargs = "ERROR: OHASD stop failed"; asmcmdshare_error_msg(9524, \@eargs); return; } return; } # 3. Handle ASMLib if configured. $asmlibexists = asmcmdafd_handle_asmlib(); if ($asmlibexists == 2) { #9524-"AFD configuration failed" @eargs = "ERROR: ASMLib deconfiguration failed"; asmcmdshare_error_msg(9524, \@eargs); return; } # 4. Install AFD if (!asmcmdafd_afdroot("install")) { #9524-"AFD configuration failed" @eargs = "ERROR: afdroot install failed"; asmcmdshare_error_msg(9524, \@eargs); return; } # 5. - Update oracleafd.conf using kfod op=GPNP if (!asmcmdafd_update_afd_conf()) { #9524-"AFD configuration failed" @eargs = "ERROR: update of oracleafd.conf file failed"; asmcmdshare_error_msg(9524, \@eargs); return; } else { # Enable filtering if "-e" if ($efilter) { asmcmdafd_afdfilter("enable", ""); } # Disable filtering if "-d" if ($dfilter) { asmcmdafd_afdfilter("disable", ""); } } # 6. If ASMLib was present in the system and we removed it before installing # AFD, then perform a rescan of the system for any ASMLib disks to be # be managed by AFD. if ($asmlibexists) { my ($dfltstr) = "/dev/sd*"; asmcmdafd_rescan_afd("$dfltstr"); } else { asmcmdafd_rescan_afd(); } # 7. - create init scripts if(!($^O =~ /win/i)) { if (!asmcmdafd_copy_afdinit()) { #9524-"AFD configuration failed" @eargs = "ERROR: copying afd init scripts to init directory failed"; asmcmdshare_error_msg(9524, \@eargs); return; } } asmcmdshare_print("Modifying resource dependencies". " - this may take some time.\n"); # 8. start OHASD with -noautostart option. This starts only the OHASD. if (!asmcmdafd_ohasd("start")) { #9524-"AFD configuration failed" @eargs = "ERROR: OHASD start failed"; asmcmdshare_error_msg(9524, \@eargs); return; } # 9. check and create ora.driver.afd OHASD resource if (!asmcmdafd_afd_resource("add")) { #9524-"AFD configuration failed" @eargs = "ERROR: AFD resource add failed"; asmcmdshare_error_msg(9524, \@eargs); return; } # 10. Add a START dependency. Modify ora.cssd resource attributes. if (!asmcmdafd_modify_resource("add")) { #9524-"AFD configuration failed" @eargs = "ERROR: AFD resource modify failed"; asmcmdshare_error_msg(9524, \@eargs); return; } # 11. stop OHASD if (!asmcmdafd_ohasd("stop")) { #9524-"AFD configuration failed" @eargs = "ERROR: OHASD stop failed"; asmcmdshare_error_msg(9524, \@eargs); return; } } ######## # NAME # asmcmdafd_process_afddeconfigure # # DESCRIPTION # To deconfigure AFD from the local node # # PARAMETER # NONE # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afddeconfigure { my ($dbh) = @_; my ($path); my ($ret); my (%args); my (@eargs); my $afd_conf = "/etc/oracleafd.conf"; my ($force) = 0; $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); $force = $args{'f'}; if ($force) { asmcmdshare_trace(3,"NOTE: afd_deconfigure 'force' option used", 'y', 'n'); } if($^O =~ /win/i) { ($afd_conf) = "$ENV{SYSTEMROOT}\\system32\\drivers\\oracleafd.conf"; } $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # 0. Bug 21058846: AFD is not supported on Exadata if (asmcmdafd_is_exadata()) { #9520-"AFD is not '%s'" @eargs = "supported"; asmcmdshare_error_msg(9520, \@eargs); return; } # 1. is supported check if (!asmcmdafd_is_afd("supported")) { #9520-"AFD is not '%s'" @eargs = "Supported"; asmcmdshare_error_msg(9520, \@eargs); return; } # 2. Verify that the command is run as 'root', clusterware is down and # AFD is configured. if (!asmcmdafd_am_root()) { #9522-"command requires Root access" asmcmdshare_error_msg(9522); return; } # 3. check if AFD is installed on the node if ((!$force) && (!asmcmdafd_is_afd("installed"))) { #9520-"AFD is not '%s'" @eargs = "installed"; asmcmdshare_error_msg(9520, \@eargs); return; } # 4. Check if cluster stack is down and ACFS driver is not loaded if (!asmcmdafd_is_cluster_down()) { #9523-"command cannot be used when Oracle Clusterware stack is up" asmcmdshare_error_msg(9523); return; } # if acfs driver is in loaded state we can't uninstall AFD if (asmcmdafd_is_acfs("loaded")) { #9525-"AFD deconfiguration failed" @eargs = "ERROR: acfs driver is loaded"; asmcmdshare_error_msg(9525, \@eargs); return; } # 5. uninstall AFD driver if (!asmcmdafd_afdroot("uninstall")) { #9525-"AFD deconfiguration failed" @eargs = "ERROR: afdroot uninstall failed"; asmcmdshare_error_msg(9525, \@eargs); return; } # 6. remove oracleafd.conf file if (-e "$afd_conf") { unlink("$afd_conf"); } # 7. remove init scripts if(!($^O =~ /win/i)) { asmcmdafd_rm_afdinit_init(); asmcmdafd_rm_afdinit_rclevel(); } asmcmdshare_print("Modifying resource dependencies". " - this may take some time.\n"); # 8. start OHASD with -noautostart option. This starts only the OHASD. if (!asmcmdafd_ohasd("start")) { #9525-"AFD deconfiguration failed" @eargs = "ERROR: OHASD start failed"; asmcmdshare_error_msg(9525, \@eargs); return; } # 9. delete ora.driver.afd dependency in ora.cssd resource if ((!asmcmdafd_modify_resource("delete")) && (!$force)) { #9525-"AFD deconfiguration failed" @eargs = "ERROR: AFD resource modify failed"; asmcmdshare_error_msg(9525, \@eargs); return; } # 10. delete ora.driver.afd resource if ((!asmcmdafd_afd_resource("delete")) && (!$force)) { #9525-"AFD deconfiguration failed" @eargs = "ERROR: AFD resource delete failed"; asmcmdshare_error_msg(9525, \@eargs); return; } # 11. stop OHASD if (!asmcmdafd_ohasd("stop")) { #9525-"AFD deconfiguration failed" @eargs = "ERROR: OHASD stop failed"; asmcmdshare_error_msg(9525, \@eargs); return; } } ######## # NAME # asmcmdafd_process_afddsset # # DESCRIPTION # To set the AFD Discovery Disksstring # # PARAMETER # $dbh (IN) - initiatized database handle, must be non-null. # <--all> - Set clusterwide AFD discovery diskstring. # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afddsset { my ($dbh) = @_; my ($path); my ($ret); my (%args); my (@eargs); my (@buf); my ($afdtool); my ($afdtoolafdds); my ($line); my ($giusr) = ""; my ($oraclebin) = "$ENV{'ORACLE_HOME'}/bin/oracle"; $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # Get the AFD Discovery diskstring $path = join(',', @{$args{'afd_dsset'}}); # is AFD supported check if (!asmcmdafd_is_afd("supported")) { #9520-"AFD is not '%s'" @eargs = "Supported"; asmcmdshare_error_msg(9520, \@eargs); return; } if ($args{'all'}) { # if AFD diskstring set requested on all the cluster nodes if (asmcmdafd_request_action("afdtool", "all", "KEYWORD=\'-afdds\' ARG1=\'update\' ARG2=\'$path\' NARGS=2", \@buf)) { foreach (@buf) { # print output - node '': $line = $_; if ($line =~ /(CRS-4413:.*)/) { if ($line =~ /(.*)from (.*)/) { asmcmdshare_print("$2\n"); } } else { asmcmdshare_print("$_"); } } } return; } # if afd disksting set on local node $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; asmcmdshare_trace(3, "NOTE: afdtool -afdds update '$path'", 'y', 'n'); $afdtoolafdds = "$afdtool -afdds update '$path'"; $ret = asmcmdshare_runcmd($afdtoolafdds, \@buf, 0, 0); if ($ret) { if (@buf) { asmcmdshare_trace(3, "FAIL: " . join('', @buf), 'y', 'n'); asmcmdshare_print(join('', @buf)); } asmcmdshare_error_msg (9512, undef); } return; } ######## # NAME # asmcmdafd_process_afddsget # # DESCRIPTION # To obtain the current AFD Discovery diskstring # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # <--all> - Get clusterwide AFD discovery diskstring. # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afddsget { my ($dbh) = shift; my ($ret, $val, $row); my (%args); my (@eargs); my (@buf); my ($afdtool); my ($afdtoolafdds); my ($line); my ($giusr) = ""; my ($oraclebin) = "$ENV{'ORACLE_HOME'}/bin/oracle"; $ret = asmcmdafd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # if AFD diskstring get requested from all the cluster nodes if ($args{'all'}) { if (asmcmdafd_request_action("afdtool", "all", "KEYWORD=\'-afdds\' ARG1=\'query\' NARGS=1", \@buf)) { foreach (@buf) { # print output - node '': $line = $_; if ($line =~ /(CRS-4413:.*)/) { if ($line =~ /(.*)from (.*)/) { asmcmdshare_print("$2\n"); } } else { asmcmdshare_print("$_"); } } } return; } # if afd disksting get on local node $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; asmcmdshare_trace(3, "NOTE: afdtool -afdds query", 'y', 'n'); $afdtoolafdds = "$afdtool -afdds query"; if (asmcmdafd_am_root()) { if ($oraclebin) { $giusr = getpwuid((stat($oraclebin))[4]); } $ret = asmcmdafd_runcmd_as_user($afdtoolafdds, $giusr, \@buf); } else { $ret = asmcmdshare_runcmd($afdtoolafdds, \@buf, 1, 0); } if (!$ret) { if (@buf) { # command succeeded asmcmdshare_trace(3, "NOTE: " . join('', @buf), 'y', 'n'); ($val) = grep { /AFD discovery/i } @buf; if ($val) { asmcmdshare_print ("$val"); return; } } } # command failed asmcmdshare_error_msg (9511, undef); return; } ######## # NAME # asmcmdafd_process_afdfilter # # DESCRIPTION # To enable or disable AFD filtering mode. # If the command is executed without specifying a disk path then # filtering is set at node level. # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # # -e - enable AFD filtering mode # -d - disable AFD filtering mode # - OS disk path to set the AFD filtering mode on. # <--all> - set Clusterwide AFD fitlering mode. # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdfilter { my ($dbh) = shift; my ($ret, $val, $row); my (%args); my (@eargs); my ($filter); my ($diskpath); my (@buf); $ret = asmcmdafd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); if ($args{'e'}) { $filter = "enable"; } if ($args{'d'}) { $filter = "disable"; } $diskpath = shift(@{$args{'afd_filter'}}); if ($diskpath) { # verify that OS disk path exists if (! -e $diskpath) { #9528-"disk '%s' does not exist" @eargs = $diskpath; asmcmdshare_error_msg(9528, \@eargs); return; } } else { $diskpath = ""; } if ($args{'all'}) { if ($diskpath eq "") { asmcmdafd_request_action("afdtool", "all", "KEYWORD=\'-filter\' ARG1=\'$filter\' NARGS=1", \@buf); } else { asmcmdafd_request_action("afdtool", "all", "KEYWORD=\'-filter\' ARG1=\'$filter\' \ ARG2=\'$diskpath\' NARGS=2", \@buf); } } # is AFD loaded check if (!asmcmdafd_is_afd("loaded")) { #9520-"AFD is not '%s'" @eargs = "Loaded"; asmcmdshare_error_msg(9520, \@eargs); return; } # execute the command asmcmdafd_afdfilter($filter, $diskpath); } ######## # NAME # asmcmdafd_process_afdsetlabel # # DESCRIPTION # To associate a AFD label to a disk # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # label - label for the disk # disk - disk path # --rename - to relabel a disk that was labeled earlier # --migrate - to label a disk that was provisioned for ASM # --init - to initialize a disk by labelling for AFD (zipinstall) # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdsetlabel { my ($dbh) = @_; my ($label, $dskpath); my ($ret); my (%args); my (@eargs); my ($labeloption) = ""; my ($afdtool); my ($afdtooladd); my (@buf); my ($val); my ($force) = 0; my ($init) = 0; my ($initoption) = ""; my ($afdloaded) = 1; my ($dskpath_num_elements) = 0; $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); if (defined($args{'init'})) { $initoption = "-init"; $init = 1; } if ((!$init) && asmcmdafd_is_member_cluster()) { #9544-"The command is not supported on a member cluster." asmcmdshare_error_msg(9544); return; } # is AFD loaded check $afdloaded = asmcmdafd_is_afd("loaded"); if ((!$afdloaded) && (!$init)) { #9520-"AFD is not '%s'" @eargs = "Loaded"; asmcmdshare_error_msg(9520, \@eargs); return; } # init option is not allowed if AFD is loaded if (($afdloaded) && ($init)) { #9521-"AFD is already configured" asmcmdshare_error_msg(9521); return; } $dskpath_num_elements = scalar @{$args{'afd_label'}}; $label = @{$args{'afd_label'}}[0]; $dskpath = join ',', @{$args{'afd_label'}}[1..$dskpath_num_elements-1]; if (defined($args{'rename'})) { $labeloption = "RENAME"; $force = 1; } if (defined($args{'migrate'})) { $labeloption = "MIGRATE"; $force = 1; } $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; if ($init) { if (asmcmdafd_am_root()) { asmcmdafd_create_afddisks(); } } if ($initoption) { asmcmdafd_create_logdir(); } if ($force) { asmcmdshare_trace(3, "NOTE: afdtool -add -f '$dskpath' '$label' $initoption", 'y', 'n'); $afdtooladd = "$afdtool -add -f '$dskpath' '$label' $initoption"; } else { asmcmdshare_trace(3, "NOTE: afdtool -add '$dskpath' '$label' $initoption", 'y', 'n'); $afdtooladd = "$afdtool -add '$dskpath' '$label' $initoption"; } if (!asmcmdshare_runcmd($afdtooladd, \@buf, 1, 0)) { if ($init) { asmcmdshare_trace(3, "NOTE: Labeled device '$dskpath' with '$label'", 'y', 'n'); if (asmcmdafd_am_root()) { asmcmdafd_update_afddisks(); } return; } if (@buf) { # command succeeded asmcmdshare_trace(3, "NOTE: " . join('', @buf), 'y', 'n'); ($val) = grep { /labeled with/ } @buf; if (asmcmdafd_am_root()) { asmcmdafd_update_afddisks(); } return if ($val); } } # Failed to label the device. if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to label an AFD device: @buf", 'y', 'n'); asmcmdshare_print(join('', @buf)); } asmcmdshare_error_msg (9513); return; } ######## # NAME # asmcmdafd_process_afdlsdsk # # DESCRIPTION # To list AFD disks. # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # <--all> - list of AFD disks from all the cluster nodes. # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdlsdsk { my ($dbh) = @_; my ($ret); my (%args); my (@eargs); my ($afdtool); my ($afdlsdsk); my (@buf); my ($line); $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # is AFD loaded check if (!asmcmdafd_is_afd("loaded")) { #9520-"AFD is not '%s'" @eargs = "Loaded"; asmcmdshare_error_msg(9520, \@eargs); return; } if ($args{'all'}) { # if AFD disk list requested from all the cluster nodes if (asmcmdafd_request_action("afdtool", "all", "KEYWORD=\'-getdevlist\' ARG1=\'-mode\' NARGS=1", \@buf)) { foreach (@buf) { # print output - node '': AFD disk list $line = $_; if ($line =~ /(CRS-4413:.*)/) { if ($line =~ /(.*)from (.*)/) { asmcmdshare_print("$2\n"); } } else { asmcmdshare_print("$_"); } } } return; } # if AFD disk list is requested from local node $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; $afdlsdsk = "$afdtool -getdevlist '\*' -mode"; asmcmdshare_runcmd($afdlsdsk, \@buf, 1, 0); if (@buf) { asmcmdshare_print(join('', @buf)); } return 0; } ######## # NAME # asmcmdafd_process_afdlslbl # # DESCRIPTION # To list AFD disks containing labels. # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdlslbl { my ($dbh) = @_; my ($ret); my (%args); my (@eargs); my ($afdtool); my ($afdlslbl); my (@buf); my ($diskpath); $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); $diskpath = shift @{$args{'afd_lslbl'}}; if(!defined($diskpath)) { $diskpath = ""; } # if AFD label list is requested from local node $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; asmcmdafd_create_logdir(); if ($diskpath) { $afdlslbl = "$afdtool -listall '$diskpath'"; } else { $afdlslbl = "$afdtool -listall"; } asmcmdshare_runcmd($afdlslbl, \@buf, 1, 0); if (@buf) { asmcmdshare_print(join('', @buf)); } return 0; } ######## # NAME # asmcmdafd_process_afdrefresh # # DESCRIPTION # To refresh AFD disks. # The command is executed without specifying a disk string, so # afd_diskstring value in oracleafd.conf file is used. # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # <--all> - refresh AFD disks on all cluster nodes. # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdrefresh { my ($dbh) = shift; my ($ret, $val, $row); my (%args); my (@eargs); my (@buf); $ret = asmcmdafd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); # is AFD loaded check if (!asmcmdafd_is_afd("loaded")) { #9520-"AFD is not '%s'" @eargs = "Loaded"; asmcmdshare_error_msg(9520, \@eargs); return; } asmcmdshare_trace(3, "NOTE: Refresh AFD disks", 'y', 'n'); if ($args{'all'}) { # if refresh AFD disks is requested on all nodes asmcmdafd_request_action("afdtool", "all", "KEYWORD=\'-refresh\'", \@buf); if (asmcmdafd_am_root()) { asmcmdafd_update_afddisks(); } return; } # if scan is requested on local node # execute the command asmcmdafd_refresh_afd(); } ######## # NAME # asmcmdafd_process_afdscan # # DESCRIPTION # To scan for AFD disks. # If the command is executed without specifying a disk string then # afd_diskstring value in oracleafd.conf file is used. # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # - OS disk string to scan the AFD disks. # <--all> - scan for AFD disks on all cluster nodes. # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdscan { my ($dbh) = shift; my ($ret, $val, $row); my (%args); my (@eargs); my (@buf); my ($diskpath); $ret = asmcmdafd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); $diskpath = shift @{$args{'afd_scan'}}; if(!defined($diskpath)) { $diskpath = ""; } # is AFD loaded check if (!asmcmdafd_is_afd("loaded")) { #9520-"AFD is not '%s'" @eargs = "Loaded"; asmcmdshare_error_msg(9520, \@eargs); return; } if ($args{'all'}) { # if scan of AFD requested on all nodes asmcmdafd_request_action("afdscan", "all", "ARG1=\'$diskpath\'", \@buf); if (asmcmdafd_am_root()) { asmcmdafd_update_afddisks(); } return; } # if scan is requested on local node # execute the command asmcmdshare_trace(3, "NOTE: AFD Scan on '$diskpath'", 'y', 'n'); asmcmdafd_rescan_afd("$diskpath"); } ######## # NAME # asmcmdafd_process_afddi # # DESCRIPTION # To manipulate the data integrity mode in the AFD driver. # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # -e - enable AFD data integrity mode # -d - disable AFD data integrity mode # -q - query AFD data integrity mode # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afddi { my ($dbh) = shift; my ($ret); my (%args); my (@eargs); my ($di); $ret = asmcmdafd_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); if ($args{'e'}) { $di = "enable"; } elsif ($args{'d'}) { $di = "disable"; } elsif ($args{'q'}) { $di = "query"; } else { @eargs = ("Unknown DI command"); asmcmdshare_error_msg(9520, \@eargs); return; } # is AFD loaded check if (!asmcmdafd_is_afd("loaded")) { #9520-"AFD is not '%s'" @eargs = ("Loaded"); asmcmdshare_error_msg(9520, \@eargs); return; } # execute the command asmcmdafd_afddi($di); } ######## # NAME # asmcmdafd_process_afdclrlabel # # DESCRIPTION # To clear an existing label (which is associated with a disk). # # PARAMETERS # $dbh (IN) - initialized database handle, must be non-null. # label - label to clear # -f - force clear the label and drain all I/Os # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdclrlabel { my ($dbh) = @_; my ($label); my ($ret); my (%args); my (@eargs); my ($afdtool); my ($afdtooldel); my (@buf); my ($val); my ($force); my ($init) = 0; my ($initoption) = ""; my ($afdloaded) = 1; $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); $force = $args{'f'}; if (defined($args{'init'})) { $initoption = "-init"; $init = 1; } if ((!$init) && asmcmdafd_is_member_cluster()) { #9544-"The command is not supported on a member cluster." asmcmdshare_error_msg(9544); return; } # is AFD loaded check $afdloaded = asmcmdafd_is_afd("loaded"); if ((!$afdloaded) && (!$init)) { #9520-"AFD is not '%s'" @eargs = "Loaded"; asmcmdshare_error_msg(9520, \@eargs); return; } # init option is not allowed if AFD is loaded if (($afdloaded) && ($init)) { #9521-"AFD is already configured" asmcmdshare_error_msg(9521); return; } ($label) = shift(@{$args{'afd_unlabel'}}); $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; if ($initoption) { asmcmdafd_create_logdir(); } if ($force) { asmcmdshare_trace(3, "NOTE: afdtool -delete -f '$label' $initoption", 'y', 'n'); $afdtooldel = "$afdtool -delete -f '$label' $initoption"; } else { asmcmdshare_trace(3, "NOTE: afdtool -delete '$label' $initoption", 'y', 'n'); $afdtooldel = "$afdtool -delete '$label' $initoption"; } if (!asmcmdshare_runcmd($afdtooldel, \@buf, 1, 0)) { if ($init) { asmcmdshare_trace(3, "NOTE: Unlabeled device $label", 'y', 'n'); return; } if (@buf) { # command succeeded asmcmdshare_trace(3, "NOTE: " . join('', @buf), 'y', 'n'); ($val) = grep { /Unlabeled/ } @buf; return if ($val); } } asmcmdshare_trace(3, "FAIL: Failed to unlabel an AFD device: @buf",'y', 'n'); asmcmdshare_print(join('', @buf)); asmcmdshare_error_msg (9514); return; } ######## # NAME # asmcmdafd_request_action # # DESCRIPTION # Execute the CRSCTL requested action on ora.driver.afd resource # # PARAMETER # action_name (IN) - action name. # nodearg (IN) - comma separated node names where to execute the action # OR 'all' to execute on all nodes of the cluster. # env (IN) - action attribute's env key values; this can be NULL. # buf_ref (OUT) - output buffer of the command for caller to consume. # # RETURNS # 1 - Successfully executed the requested action # 0 - Failure # # NOTES # ######## sub asmcmdafd_request_action { my ($crsctlcmd); my ($crsctl); my (@eargs); my (@buf); my ($nodes) = ""; my ($afdres) = "ora.driver.afd"; my ($action_name, $nodearg, $env, $buf_ref) = @_; if ($nodearg eq "") { # invalid input nodes return 0; } if ($nodearg eq "all") { $nodes = "-all"; } else { $nodes = "-n \'$nodearg\'"; } $crsctl = "$ENV{'ORACLE_HOME'}/bin/crsctl"; #The path in WIN is ORACLE_HOME/bin/crsctl.exe $crsctl .= ".exe" if($^O =~ /win/i); # Make sure the crsctl binary exists and can be executed. if (! -x $crsctl) { @eargs = ($crsctl); asmcmdshare_error_msg(8313, \@eargs); return 0; } #untaint crsctl $crsctl =~ /([^\n^\r^\t]+)/; $crsctl = $1; # execute requested action on ora.driver.afd resource $crsctlcmd = "$crsctl request action "; $crsctlcmd .= "$action_name -r $afdres -env \"$env\"\ $nodes -init"; # To run an action on a resource, OHASD is required. That means clusterware # stack needs to be up. if (!asmcmdafd_ohasd("check")) { #9532-"command cannot be used when Oracle Clusterware stack is down" asmcmdshare_error_msg(9532); return 0; } # check if AFD resource is present. if (asmcmdafd_afd_resource("status")) { #9533-"resource ora.driver.afd does not exist" asmcmdshare_error_msg(9533); return 0; } asmcmdshare_runcmd($crsctlcmd, \@buf, 1, 0); # store the command output to the OUT buffer @{$buf_ref} = @buf; asmcmdshare_trace(3, "NOTE: command: $crsctlcmd\n @buf", 'y', 'n'); return 1; } ######## # NAME # asmcmdafd_process_afdstate # # DESCRIPTION # To query the state of AFD # # PARAMETER # NONE # # RETURNS # NULL. # # NOTES # Only asmcmdafd_process_cmd() calls this function. ######## sub asmcmdafd_process_afdstate { my ($ret); my (%args); my (@eargs); my ($host) = hostname; my ($state) = ""; my ($filter) = "DEFAULT"; my ($afdtool); my ($afdfilter); my (@buf); my ($line); $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); if ($args{'all'}) { # if state of AFD requested from all nodes if (asmcmdafd_request_action("afdstate", "all", "", \@buf)) { foreach (@buf) { # print output like : # node '': State of AFD: LOADED and Filtering Status: DISABLED $line = $_; if ($line =~ /(CRS-4413:.*)/) { chomp($line); if ($line =~ /(.*)from (.*)/) { asmcmdshare_print("$2"); } } else { asmcmdshare_print(" $_"); } } } return; } # if state of AFD requested from local node if (!asmcmdafd_is_afd("supported")) { # AFD may be installed on a supported kernel/O.S and later the system # may have been moved to an unsupported kernel/O.S. In those cases, # AFD drivers are installed but are not compatible with current # running kernel/O.S. if (asmcmdafd_is_afd("installed")) { asmcmdshare_error_msg(9545); } else { $state = "NOT SUPPORTED"; @eargs = ($state); asmcmdshare_error_msg(9530, \@eargs); } } elsif (asmcmdafd_is_afd("loaded")) { $state = "LOADED"; $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; $afdfilter = "$afdtool -filter query"; if (!asmcmdshare_runcmd($afdfilter, \@buf, 1, 0)) { if (@buf) { # command succeeded if ($buf[0] =~ /Filtering Status: (.*)/) { $filter = $1; } } } @eargs = ($state, $filter , $host); asmcmdshare_error_msg(9526, \@eargs); } elsif (asmcmdafd_is_afd("installed")) { $state = "INSTALLED"; @eargs = ($state); asmcmdshare_error_msg(9530, \@eargs); } else { $state = "NOT INSTALLED"; @eargs = ($state); asmcmdshare_error_msg(9530, \@eargs); } return; } ######## # NAME # asmcmdafd_afdfilter # # DESCRIPTION # To enable or disable filtering mode in AFD # # PARAMETER # enable - enable filtering # disable - disable filtering # # RETURNS # 1 if successfully enabled or disabled AFD filtering ; 0 otherwise. # # NOTES ######## sub asmcmdafd_afdfilter { my ($action, $diskpath) = @_; my ($ret); my (%args); my (@eargs); my ($afdtool); my ($afdfilter); my (@buf); $ret = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($ret); asmcmdshare_trace(3, "NOTE: $action AFD Filtering on '$diskpath'", 'y', 'n'); $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; if ($diskpath eq "") { $afdfilter = "$afdtool -filter $action"; } else { $afdfilter = "$afdtool -filter $action '$diskpath'"; } if (asmcmdshare_runcmd("$afdfilter", \@buf, 1, 1)) { asmcmdshare_trace(3, "NOTE: command: $afdfilter\n @buf", 'y', 'n'); asmcmdshare_print(join('', @buf)); } else { if ($diskpath eq "") { asmcmdshare_trace(3, "NOTE: AFD Filtering $action"."d on 'Node Level'", 'y', 'n'); } else { asmcmdshare_trace(3, "NOTE: AFD Filtering $action"."d on '$diskpath'", 'y', 'n'); } return 1; } return 0; } ######## # NAME # asmcmdafd_afddi # # DESCRIPTION # To enable, disable, or query data integrity mode in AFD # # PARAMETER # enable - enable integrity # disable - disable integrity # query - query data integrity # # RETURNS # 1 - No error on data integrity operation - enabled, disabled, or query # 0 - afdtool command returned an error # # NOTES ######## sub asmcmdafd_afddi { my ($action) = @_; my ($ret); my ($rc); my (%args); my (@eargs); my ($afdtool); my ($cmdout); my (@buf); $rc = asmcmdafd_parse_int_args ($asmcmdglobal_hash{'cmd'}, \%args); return unless defined ($rc); $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; $rc = asmcmdshare_runcmd("$afdtool -di $action", \@buf, 1, 0); if (@buf) { ($cmdout) = grep { /Data Integrity/ } @buf; } if (defined($cmdout)) { asmcmdshare_print("$cmdout"); } # asmcmdshare_runcmd & asmcmdafd_afddi interpret success differently $ret = ($rc == 0) ? 1 : 0; return $ret; } ######## # NAME # asmcmdafd_ohasd # # DESCRIPTION # This function will start OHASD without starting the rest of the stack # or stop OHASD or check OHASD status. # # PARAMETERS # start - start OHASD # stop - stop OHASD # check - check OHASD # # RETURNS # 1 if successfully started or stopped ohasd OR ohasd is online; 0 otherwise. ######## sub asmcmdafd_ohasd { my ($action) = @_; my (@eargs); my $crsctlcmd; my $crsctl; my ($buf); my ($line); my (@lines); my ($cmdout); my ($status); my ($issiha); my ($crsmode); $crsctl = "$ENV{'ORACLE_HOME'}/bin/crsctl"; #The path in WIN is ORACLE_HOME/bin/crsctl.exe $crsctl .= ".exe" if($^O =~ /win/i); # Make sure the crsctl binary exists and can be executed. if (! -x $crsctl) { @eargs = ($crsctl); asmcmdshare_error_msg(8313, \@eargs); return 0; } #untaint crsctl $crsctl =~ /([^\n^\r^\t]+)/; $crsctl = $1; # Verify if the env is either GI or SIHA $issiha = asmcmdafd_is_siha(); if ($issiha) { $crsmode = "has"; } else { $crsmode = "crs"; } if ($action eq "start") { # start OHASD $crsctlcmd = "$crsctl start $crsmode -noautostart"; asmcmdshare_trace(3, "NOTE: Starting OHASD... ", 'y', 'n'); $cmdout = 4123; } if ($action eq "stop") { # stop OHASD $crsctlcmd = "$crsctl stop $crsmode -f"; asmcmdshare_trace(3, "NOTE: Stopping OHASD... ", 'y', 'n'); $cmdout = 4133; } if ($action eq "check") { # check OHASD asmcmdshare_trace(3, "NOTE: Checking the cluster status.. ", 'y', 'n'); $crsctlcmd = "$crsctl check has"; $cmdout = 4638; } asmcmdshare_runcmd($crsctlcmd, \@lines, 1, 0); foreach $line (@lines) { if($line =~ /([^\d]+)([^:]+)/) { $status = $2; if(defined($status)) { # CRS-4123: Oracle High Availability Services has been started. # CRS-4133: Oracle High Availability Services has been stopped. # CRS-4638: Oracle High Availability Services is online if($status eq $cmdout) { # Successfully started or stopped OHASD OR OHASD is online. return 1; } } } } # Failed to start or stop OHASD asmcmdshare_trace(3, "FAIL: Failed to $action OHASD", 'y', 'n'); asmcmdshare_trace(3, "$status", 'y', 'n'); return 0; } ######## # NAME # asmcmdafd_modify_resource # # DESCRIPTION # This function will modify the dependencies of CSSD resources # ora.cssd and ora.cssdmonitor # SIHA - ora.cssd(START and STOP) # GI - ora.cssd(STOP) and ora.cssdmonitor(START) # # PARAMETERS # add - add ora.driver.afd dependency in cssd resource # delete - delete ora.driver.afd dependency from cssd resource # # RETURNS # 1 if successfully modified ; 0 otherwise. ######## sub asmcmdafd_modify_resource { my ($action) = @_; my (@eargs); my $notExist = 0; my $status; my $crsctlcmd; my (@cssdlines); my (@cssdmonlines); my ($line); my (@buf); my ($attr) = ""; my ($resName) = "ora.driver.afd"; my $issiha; my $crsctl = "$ENV{'ORACLE_HOME'}/bin/crsctl"; #The path in WIN is ORACLE_HOME/bin/crsctl.exe $crsctl .= ".exe" if($^O =~ /win/i); # Make sure the crsctl binary exists and can be executed. if (! -x $crsctl) { @eargs = ($crsctl); asmcmdshare_error_msg(8313, \@eargs); return 0; } #untaint crsctl $crsctl =~ /([^\n^\r^\t]+)/; $crsctl = $1; # Verify if the env is either GI or SIHA $issiha = asmcmdafd_is_siha(); # First read the resource dependencies $crsctlcmd = "$crsctl stat res ora.cssd -init -f"; asmcmdshare_runcmd($crsctlcmd, \@cssdlines, 1, 0); if (!$issiha) { $crsctlcmd = "$crsctl stat res ora.cssdmonitor -init -f"; asmcmdshare_runcmd($crsctlcmd, \@cssdmonlines, 1, 0); } if ($issiha) { # incase of SIHA modify ora.cssd resource foreach $line (@cssdlines) { if (($line =~ /START_DEPENDENCIES/) || ($line =~ /STOP_DEPENDENCIES/)) { my $hard = ""; my $weak = ""; my $pullup = ""; if ($line =~ /(.*)(hard\(.*?\))(.*)/) { $hard = $2; } if ($line =~ /(.*)(weak?\(.*?\))(.*)/) { $weak = $2; } if ($line =~ /(.*)(pullup?\(.*?\))(.*)/) { $pullup = $2; } if ($action eq "add") { if ($line =~ /START_DEPENDENCIES/) { if ($hard) { $hard =~ s/\)/,ora.driver.afd\)/; } else { $hard = "hard(ora.driver.afd)"; } $attr = ("\"START_DEPENDENCIES=\'".$weak.$hard.$pullup . "\'\""); } if ($line =~ /STOP_DEPENDENCIES/) { $hard =~ s/\)/,shutdown:ora.driver.afd\)/; $attr = ("\"STOP_DEPENDENCIES=\'".$weak.$hard.$pullup . "\'\""); } # Now, update the resource attribute if ($attr) { $crsctlcmd = "$crsctl modify res ora.cssd -attr ".$attr." -init"; asmcmdshare_trace(3, "cssd res modify command : $crsctlcmd", 'y', 'n'); asmcmdshare_runcmd($crsctlcmd, \@buf, 1, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to modify ora.cssd resource" . " attribute: " . join('', @buf), 'y', 'n'); return 0; } } } elsif ($action eq "delete") { my $tmpattr; if ($line =~ /START_DEPENDENCIES/) { if ($hard) { $hard =~ s/\,?ora.driver.afd//g; if ($hard =~ /hard\(\)/) { $hard = ""; } } $line =~ s/\,?ora.driver.afd//g; if ($line =~ /START_DEPENDENCIES=(.*)/) { $tmpattr = $1; } $attr = ("\"START_DEPENDENCIES=\'".$weak.$hard.$pullup . "\'\""); } if ($line =~ /STOP_DEPENDENCIES/) { $line =~ s/\,?shutdown:ora.driver.afd//g; if ($line =~ /STOP_DEPENDENCIES=(.*)/) { $tmpattr = $1; } $attr = ("\"STOP_DEPENDENCIES=\'".$tmpattr . "\'\""); } # Now, update the resource attribute if ($attr) { $crsctlcmd = "$crsctl modify res ora.cssd -attr ".$attr." -init"; asmcmdshare_trace(3, "cssd res modify command : $crsctlcmd", 'y', 'n'); asmcmdshare_runcmd($crsctlcmd, \@buf, 0, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to modify ora.cssd resource". " attribute: " . join('', @buf), 'y', 'n'); return 0; } } } } } asmcmdshare_trace(3, "NOTE: Modified ora.cssd res attributes", 'y', 'n'); } else { # incase of GI modify ora.cssd and ora.cssdmonitor resources foreach $line (@cssdlines) { if ($line =~ /STOP_DEPENDENCIES/) { my $hard = ""; my $weak = ""; my $pullup = ""; if ($line =~ /(.*)(hard\(.*?\))(.*)/) { $hard = $2; } if ($line =~ /(.*)(weak?\(.*?\))(.*)/) { $weak = $2; } if ($line =~ /(.*)(pullup?\(.*?\))(.*)/) { $pullup = $2; } if ($action eq "add") { $hard =~ s/\)/,shutdown:ora.driver.afd\)/; $attr = ("\"STOP_DEPENDENCIES=\'".$weak.$hard.$pullup . "\'\""); # Now, update the resource attribute if ($attr) { $crsctlcmd = "$crsctl modify res ora.cssd -attr ".$attr." -init"; asmcmdshare_trace(3, "cssd res modify command : $crsctlcmd", 'y', 'n'); asmcmdshare_runcmd($crsctlcmd, \@buf, 0, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to modify ora.cssd resource" . " attribute: " . join('', @buf), 'y', 'n'); return 0; } } } elsif ($action eq "delete") { my $tmpattr; if ($line =~ /STOP_DEPENDENCIES/) { $line =~ s/\,?shutdown:ora.driver.afd//g; if ($line =~ /STOP_DEPENDENCIES=(.*)/) { $tmpattr = $1; } $attr = ("\"STOP_DEPENDENCIES=\'".$tmpattr . "\'\""); } # Now, update the resource attribute if ($attr) { $crsctlcmd = "$crsctl modify res ora.cssd -attr ".$attr." -init"; asmcmdshare_trace(3, "cssd res modify command : $crsctlcmd", 'y', 'n'); asmcmdshare_runcmd($crsctlcmd, \@buf, 0, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to modify ora.cssd resource". " attribute: " . join('', @buf), 'y', 'n'); return 0; } } } last; } } foreach $line (@cssdmonlines) { if ($line =~ /START_DEPENDENCIES/) { my $hard = ""; my $weak = ""; my $pullup = ""; if ($line =~ /(.*)(hard\(.*?\))(.*)/) { $hard = $2; } if ($line =~ /(.*)(weak?\(.*?\))(.*)/) { $weak = $2; } if ($line =~ /(.*)(pullup?\(.*?\))(.*)/) { $pullup = $2; } if ($action eq "add") { $hard =~ s/\)/,ora.driver.afd\)/; if (!$hard) { $hard = "hard(ora.driver.afd)"; } $attr = ("\"START_DEPENDENCIES=\'".$weak.$hard.$pullup . "\'\""); # Now, update the resource attribute if ($attr) { $crsctlcmd = "$crsctl modify res ora.cssdmonitor -attr ".$attr. " -init"; asmcmdshare_trace(3, "cssdmonitor res modify command : $crsctlcmd", 'y', 'n'); asmcmdshare_runcmd($crsctlcmd, \@buf, 0, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to modify ora.cssdmonitor " . "resource attribute: " . join('', @buf), 'y', 'n'); return 0; } } } elsif ($action eq "delete") { my $tmpattr; if ($line =~ /START_DEPENDENCIES/) { $line =~ s/\,?ora.driver.afd//g; if ($line =~ /START_DEPENDENCIES=.*\(\)/) { $attr = ("\"START_DEPENDENCIES=\""); } elsif ($line =~ /START_DEPENDENCIES=(.*)/) { $tmpattr = $1; $attr = ("\"START_DEPENDENCIES=\'".$tmpattr . "\'\""); } } # Now, update the resource attribute if ($attr) { $crsctlcmd = "$crsctl modify res ora.cssdmonitor -attr ".$attr. " -init"; asmcmdshare_trace(3, "cssdmonitor res modify command : $crsctlcmd", 'y', 'n'); asmcmdshare_runcmd($crsctlcmd, \@buf, 0, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to modify ora.cssdmonitor ". "resource attribute: " . join('', @buf), 'y', 'n'); return 0; } } } last; } } asmcmdshare_trace(3, "NOTE: Modified ora.cssd and ora.cssdmonitor". " resource attributes", 'y', 'n'); } return 1; } ######## # NAME # asmcmdafd_afd_resource_type # # DESCRIPTION # This function will add or remove or status check AFD OHASD resource type # ora.driver.afd.type # Keep consistent with oraafd.pm:actionASMDriverResource(). # # PARAMETERS # add - add the resource type in ohasd # delete - remove the resource type from ohasd # status - find the status of resource type from ohasd # # RETURNS # 1 if resouce type doesn't exist or is added/removed; 0 otherwise. ######## sub asmcmdafd_afd_resource_type { my ($action) = @_; my (@eargs); my $ORACLE_HOME = $ENV{'ORACLE_HOME'}; my $type = "ora.driver.afd.type"; my $baseType = "ora.daemon.type"; my $templateFile = "driver.afd.type"; my $CRS_HOME_TEMPLATE = catdir($ORACLE_HOME, "crs", "template"); my $infile = catfile($CRS_HOME_TEMPLATE, $templateFile); my $restypecmd; my @buf; my $notExist = 0; my $status; my $crsctl = "$ENV{'ORACLE_HOME'}/bin/crsctl"; #The path in WIN is ORACLE_HOME/bin/crsctl.exe $crsctl .= ".exe" if($^O =~ /win/i); # Make sure the crsctl binary exists and can be executed. if (! -x $crsctl) { @eargs = ($crsctl); asmcmdshare_error_msg(8313, \@eargs); return 0; } #untaint crsctl $crsctl =~ /([^\n^\r^\t]+)/; $crsctl = $1; # First check the status of the resource type $restypecmd = "$crsctl stat type $type -init"; asmcmdshare_runcmd($restypecmd, \@buf, 1, 0); if (!grep(/TYPE_NAME=ora.driver.afd.type/, @buf)) { #output: CRS-2560: Resource type 'ora.driver.afd.type' does not exist asmcmdshare_trace(3, "NOTE: ora.driver.afd.type res type doesn't exist", 'y', 'n'); $notExist = 1; } # if action is 'status' then just send the status value if ($action eq "status") { return $notExist; } # if resource type does not exist and action is 'add' if (scalar($notExist) > 0 && ($action eq "add")) { asmcmdshare_trace(3, "NOTE: Registering resource type ora.driver.afd.type", 'y', 'n'); $restypecmd = "$crsctl add type $type -basetype $baseType " . "-file $infile -init"; asmcmdshare_runcmd($restypecmd, \@buf, 0, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to add resource type". " ora.driver.afd.type: " . join('', @buf), 'y', 'n'); return 0; } else { asmcmdshare_trace(3, "NOTE: added resource type ora.driver.afd.type", 'y', 'n'); return 1; } } # if resource type exist and action is 'delete' if ((scalar($notExist) == 0) && ($action eq "delete")) { asmcmdshare_trace(3, "NOTE: Deleting resource type ora.driver.afd.type", 'y', 'n'); $restypecmd = "$crsctl delete type $type -init"; asmcmdshare_runcmd($restypecmd, \@buf, 1, 0); if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to delete resource type". " ora.driver.afd.type: " . join('', @buf), 'y', 'n'); return 0; } else { asmcmdshare_trace(3, "NOTE: deleted resource type ora.driver.afd.type", 'y', 'n'); return 1; } } return 1; } ######## # NAME # asmcmdafd_afd_resource # # DESCRIPTION # This function will add or remove or status check AFD OHASD resource # ora.driver.afd # Keep consistent with oraafd.pm:actionASMDriverResource(). # # PARAMETERS # add - add the resource # delete - delete the resource # status - find the status of resource # # RETURNS # 1 if resouce doesn't exist or is added or removed; 0 otherwise. ######## sub asmcmdafd_afd_resource { my ($action) = @_; my (@eargs); my (@lines); my (@buf); my ($crsctl); my ($crsctlcmd); my $notExist = 0; my $status; my $afd_attr; my $resName = "ora.driver.afd"; my $resType = "ora.driver.afd.type"; my $restypecmd; my ($issiha); my $ousr; my $ogrp; my $i; # Verify if the env is either GI or SIHA $issiha = asmcmdafd_is_siha(); if (-e "$ENV{'ORACLE_HOME'}/crs/install/crsconfig_params") { unless (open(FD,"<$ENV{'ORACLE_HOME'}/crs/install/crsconfig_params")) { return 0; } @lines = ; unless (close(FD)) { return 0; } for($i = 0; $i<=$#lines; $i++) { if($lines[$i] =~ "ORACLE_OWNER=") { $ousr = $lines[$i]; $ousr =~ /(.*\=)(.*)/i; $ousr = $2; } if($lines[$i] =~ "ORA_ASM_GROUP=") { $ogrp = $lines[$i]; $ogrp =~ /(.*\=)(.*)/i; $ogrp = $2; } } } # if we can't retrieve oracle user and group then we cannot add/remove res. if (!$ousr && !$ogrp) { asmcmdshare_trace(3, "FAIL: Failed to retrieve Oracle owner & group", 'y', 'n'); return 0; } $crsctl = "$ENV{'ORACLE_HOME'}/bin/crsctl"; #The path in WIN is ORACLE_HOME/bin/crsctl.exe $crsctl .= ".exe" if($^O =~ /win/i); # Make sure the crsctl binary exists and can be executed. if (! -x $crsctl) { @eargs = ($crsctl); asmcmdshare_error_msg(8313, \@eargs); return 0; } #untaint crsctl $crsctl =~ /([^\n^\r^\t]+)/; $crsctl = $1; # Check the existence of the AFD resource $crsctlcmd = "$crsctl stat res ora.driver.afd -init"; asmcmdshare_trace(3, "NOTE: Checking existence of AFD resource", 'y', 'n'); asmcmdshare_runcmd($crsctlcmd, \@buf, 1, 0); #if($buf =~ /([^\d]+)([^:]+)/) if (!grep(/NAME=ora.driver.afd/, @buf)) { #output: CRS-2613: Could not find resource 'ora.driver.afd'. asmcmdshare_trace(3, "NOTE: ora.driver.afd resource doesn't exist", 'y', 'n'); $notExist = 1; } # if resource doesn't exist and action is 'status' if ($action eq "status") { return $notExist; } # if resource doesn't exist and action is 'add' if (($notExist == 1) && ($action eq "add")) { # add AFD resource type if it does not exist. if (!asmcmdafd_afd_resource_type("add")) { asmcmdshare_trace(3, "FAIL: Failed to add AFD resource type", 'y', 'n'); return 0; } if ($issiha) { $afd_attr = ("ACL=\'owner:$ousr:rwx,pgrp:$ogrp:r-x,other::r--," . "user:$ousr:r-x\',ACTIONS=\'afdscan,user:$ousr ". "afdds,user:$ousr ". "afdtool,user:$ousr ". "afdstate,user:$ousr\'"); } else { $afd_attr = ("ACL=\'owner:root:rwx,pgrp:$ogrp:r-x,other::r--," . "user:$ousr:r-x\',ACTIONS=\'afdscan,user:$ousr ". "afdds,user:$ousr ". "afdtool,user:$ousr afdstate,user:$ousr\'"); } $crsctlcmd = "$crsctl add resource $resName -attr \"". $afd_attr . "\" -type $resType -init"; asmcmdshare_runcmd($crsctlcmd, \@buf, 0, 0); if (@buf) { # resource add failed asmcmdshare_trace(3, "FAIL: Failed to add AFD resource: " . join('', @buf), 'y', 'n'); return 0; } else { asmcmdshare_trace(3, "NOTE: Added AFD resource", 'y', 'n'); return 1; } } # if resource exists and action is 'delete' if (($notExist == 0) && ($action eq "delete")) { my (@lines); my ($line); # stop AFD resource $crsctlcmd = ("$crsctl stop resource $resName -init"); asmcmdshare_runcmd($crsctlcmd, \@lines, 0, 0); foreach $line (@lines) { if($line =~ /([^\d]+)([^:]+)/) { $status = $2; if(defined($status)) { #CRS-2677: Stop of 'ora.driver.afd' on 'slc05gkm' succeeded #CRS-2500: Cannot stop resource 'ora.driver.afd' as it is not running if (($status eq 2677) || ($status eq 2500)) { # Successfully stopped AFD resource or it is not running. asmcmdshare_trace(3, "NOTE: AFD resource stopped or not running", 'y', 'n'); $status = 1; last; } } } } if ((defined($status)) && ($status != 1)) { # Failed to stop AFD resource. asmcmdshare_trace(3, "FAIL: Failed to stop AFD resource", 'y', 'n'); return 0; } $crsctlcmd = ("$crsctl delete resource $resName -init"); asmcmdshare_runcmd($crsctlcmd, \@buf, 0, 0); if (@buf) { # resource delete failed asmcmdshare_trace(3, "FAIL: Failed to delete AFD resource : " . join('', @buf), 'y', 'n'); return 0; } else { asmcmdshare_trace(3, "NOTE: Deleted AFD resource", 'y', 'n'); return 1; } # delete AFD resource type if (!asmcmdafd_afd_resource_type("delete")) { asmcmdshare_trace(3, "FAIL: Failed to delete AFD resource type", 'y', 'n'); return 0; } } return 1; } ######## # NAME # asmcmdafd_is_cluster_down # # DESCRIPTION # This function checks if clusterware is shutdown on the local system # # PARAMETERS # NONE # # RETURNS # 1 if clusterware is down ; 0 otherwise. ######## sub asmcmdafd_is_cluster_down { my ($crsctl); my (@buf); my ($status); my (@eargs); $crsctl = "$ENV{'ORACLE_HOME'}/bin/crsctl"; #The path in WIN is ORACLE_HOME/bin/crsctl.exe $crsctl .= ".exe" if($^O =~ /win/i); # Make sure the crsctl binary exists and can be executed. if (! -x $crsctl) { @eargs = ($crsctl); asmcmdshare_error_msg(8313, \@eargs); return 0; } #untaint crsctl $crsctl =~ /([^\n^\r^\t]+)/; $crsctl = $1; asmcmdshare_runcmd("$crsctl check has", \@buf, 1, 0); # Check for the number at CRS-xxxx in the output. if((@buf) && ($buf[0] =~ /([^\d]+)([^:]+)/)) { $status = $2; if(defined($status)) { if(($status eq 4639) || ($status eq 4047)) { #output: CRS-4639: Could not contact Oracle High Availability Services #output: CRS-4047: No Oracle Clusterware components configured. asmcmdshare_trace(3, "NOTE: Status of clusterware stack : Not online", 'y', 'n'); return 1; } } else { asmcmdshare_error_msg(8309, undef); return 0; } } return 0; } # end asmcmdafd_is_cluster_down ######## # NAME # asmcmdafd_get_asmdiskstr_fromprofile # # DESCRIPTION # This function returns asm_diskstring value from gpnp profile. # # PARAMETERS # NONE # # RETURNS # asm_diskstring value if available ; "" otherwise. ######## sub asmcmdafd_get_asmdiskstr_fromprofile { my ($kfod); my (@buf); my (@eargs); # if unable to query, return empty string my $asmdiskstr = ""; my ($asm_discstr) = ""; $kfod = catfile($ENV{'ORACLE_HOME'}, 'bin', 'kfod'); $kfod .= ".exe" if($^O =~ /win/i); # Make sure the kfod binary exists and can be executed. if (! -x $kfod) { @eargs = ($kfod); asmcmdshare_error_msg(9515, \@eargs); return; } asmcmdshare_runcmd("$kfod op=GPNPDSTR nohdr=true", \@buf, 0, 0); foreach my $line (@buf) { $asmdiskstr = $line; } # kfod returns one line o/p for asm_diskstring. # Last line contains the asm_diskstring. # # kfod may return 0 but asm_diskstring may # be 'Not Set' or 'Not Available'. # # If asm_diskstring was never setup at profile creation # time or later, the default value in profile.xml is # "++no-value-at-profile-creation--never-updated-through-ASM++" # This special string also needs to be handled well. # For those, return empty string. # # Empty string is interpreted as default discovery string # by afdboot/afdtool. # chomp($asmdiskstr); if( ($asmdiskstr eq "Not Set") || ($asmdiskstr eq "Not Available") || ($asmdiskstr eq "++no-value-at-profile-creation--never-updated-through-ASM++") ) { $asmdiskstr = ""; } asmcmdshare_trace(3, "Retrieved asm disk string from gpnp : \'$asmdiskstr\'", 'y', 'n'); return $asmdiskstr; } # end asmcmdafd_get_asmdiskstr_fromprofile ######## # NAME # asmcmdafd_isSUSELinux # # DESCRIPTION # This function checks if the node is running SUSE Linux # # PARAMETERS # NONE # # RETURNS # 1 if the system is SUSE Linux ; 0 otherwise. ######## sub asmcmdafd_isSUSELinux { my @buf; if($^O =~ /linux/i) { my @cmd = (catfile('/bin', 'rpm'), '-q', 'sles-release'); if (!asmcmdshare_runcmd($cmd[0], \@buf, 1, 1)) { # rpm command succeeded. if (defined($buf[0]) and !($buf[0] =~ /not installed/)) { return 1; } } } return 0; } # end asmcmdafd_isSUSELinux ######## # NAME # asmcmdafd_clean_rcdirs # # DESCRIPTION # This function removed AFD init start or kill scripts from rc directories. # # PARAMETERS # $file - name of the init script file ("afd" in this case) # # RETURNS # 1 if no error; 0 otherwise. ######## sub asmcmdafd_clean_rcdirs { my $file = $_[0]; my @cmd; my @buf; if (!$file) { return 0; } #remove old ones if ($RCALLDIR) { my ($rc, $rcStartFile, $rcKillFile, $rcKillOldFile, $rcKillOld2File); my @RCALLDIRLIST = split (/ /, $RCALLDIR); foreach $rc (@RCALLDIRLIST) { if ($RC_START) { $rcStartFile = catfile ($rc, "$RC_START" . "$file"); @cmd = "rm $rcStartFile 2>&1"; eval { @buf = `@cmd`; }; } if ($RC_KILL) { $rcKillFile = catfile ($rc, $RC_KILL . $file); @cmd = "rm $rcKillFile 2>&1"; eval { @buf = `@cmd`; }; } if ($RC_KILL_OLD) { $rcKillOldFile = catfile ($rc, $RC_KILL_OLD . $file); @cmd = "rm $rcKillOldFile 2>&1"; eval { @buf = `@cmd`; }; } if ($RC_KILL_OLD2) { $rcKillOldFile = catfile ($rc, $RC_KILL_OLD . $file); @cmd = "rm $rcKillOldFile 2>&1"; eval { @buf = `@cmd`; }; } } } return 1; } # end asmcmdafd_clean_rcdirs ######## # NAME # asmcmdafd_afd_install_initd # # DESCRIPTION # This function is used to run install_initd command to create afd links # under rc directories. Only for SUSE Linux. # # PARAMETERS # NONE # # RETURNS # NONE ######## sub asmcmdafd_afd_install_initd { # call install_initd if it's SUSE Linux if (asmcmdafd_isSUSELinux()) { my $afd = catfile($INITD, "afd"); my $initd = catfile('/usr', 'lib', 'lsb', 'install_initd'); my @buf = ""; my $cmd; $cmd = "$initd $afd"; # Not checking for the return value asmcmdshare_runcmd("$cmd", \@buf, 1, 1); for (@buf) { s/`//g; } if (@buf) { asmcmdshare_trace(3, "NOTE: install_initd output : @buf", 'y', 'n'); } } } ######## # NAME # asmcmdafd_afd_remove_initd # # DESCRIPTION # This function is used to run remove_initd command to remove afd links # from rc directories. Only for SUSE Linux. # # PARAMETERS # NONE # # RETURNS # NONE ######## sub asmcmdafd_afd_remove_initd { # call remove_initd if it's SUSE Linux if (asmcmdafd_isSUSELinux()) { my $afd = catfile($INITD, "afd"); my $initd = catfile('/usr', 'lib', 'lsb', 'remove_initd'); my @buf = ""; my $cmd; $cmd = "$initd $afd"; # Not checking for the return value asmcmdshare_runcmd("$cmd", \@buf, 1, 1); for (@buf) { s/`//g; } if (@buf) { asmcmdshare_trace(3, "NOTE: remove_initd output : @buf", 'y', 'n'); } } } ######## # NAME # asmcmdafd_copy_to_rcdirs # # DESCRIPTION # This function copies AFD init script to system init directory and also # copies AFD init start or kill scripts from rc directories. # # PARAMETERS # $sourcefile - init script file to copy (say "GI_home/crs/init/afd") # $destfile - name of the init file to copy as (say "/etc/init.d/afd") # # RETURNS # 1 if no error; 0 otherwise. ######## sub asmcmdafd_copy_to_rcdirs { my $sourcefile = $_[0]; my $destfile = $_[1]; my @buf; my @cmd; if (!($sourcefile)) { asmcmdshare_trace(3, "FAIL: Failed to copy AFD init scripts; no srcfile", 'y', 'n'); return 0; } if (! -e $sourcefile) { asmcmdshare_trace(3, "FAIL: Failed to copy AFD init scripts to rcdirs", 'y', 'n'); return 0; } # Copy to init dir copy ($sourcefile, catfile ($INITD, $destfile)) || return 0; @cmd = "chmod 0755 " . catfile($INITD, $destfile); eval { @buf = `@cmd`; }; if (asmcmdafd_isSUSELinux()) { # for SUSE Linux, do not create link to the file in the init dir return 1; } # Create a link to the file in the init dir my @RCSDIRLIST = split (/ /, $RCSDIR); foreach my $rc (@RCSDIRLIST) { @cmd = "rm $rc/$RC_START$destfile 2>&1"; eval { @buf = `@cmd`; }; symlink (catfile($INITD, $destfile), catfile($rc, "$RC_START$destfile")) || return 0; } my @RCKDIRLIST = split (/ /, $RCKDIR); foreach my $rc (@RCKDIRLIST) { @cmd = "rm $rc/$RC_KILL$destfile 2>&1"; eval { @buf = `@cmd`; }; symlink(catfile($INITD, $destfile), catfile($rc, "$RC_KILL$destfile")) || return 0; } asmcmdshare_trace(3, "Copied AFD init scripts to rcdirs", 'y', 'n'); return 1; } # end asmcmdafd_copy_to_rcdirs ######## # NAME # asmcmdafd_rm_afdinit_init # # DESCRIPTION # This function removes AFD init file (say "/etc/init.d/afd") from the node. # # PARAMETERS # NONE # # RETURNS # NONE ######## sub asmcmdafd_rm_afdinit_init { my $afdfile = catfile($INITD, "afd"); if(-e $afdfile) { asmcmdafd_afd_remove_initd(); unlink($afdfile); } return; } # end asmcmdafd_rm_afdinit_init ######## # NAME # asmcmdafd_rm_afdinit_rclevel # # DESCRIPTION # This function is used to clean AFD init files or scripts from the node. # # PARAMETERS # NONE # # RETURNS # NONE ######## sub asmcmdafd_rm_afdinit_rclevel { asmcmdafd_clean_rcdirs ("afd"); return; } # end asmcmdafd_rm_afdinit_rclevel ######## # NAME # asmcmdafd_copy_afdinit # # DESCRIPTION # This function is used to copy AFD init files or scripts to system dirs. # # PARAMETERS # NONE # # RETURNS # 1 if no errors; 0 otherwise. ######## sub asmcmdafd_copy_afdinit { my $INITDIR = catfile ($ENV{'ORACLE_HOME'}, "crs", "init"); my $srv = "afd"; my $INITDIR_SRV = catfile ($INITDIR, $srv); asmcmdshare_trace(3, "Creating AFD init scripts", 'y', 'n'); #if SUSE linux, copy the afd.sles to the rcdirs if (asmcmdafd_isSUSELinux()) { $INITDIR_SRV = catfile ($INITDIR, "$srv.sles"); } asmcmdafd_copy_to_rcdirs ($INITDIR_SRV, "afd") || return 0; asmcmdafd_afd_install_initd(); return 1; } # end asmcmdafd_copy_afdinit ######## # NAME # asmcmdafd_update_afd_conf # # DESCRIPTION # This function creates oracleafd.conf file in the system directory and adds # afd_diskstring parameter and with its value. # # PARAMETERS # NONE # # RETURNS # 1 if no errors; 0 otherwise. ######## sub asmcmdafd_update_afd_conf { my (@plines); my (@lines); my ($i); my ($line); my ($ousr); my ($ogrp); my ($uid); my ($gid); my ($afdds); asmcmdshare_trace(3, "Updating oracleafd.conf", 'y', 'n'); if (-e "$ENV{'ORACLE_HOME'}/crs/install/crsconfig_params") { unless (open(FD,"<$ENV{'ORACLE_HOME'}/crs/install/crsconfig_params")) { asmcmdshare_trace(3, "FAIL: crsconfig_params file does not exist", 'y', 'n'); return 0; } @plines = ; unless (close(FD)) { return 0; } for($i = 0; $i<=$#plines; $i++) { if($plines[$i] =~ "ORACLE_OWNER=") { $ousr = $plines[$i]; $ousr =~ /(.*\=)(.*)/i; $ousr = $2; } if($plines[$i] =~ "ORA_ASM_GROUP=") { $ogrp = $plines[$i]; $ogrp =~ /(.*\=)(.*)/i; $ogrp = $2; } } } # Update oracleafd.conf with the default discovery string which is blank ''. # "afd_diskstring" is the key in oracleafd.conf . my $afd_conf = "/etc/oracleafd.conf"; if($^O =~ /win/i) { ($afd_conf) = "$ENV{SYSTEMROOT}\\system32\\drivers\\oracleafd.conf"; } # get asm_diskstring and remove AFD:* from it, if present. $afdds = asmcmdafd_get_asmdiskstr_fromprofile(); $afdds =~ s/(^AFD:.*?,)//g; $afdds =~ s/(,AFD:.*?,)/,/g; $afdds =~ s/(,AFD:.*$)//g; if ($afdds =~ /AFD:/) { $afdds = ''; } if(-e $afd_conf) { unless (open(FD,"<$afd_conf")) { return 0; } @lines = ; unless (close(FD)) { return 0; } for($i = 0; $i<=$#lines; $i++) { if($lines[$i] =~ /afd_diskstring/) { $lines[$i] = "afd_diskstring='".$afdds."'\n"; last; } } } else { $lines[0] = "afd_diskstring='".$afdds."'\n"; } # Write to oracleafd.conf unless (open(FD,">$afd_conf")) { return 0; } foreach $line (@lines) { print FD $line; } unless (close(FD)) { return 0; } # Set appropriate permissions on /etc/oracleafd.conf file if ($ousr && $ogrp) { $uid = getpwnam ($ousr); $gid = getgrnam ($ogrp); chown($uid, $gid, "$afd_conf"); } chmod(0664, "$afd_conf"); asmcmdshare_trace(3, "Created $afd_conf", 'y', 'n'); return 1; } # end asmcmdafd_update_afd_conf ######## # NAME # asmcmdafd_handle_asmlib # # DESCRIPTION # This function verifies and removes ASMLib if exists in the system. # # PARAMETERS # NONE # # RETURNS # 1 if ASMLib is removed, 2 in case of an error ; 0 otherwise. ######## sub asmcmdafd_handle_asmlib { my ($asmlib); my ($asmlibexists) = 0; my ($afdtool); my (@buf); if (!($^O =~ /linux/i)) { return $asmlibexists; } if (-e "/opt/oracle/extapi") { open (ASMLIB, "find /opt/oracle/extapi/ | grep libasm.so |"); while ($asmlib = ) { $asmlibexists = 1; chomp($asmlib); unlink("$asmlib"); } close(ASMLIB); } open (ASMLIB, "/sbin/lsmod | grep oracleasm |"); while ($asmlib = ) { $asmlibexists = 1; asmcmdshare_runcmd("/sbin/rmmod oracleasm", \@buf, 0, 1); if (@buf) { asmcmdshare_trace(3, "NOTE: unload ASMLIB failed: " . join('', @buf) . "try second way", 'y', 'n'); if (-e "/etc/init.d/oracleasm") { asmcmdshare_runcmd("/etc/init.d/oracleasm disable", \@buf, 0, 1); } if (-e "/usr/sbin/oracleasm") { asmcmdshare_runcmd("/usr/sbin/oracleasm exit", \@buf, 0, 1); } if (@buf) { asmcmdshare_trace(3, "FAIL: Failed to unload ASMLib driver: " . join('', @buf), 'y', 'n'); return 2; } } else { return 1; } } close(ASMLIB); return $asmlibexists; } ######## # NAME # asmcmdafd_rescan_afd # # DESCRIPTION # This function rescans AFD disks on the local system # # PARAMETERS # NONE # # RETURNS # 1 if AFD disks are rescanned; 0 otherwise. ######## sub asmcmdafd_rescan_afd { my ($rescanstr) = @_; my (@eargs); my (@buf); my ($afdtool); my ($afdtoolrescan); $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; if ($rescanstr) { asmcmdshare_trace(3, "NOTE: Rescanning AFD disks; diskstring:'$rescanstr'", 'y', 'n'); $afdtoolrescan = "$afdtool -rescan '$rescanstr'"; } else { asmcmdshare_trace(3, "NOTE: Rescanning AFD disks; using afd_diskstring.", 'y', 'n'); $afdtoolrescan = "$afdtool -rescan"; } asmcmdshare_runcmd($afdtoolrescan, \@buf, 1, 0); if (asmcmdafd_am_root()) { asmcmdafd_update_afddisks(); } if (grep(/Rescanned/i, @buf)) { return 1; } else { return 0; } } #end asmcmdafd_rescan_afd ######## # NAME # asmcmdafd_refresh_afd # # DESCRIPTION # This function refreshes AFD disks on the local system # # PARAMETERS # NONE # # RETURNS # 1 if AFD disks are refreshed; 0 otherwise. ######## sub asmcmdafd_refresh_afd { my (@eargs); my (@buf); my ($afdtool); my ($afdtoolrefresh); $afdtool = "$ENV{'ORACLE_HOME'}/bin/afdtool"; #The path in WIN is ORACLE_HOME/bin/afdtool.exe $afdtool .= ".exe" if($^O =~ /win/i); # Make sure the afdtool binary exists and can be executed. if (! -x $afdtool) { @eargs = ($afdtool); asmcmdshare_error_msg(9516, \@eargs); return 0; } #untaint afdtool $afdtool =~ /([^\n^\r^\t]+)/; $afdtool = $1; asmcmdshare_trace(3, "NOTE: Refreshing AFD disks; using afd_diskstring.", 'y', 'n'); $afdtoolrefresh = "$afdtool -refresh"; asmcmdshare_runcmd($afdtoolrefresh, \@buf, 1, 0); if (asmcmdafd_am_root()) { asmcmdafd_update_afddisks(); } if (grep(/Refreshed/i, @buf)) { return 1; } else { return 0; } } #end asmcmdafd_refresh_afd ######## # NAME # asmcmdafd_afdroot # # DESCRIPTION # This function installs and loads AFD driver on the local system OR # uninstalls AFD from the local system # # PARAMETERS # $action # # RETURNS # 1 if AFD is installed and loaded ; 0 otherwise. ######## sub asmcmdafd_afdroot { my ($action) = @_; my (@eargs); my ($afdroot); my (@lines); my ($line); my ($status); my ($cmdout1); my ($cmdout2); $afdroot = "$ENV{'ORACLE_HOME'}/bin/afdroot"; #The path in WIN is ORACLE_HOME/bin/afdroot.exe $afdroot .= ".exe" if($^O =~ /win/i); # Make sure the afdroot binary exists and can be executed. if (! -x $afdroot) { @eargs = ($afdroot); asmcmdshare_error_msg(9517, \@eargs); return 0; } #untaint afdroot $afdroot =~ /([^\n^\r^\t]+)/; $afdroot = $1; if ($action eq "install") { # Install AFD asmcmdshare_trace(3, "NOTE: Installing AFD... ", 'y', 'n'); # AFD-638: AFD installation correctness verified. $cmdout1 = 638; # non-existing message $cmdout2 = 999; } if ($action eq "uninstall") { # uninstall AFD asmcmdshare_trace(3, "NOTE: Uninstalling AFD... ", 'y', 'n'); #AFD-635: Previous AFD components successfully removed. $cmdout1 = 635; #AFD-633: No AFD installation detected. $cmdout2 = 633; } if (!asmcmdshare_runcmd("$afdroot $action", \@lines, 1, 0)) { foreach $line (@lines) { print $line; if($line =~ /([^\d]+)([^:]+)/) { $status = $2; if(defined($status)) { if(($status eq $cmdout1) || ($status eq $cmdout2)) { # Successfully installed AFD. asmcmdshare_trace(3, "NOTE: Successfully $action". "ed AFD", 'y', 'n'); return 1; } } } } } #asmcmdshare_print("@lines\n"); asmcmdshare_print(join('', @lines)); asmcmdshare_trace(3, "FAIL: Failed to $action AFD", 'y', 'n'); return 0; } #end asmcmdafd_afdroot ######## # NAME # asmcmdafd_create_logdir # # DESCRIPTION # This function creates log directory $ORACLE_HOME/log/$HOST/client. # Call this function only when the command is run as root user. # # PARAMETERS # # RETURNS # 1 if successfully created the log directory; 0 otherwise. ######## sub asmcmdafd_create_logdir { my ($oraclebin) = "$ENV{'ORACLE_HOME'}/bin/oracle"; my ($host) = hostname; my ($logdir); my ($giusr) = ""; my ($cmd); my ($ret) = 0; my (@buf); # Windows Oracle always runs in admin mode if($^O =~ /win/i) { return 1; } # trim domain (ex: .us.oracle.com) from hostname $host =~ s/\..*//; $logdir = "$ENV{'ORACLE_HOME'}/log/$host/client"; if(!(-e $logdir)) { if (asmcmdafd_am_root()) { if ($oraclebin) { $giusr = getpwuid((stat($oraclebin))[4]); asmcmdshare_trace(3, "Creating '$logdir' directory as '$giusr'", 'y', 'n'); $cmd = "mkdir -m 755 -p $logdir"; $ret = asmcmdafd_runcmd_as_user($cmd, $giusr, \@buf); return 1; } } } else { asmcmdshare_trace(3, "AFD log directory : $logdir exists", 'y', 'n'); } return 0; } #end asmcmdafd_create_logdir ######## # NAME # asmcmdafd_create_afddisks # # DESCRIPTION # This function creates AFD disks directory. # Call this function only when the command is run as root user. # # PARAMETERS # # RETURNS # 1 if successfully created the AFD disks directory; 0 otherwise. ######## sub asmcmdafd_create_afddisks { # Windows Oracle always runs in admin mode if($^O =~ /win/i) { return 1; } if(!(-e $AFDDISKLOC)) { my ($oraclebin) = "$ENV{'ORACLE_HOME'}/bin/oracle"; my ($giuid) = ((stat($oraclebin))[4]); my ($gigid) = ((stat($oraclebin))[5]); my ($giusr) = getpwuid((stat($oraclebin))[4]); my ($gigrp) = getgrgid((stat($oraclebin))[5]); asmcmdshare_trace(3, "Creating $AFDDISKLOC directory with $giusr:$gigrp", 'y', 'n'); `mkdir -m 770 -p $AFDDISKLOC`; chown $giuid, $gigid, $AFDDISKLOC; return 1; } else { asmcmdshare_trace(3, "AFD disks directory : $AFDDISKLOC exists", 'y', 'n'); } return 0; } #end asmcmdafd_create_afddisks ######## # NAME # asmcmdafd_update_afddisks # # DESCRIPTION # This function modifies owership of AFD disks files. # Call this function only when the command is run as root user. # # PARAMETERS # # RETURNS # 1 if successfully updated the owership of AFD disks; 0 otherwise. ######## sub asmcmdafd_update_afddisks { # Windows Oracle always runs in admin mode if($^O =~ /win/i) { return 1; } if(-e $AFDDISKLOC) { my ($oraclebin) = "$ENV{'ORACLE_HOME'}/bin/oracle"; my ($giuid) = ((stat($oraclebin))[4]); my ($gigid) = ((stat($oraclebin))[5]); my ($giusr) = getpwuid((stat($oraclebin))[4]); my ($gigrp) = getgrgid((stat($oraclebin))[5]); my (@flist) = glob("$AFDDISKLOC/*"); # expand AFDDISKLOC asmcmdshare_trace(3, "Changing owership of $AFDDISKLOC/* to $giusr:$gigrp", 'y', 'n'); asmcmdshare_trace(3, "Label list under $AFDDISKLOC/* : @flist", 'y', 'n'); if (@flist) { chown $giuid, $gigid, @flist; chmod 0770, @flist; } return 1; } asmcmdshare_trace(3, "No AFD disks directory : $AFDDISKLOC", 'y', 'n'); return 0; } #end asmcmdafd_update_afddisks ######## # NAME # asmcmdafd_is_acfs # # DESCRIPTION # This function checks if AFD is loaded on the local system # # PARAMETERS # $state - installed/loaded/supported # # RETURNS # 1 if ACFS is loaded ; 0 otherwise. ######## sub asmcmdafd_is_acfs { my ($state) = @_; my (@eargs); my (@buf); my ($acfsdriverstate); # return not supproted if not any of these platforms. if (!($^O =~ /win/i) && !($^O =~ /linux/i) && !($^O =~ /solaris/i) && (!($^O =~ /aix/i))) { # not supported return 0; } $acfsdriverstate = "$ENV{'ORACLE_HOME'}/bin/acfsdriverstate"; #The path in WIN is ORACLE_HOME/bin/acfsdriverstate.exe $acfsdriverstate .= ".exe" if($^O =~ /win/i); # Make sure the acfsdriverstate binary exists and can be executed. if (! -x $acfsdriverstate) { @eargs = ($acfsdriverstate); asmcmdshare_error_msg(9518, \@eargs); return; } #untaint acfsdriverstate $acfsdriverstate =~ /([^\n^\r^\t]+)/; $acfsdriverstate = $1; asmcmdshare_runcmd("$acfsdriverstate $state", \@buf, 1, 0); if ((($state =~ /loaded/i) && ($buf[0] =~ /true/i)) || (($state =~ /supported/i) && ($buf[0] =~ /Supported/i)) || (($state =~ /installed/i) && ($buf[0] =~ /true/i))) { asmcmdshare_trace(3, "NOTE: Verifying ACFS driver state : $state", 'y', 'n'); return 1; } else { asmcmdshare_trace(3, "NOTE: Verifying ACFS driver state : Not $state", 'y', 'n'); return 0; } } # end asmcmdafd_is_acfs ######## # NAME # asmcmdafd_is_afd # # DESCRIPTION # This function checks if AFD is loaded on the local system # # PARAMETERS # $state - installed/loaded/supported # # RETURNS # 1 if AFD is loaded ; 0 otherwise. ######## sub asmcmdafd_is_afd { my ($state) = @_; my (@eargs); my (@buf); my ($afddriverstate); # return not supproted if not any of these platforms. if (!($^O =~ /win/i) && !($^O =~ /linux/i) && !($^O =~ /solaris/i) && (!($^O =~ /aix/i))) { # not supported return 0; } $afddriverstate = "$ENV{'ORACLE_HOME'}/bin/afddriverstate"; #The path in WIN is ORACLE_HOME/bin/afddriverstate.exe $afddriverstate .= ".exe" if($^O =~ /win/i); # Make sure the afddriverstate binary exists and can be executed. if (! -x $afddriverstate) { @eargs = ($afddriverstate); asmcmdshare_error_msg(9518, \@eargs); return 0; } #untaint afddriverstate $afddriverstate =~ /([^\n^\r^\t]+)/; $afddriverstate = $1; asmcmdshare_runcmd("$afddriverstate $state", \@buf, 1, 0); if ((($state =~ /loaded/i) && ($buf[0] =~ /true/i)) || (($state =~ /supported/i) && ($buf[0] =~ /9200/i)) || (($state =~ /installed/i) && ($buf[0] =~ /true/i))) { asmcmdshare_trace(3, "NOTE: Verifying AFD driver state : $state", 'y', 'n'); return 1; } else { asmcmdshare_trace(3, "Error: " . join('', @buf), 'y', 'n'); asmcmdshare_trace(3, "NOTE: Verifying AFD driver state : Not $state", 'y', 'n'); return 0; } } # end asmcmdafd_is_afd ######## # NAME # asmcmdafd_am_root # # DESCRIPTION # This function verifies that the command is run as root. # # PARAMETERS # NONE # # RETURNS # 1 if root ; 0 otherwise. ######## sub asmcmdafd_am_root { # Windows Oracle always runs in admin mode if($^O =~ /win/i) { return 1; } if ($>) # get euid { # not zero (root) # If this is AIX, let the grid user in. if ($^O =~ /aix/i) { my $tusr; if (-e "$ENV{'ORACLE_HOME'}/crs/install/crsconfig_params") { $tusr=`grep ORACLE_OWNER $ENV{'ORACLE_HOME'}/crs/install/crsconfig_params|/usr/bin/cut -f2 -d '='`; } my $me=`/bin/id -un`; $tusr =~ s/\s+$//; $me =~ s/\s+$//; if ($me eq $tusr) { return 1; } else { return 0; } } return 0; } return 1; } # end asmcmdafd_am_root ######## # NAME # asmcmdafd_is_siha # # DESCRIPTION # This function verifies that the oracle sw is SIHA. # # PARAMETERS # NONE # # RETURNS # 1 if SIHA ; 0 otherwise. ######## sub asmcmdafd_is_siha { my $val = ""; my $cfgfile = $OCRLOC; my $key = "local_only"; # open OCRCONFIG file asmcmdshare_trace(3, "NOTE: asmcmdafd_is_siha Opening $cfgfile", 'y', 'n'); if (-e $cfgfile) { open (CFGFL, "<$cfgfile") or return $val; while () { if (/^$key=(\S+)/) { $val = $1; last; } } close (CFGFL); asmcmdshare_trace(3, "NOTE: asmcmdafd_is_siha Value ($val) set for $key", 'y', 'n'); } if ($val =~ m/true/i) { return 1; } return 0; } ######## # NAME # asmcmdafd_is_exadata # # DESCRIPTION # This function verifies that the sw env. is Exadata # # PARAMETERS # NONE # # RETURNS # 1 if Exadata ; 0 otherwise. ######## sub asmcmdafd_is_exadata { my $checksc = "/etc/oracle/cell/network-config/cellip.ora"; if (! (-e $checksc)) { asmcmdshare_trace(3, "NOTE: asmcmdafd_is_exadata $checksc not found", 'y', 'n'); return 0; } return 1; } ######## # NAME # asmcmdafd_runcmd_as_user # # DESCRIPTION # Function for running a command as given user # # PARAMETERS # runcmd: cmd to be executed # user: user name # buf_ref: address of the buffer to store the output of the command # # RETURNS # exit code of the system command execution ######## ####--------------------------------------------------------- sub asmcmdafd_runcmd_as_user { my ($runcmd, $user, $buf_ref) = @_; my $ret; my $cmd; my @buf; if ($user) { $cmd = "$SU $user -c \"$runcmd\""; asmcmdshare_trace(3, "NOTE: Invoking \"$cmd\" as user \"$user\"", 'y', 'n'); } else { $cmd = $runcmd; asmcmdshare_trace(3, "NOTE: Invoking \"$cmd\"", 'y', 'n'); } $ret = asmcmdshare_runcmd($cmd, \@buf, 0, 0); @{$buf_ref} = @buf; return $ret; } ######## # NAME # asmcmdafd_is_member_cluster # # DESCRIPTION # Function to verify if the command is run on a member(client) cluster # # PARAMETERS # NONE # # RETURNS # 1 if member cluster ; 0 otherwise. ######## ####--------------------------------------------------------- sub asmcmdafd_is_member_cluster { my ($kfod); my (@buf); my (@eargs); my ($val); my ($ret); $kfod = catfile($ENV{'ORACLE_HOME'}, 'bin', 'kfod'); $kfod .= ".exe" if($^O =~ /win/i); # Make sure the kfod binary exists and can be executed. if (! -x $kfod) { @eargs = ($kfod); asmcmdshare_error_msg(9515, \@eargs); return; } asmcmdshare_runcmd("$kfod op=getclstype nohdr=true", \@buf, 0, 0); if (!$ret) { if (@buf) { # command succeeded asmcmdshare_trace(3, "NOTE: " . join('', @buf), 'y', 'n'); ($val) = grep { /Client cluster/i } @buf; if ($val) { # Client Cluster return 1; } } } return 0; } ######## # NAME # asmcmdafd_is_help # # DESCRIPTION # This function is the help function for the ASMCMDAFD module. # # PARAMETERS # command (IN) - display the help message for this command. # # RETURNS # 1 if command found; 0 otherwise. ######## sub asmcmdafd_process_help { my ($command) = shift; # User-specified argument; show help on $cmd. # my ($desc); # Command description for $cmd. # my ($succ) = 0; # 1 if command found, 0 otherwise. # if (asmcmdafd_is_cmd ($command)) { # User specified a command name to look up. # $desc = asmcmdshare_get_help_desc($command); asmcmdshare_print "$desc\n"; $succ = 1; } return $succ; } ######## # NAME # asmcmdafd_is_cmd # # DESCRIPTION # This routine checks if a user-entered command is one of the known # ASMCMD internal commands that belong to the ASMCMDAFD module. # # PARAMETERS # arg (IN) - user-entered command name string. # # RETURNS # True if $arg is one of the known commands, false otherwise. ######## sub asmcmdafd_is_cmd { my ($arg) = shift; return defined ( $asmcmdafd_cmds{ $arg } ); } ######## # NAME # asmcmdafd_is_wildcard_cmd # # DESCRIPTION # This routine determines if an ASMCMDAFD command allows the use # of wild cards. # # PARAMETERS # arg (IN) - user-entered command name string. # # RETURNS # True if $arg is a command that can take wildcards as part of its argument, # false otherwise. ######## sub asmcmdafd_is_wildcard_cmd { my ($arg) = shift; my (%cmdhash); # Empty hash; no ASMCMDAFD command supports wildcards. # return (asmcmdshare_get_cmd_wildcard($arg) eq "true"); } ######## # NAME # asmcmdafd_is_no_instance_cmd # # DESCRIPTION # This routine determines if a command can run without an ASM instance. # # PARAMETERS # arg (IN) - user-entered command name string. # # RETURNS # 1 if $arg is a command that can run without an ASM instance or it does not # belong to this module # 0 if $arg is a command that needs to connect to an ASM instance # -1 if $arg is a command that may use an ASM instance. # # NOTES # The asmcmdafd module currently supports no command that can run # without an ASM instance. ######## sub asmcmdafd_is_no_instance_cmd { my ($arg) = shift; my ($rc); return 1 unless defined($asmcmdafd_cmds{$arg}); $rc = asmcmdshare_get_cmd_noinst($arg); if ($rc eq "true") { return 1; } elsif ($rc eq "undef") { return -1; } return 0; } ######## # NAME # asmcmdafd_parse_int_args # # DESCRIPTION # This routine parses the arguments for flag options for ASMCMDAFD # internal commands. # # PARAMETERS # cmd (IN) - user-entered command name string. # args_ref (OUT) - hash of user-specified flag options for a command, # populated by getopts(). # # RETURNS # Zero on success; undefined on error. # # NOTES # $cmd must already be verified as a valid ASMCMDAFD internal command. ######## sub asmcmdafd_parse_int_args { my ($cmd, $args_ref) = @_; my ($key); my (@string); # Use Gsmcmdparser_parse_issued_command() from the asmcmdparser package to parse arguments for # internal commands. These arguments are stored in @ARGV. if(!asmcmdparser_parse_issued_command($cmd, $args_ref, \@string)) { # Print correct command format if syntax error. # asmcmdafd_syntax_error($cmd); return undef; } return 0; } ######## # NAME # asmcmdafd_syntax_error # # DESCRIPTION # This function prints the correct syntax for a command to STDERR, used # when there is a syntax error. This function is responsible for # only ASMCMDAFD commands. # # PARAMETERS # cmd (IN) - user-entered command name string. # # RETURNS # 1 if the command belongs to this module; 0 if command not found. # # NOTES # These errors are user-errors and not internal errors. They are of type # record, not signal. # # N.B. Functions in this module can call this function directly, without # calling the asmcmdshare::asmcmdshare_syntax_error equivalent. The # latter is used only by the asmcmdcore module. ######## sub asmcmdafd_syntax_error { my ($cmd) = shift; my ($cmd_syntax); # Correct syntax for $cmd. # my ($succ) = 0; #display syntax only if the command belongs to this module if (asmcmdafd_is_cmd($cmd)) { $cmd_syntax = asmcmdshare_get_help_syntax($cmd); # Get syntax for $cmd. # $cmd_syntax = asmcmdshare_trim_str ($cmd_syntax); # Trim blank spaces # if (defined ($cmd_syntax)) { asmcmdshare_printstderr 'usage: ' . $cmd_syntax . "\n"; asmcmdshare_printstderr 'help: help ' . $cmd . "\n"; $succ = 1; } } return $succ; } ######## # NAME # asmcmdafd_get_asmcmd_cmds # # DESCRIPTION # This routine constructs a string that contains a list of the names of all # ASMCMD internal commands and returns this string. # # PARAMETERS # None. # # RETURNS # A string contain a list of the names of all ASMCMD internal commands. # # NOTES # Used by the help command and by the error command when the user enters # an invalid internal command. # # IMPORTANT: the commands names must be preceded by eight (8) spaces of # indention! This formatting is mandatory. ######## sub asmcmdafd_get_asmcmd_cmds { return asmcmdshare_filter_invisible_cmds(%asmcmdafd_cmds); } 1;