MINI MINI MANI MO
# Copyright (c) 2004, 2018, 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)
# apfwkr 06/11/18 - Backport ssprasad_bug-28074713 from main
# ssprasad 05/25/18 - 28074713: fix in asmcmdafd_isSUSELinux
# wanhlee 08/02/17 - 26564508: Verify afd/acfsdriverstate return result.
# csusarre 04/28/17 - fix afddriverstate and afdroot extensions on Windows
# OS, changed to .bat
# ssprasad 04/27/17 - 25902425: asmcmd/afd-udev to set same permissions
# prabbala 03/27/17 - 25825910: use asmcmdshare_runcmd in sub _isSUSELinux
# siyarlag 01/10/17 - 25117436: check for mc after GI is setup
# 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 = <ASMLIB>)
{
$asmlibexists = 1;
}
close(ASMLIB);
}
open (ASMLIB, "/sbin/lsmod | grep oracleasm |");
while ($asmlib = <ASMLIB>)
{
$asmlibexists = 1;
}
close(ASMLIB);
if ($asmlibexists)
{
my $asm_dis;
$asm_dis = asmcmdafd_get_asmdiskstr_fromprofile();
# Bug 24939841: don't need empty asm_diskstring if not using ASMLib disks
if (($asm_dis) && (($asm_dis =~ /ORCL:/) || ($asm_dis =~ /oracleasm/)))
{
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 '<nodenam>':
$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 '<nodenam>':
$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
# <disk-path> - 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;
}
# 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;
}
if (($afdloaded) && asmcmdafd_is_member_cluster())
{
#9544-"The command is not supported on a member cluster."
asmcmdshare_error_msg(9544);
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 '<nodenam>': 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.
# <disk-string> - 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 '<nodenam>': 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 = <FD>;
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)
{
if (!asmcmdshare_runcmd("/bin/rpm -q sles-release", \@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 = <FD>;
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 = <FD>;
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 = <ASMLIB>)
{
$asmlibexists = 1;
chomp($asmlib);
unlink("$asmlib");
}
close(ASMLIB);
}
open (ASMLIB, "/sbin/lsmod | grep oracleasm |");
while ($asmlib = <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.bat
$afdroot .= ".bat" 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');
# asmcmd and AFD (linux) udev rules should set the same permissions.
# Please see : usm/src/cmds/afdlib/lin/osds*pm
`mkdir -m 775 -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)
{
# asmcmd and AFD (linux) udev rules should set the same permissions.
# Please see : usm/src/cmds/afdlib/lin/osds*pm
chown $giuid, $gigid, @flist;
chmod 0664, @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 ((@buf) &&
((($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.bat
$afddriverstate .= ".bat" 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 ((@buf) &&
((($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 (<CFGFL>) {
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;
OHA YOOOO