# # # okalib.pm # # Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. # # # NAME # okalib.pm - Common (non platform specific) functions used by # the install/runtime scripts. (for OKA) # # DESCRIPTION # Purpose # See above. # # NOTES # All user visible output should be done in the common code. # this will ensure a consistent look and feel across all platforms. # # package okalib; use strict; use English; use acfslib; use Sys::Hostname; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw( lib_check_oka_drivers_installed lib_check_any_oka_driver_installed lib_check_oka_drivers_loaded lib_count_oka_drivers_loaded lib_get_oka_admin_name lib_oka_supported lib_verify_oka_devices lib_load_oka_drivers lib_unload_oka_drivers oka_resource_exists create_oka_drivers_resource_type add_oka_drivers_resource start_oka_drivers_resource delete_oka_drivers_resource modify_oka_drivers_resource stop_oka_drivers_resource activate_oka_drivers_resource deactivate_oka_drivers_resource OKA_IDX OKG_IDX ); use DBI; use acfslib; use osds_okalib; use osds_acfslib; use File::Spec::Functions; my ($ADE_VIEW_ROOT) = $ENV{ADE_VIEW_ROOT}; my ($ORACLE_HOME) = $ENV{ORACLE_HOME}; my ($ORA_CRS_HOME) = $ENV{ORA_CRS_HOME}; # set the product global variable to KA $acfslib::USM_CURRENT_PROD = USM_PROD_OKA; use Config; my ($OSNAME) = $Config{osname}; chomp($OSNAME); # # lib_check_oka_drivers_installed # sub lib_check_oka_drivers_installed { my ($driver); my ($num_drivers_installed) = 0; my ($idx); foreach $idx (0 .. $#OKA_DRIVER_COMPONENTS) { $driver = $OKA_DRIVER_COMPONENTS[$idx]; if($VERBOSE) { lib_inform_print_noalert(9155, "Checking for existing '%s' driver " . "installation.", $driver); } if (lib_osds_check_driver_installed($driver)) { $num_drivers_installed++; } } # in linux we have 2 drivers oracka.ko oracka_mod_kga.ko # in solaris we have 3 drivers oracka oracka_rt skjmodkga. # we look for the size of @OKA_DRIVER_COMPONENTS, to check all drivers installed if ($num_drivers_installed != ($#OKA_DRIVER_COMPONENTS + 1)) { return 0; } return 1; } # end lib_check_oka_drivers_installed # lib_check_any_oka_driver_installed # sub lib_check_any_oka_driver_installed { my ($driver); my ($idx); foreach $idx (0 .. $#OKA_DRIVER_COMPONENTS) { $driver = $OKA_DRIVER_COMPONENTS[$idx]; if($VERBOSE) { lib_inform_print_noalert(9155, "Checking for existing '%s' driver " . "installation.", $driver); } if (lib_osds_check_driver_installed($driver)) { return 1; } } return 0; } # end lib_check_any_oka_driver_installed # lib_count_oka_drivers_loaded # sub lib_count_oka_drivers_loaded { my ($driver); my ($num_drivers_loaded) = 0; my ($idx); foreach $idx (0 .. $#OKA_DRIVER_COMPONENTS) { $driver = $OKA_DRIVER_COMPONENTS[$idx]; if (lib_osds_check_driver_loaded($driver)) { $num_drivers_loaded++; } } return $num_drivers_loaded; } # end lib_count_oka_drivers_loaded # lib_check_oka_drivers_loaded # sub lib_check_oka_drivers_loaded { my ($num_drivers_loaded) = 0; my ($return_val); my ($num_expected_loaded) = 0; my ($idx); my ($driver); # we only need the drivers of type drv to be loaded to return true foreach $idx (0 .. $#OKA_DRIVER_COMPONENTS) { $driver = $OKA_DRIVER_COMPONENTS[$idx]; if ($OKA_DRIVER_INFO{$driver}->{'type'} eq "drv") { $num_expected_loaded++; } } $num_drivers_loaded = lib_count_oka_drivers_loaded(); if ($num_drivers_loaded != $num_expected_loaded) { $return_val = 0; } else { $return_val = 1; } return $return_val; } # end lib_check_oka_drivers_loaded # lib_load_oka_drivers # # Load the drivers if not already loaded. Silently ignore if a driver is loaded # sub lib_load_oka_drivers { my ($driver); my (@loaded); my ($idx); my ($okaadmin); my ($created) = 0; # extract the admin name for use $okaadmin = lib_get_oka_admin_name(); # determine which drivers are already loaded (if any). foreach $idx (0 .. $#OKA_DRIVER_COMPONENTS) { $driver = $OKA_DRIVER_COMPONENTS[$idx]; $loaded[$idx] = 0; if (lib_osds_check_driver_loaded($driver)) { $loaded[$idx] = 1; } } # Load the not already loaded drivers. # The order is important - OKA must be first. # misc drivers do not need to be loaded here. foreach $idx (0 .. $#OKA_DRIVER_COMPONENTS) { $driver = $OKA_DRIVER_COMPONENTS[$idx]; if (!$loaded[$idx]) { my ($return_val); if ($OKA_DRIVER_INFO{$driver}->{'type'} eq "drv") { lib_inform_print_noalert(9154, "Loading '%s' driver.", $driver); $return_val = lib_osds_load_driver($driver, $COMMAND); if ($return_val != USM_SUCCESS) { lib_error_print_noalert(9109, "%s driver failed to load.", $driver); return USM_FAIL; } } if (!$created) { $created = 1; print("Creating oka node...\n"); lib_osds_oka_create_node($okaadmin); } } } return USM_SUCCESS; } # end lib_load_oka_drivers # lib_unload_oka_drivers # # Unload the OKA drivers. Return error if any driver fails to unload. # sub lib_unload_oka_drivers { # Optional argument: location of new install files. Utilities from new # install files may be used to unload drivers if old utilities cannot be # found my ($install_files_loc, $sub_command) = @_; my ($driver); my ($return_val) = USM_SUCCESS; my ($idx); # we unload in the reverse order we loaded foreach $idx (reverse(0 .. $#OKA_DRIVER_COMPONENTS)) { $driver = $OKA_DRIVER_COMPONENTS[$idx]; # nothing to do if the driver is not loaded if (lib_osds_check_driver_loaded($driver)) { # test to see that the driver is not being used if (lib_osds_check_driver_inuse($driver)) { lib_error_print_noalert (9118, "Driver %s in use - cannot unload.", $driver); # If this is 'okaroot install', we pretend to succeed. # This way the new drivers get installed but we exit with # USM_REBOOT_RECOMMENDED. After the reboot, the new drivers are running. if (($COMMAND eq "okaroot") && ($sub_command eq "install")) { $return_val = USM_SUCCESS; } else { $return_val = USM_FAIL; last; } } if ($OKA_DRIVER_INFO{$driver}->{'type'} eq "drv") { $return_val = lib_osds_unload_driver($driver, $install_files_loc); if ($return_val != USM_SUCCESS) { lib_error_print_noalert(9119, "Driver %s failed to unload.", $driver); $return_val = USM_REBOOT_RECOMMENDED; last; } } } } return $return_val; } # end lib_unload_oka_drivers # lib_oka_supported # # call into lib_osds_oka_supported # sub lib_oka_supported { my ($ret) = 0; my ($oka_supported) = 0; if( (defined ($ENV{'ORA_OKA_INSTALL_FORCE'}) ) && ($ENV{ORA_OKA_INSTALL_FORCE} eq "true" ) ) { $ret = 1; } else { # lib_osds_oka_supported returns: # USM_SUPPORTED or USM_NOT_SUPPORTED instead 0 or 1 $oka_supported = lib_osds_oka_supported(); if($oka_supported == USM_SUPPORTED) { if($OSNAME eq "linux") { if(is_Exadata() || is_ODA()) { $ret = 1; } } elsif($OSNAME eq "solaris") { if(is_Exadata() || is_Supercluster()) { $ret = 1; } } } } return $ret; } # end lib_oka_supported # is_Exadata # # check if we are in Exadata # this function is a replica of the one located under # has/install/crsconfig/s_crsutils.pm # sub is_Exadata { my $status; my $checksc = "/etc/oracle/cell/network-config/cellip.ora"; if (! (-e $checksc)) { return 0; } return 1; } # is_ODA # # check if we are in ODA # for the time being this is only a place holder # sub is_ODA { my $status; # it could have several versions, so if you find one, consider ODA # installation my @files = glob('/opt/oracle/extapi/64/oak/liboak.*.so'); for my $file (@files) { if (-e $file) { return 1; } } return 0; } # is_Supercluster # # check if we are in Supercluster # for the time being this is only a place holder # sub is_Supercluster { return is_Exadata(); } # lib_verify_oka_devices # # call into lib_osds_verify_oka_devices # sub lib_verify_oka_devices { return lib_osds_verify_oka_devices(); } # end lib_verify_oka_devices # lib_get_oka_admin_name # # Get the group name of the OKA device # sub lib_get_oka_admin_name { my $okaadmin = 'oinstall'; # for now just a hardcoded value - may want to read from config file return $okaadmin; } # end lib_get_oka_admin_name # # OKA resource utility functions # # Add the OKA drivers resource. sub add_oka_drivers_resource { my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my $grp = acfslib::getParam("ORA_DBA_GROUP"); chomp $grp; my $owner = "root"; my $CRSDUSER = acfslib::getParam("ORACLE_OWNER"); chomp $CRSDUSER; lib_trace( 9176, "Entering '%s'", "adoka drvsres"); if ((($CRSDUSER eq "") || ($grp eq "")) && !($OSNAME eq "Windows_NT" || $OSNAME eq "MSWin32")) { # getParam failed. lib_error_print_noalert(9375, "Adding OKA drivers resource failed."); lib_trace( 9178, "Return code = %s", "USM_FAIL"); lib_trace( 9177, "Return from '%s'", "adoka drvsres"); return USM_FAIL; } if ($OSNAME eq "Windows_NT" || $OSNAME eq "MSWin32") { $owner = "NT AUTHORITY\\SYSTEM"; } my $ret = system($crsctl, "add", "resource", "ora.drivers.oka", "-attr", "ACL='owner:$owner:rwx,pgrp:$grp:r-x,other::r--,user:$CRSDUSER:r-x'", "-type", "ora.oka.type","-init"); lib_trace( 9179, "Command executed: '%s', output = '%s'", "$crsctl", "$ret"); if ($ret != 0) { lib_error_print_noalert(9375, "Adding OKA drivers resource failed."); lib_trace( 9178, "Return code = %s", "USM_FAIL"); lib_trace( 9177, "Return from '%s'", "adoka drvsres"); return USM_FAIL; } else { lib_inform_print_noalert(9376, "Adding OKA drivers resource succeeded."); lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); lib_trace( 9177, "Return from '%s'", "adoka drvsres"); return USM_SUCCESS; } } # Activate the OKA drivers resource. sub activate_oka_drivers_resource { my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my $owner = "root"; lib_trace( 9176, "Entering '%s'", "actoka drvsres"); my $ret = system($crsctl, "modify", "res", "ora.drivers.oka", "-attr", "ENABLED=1","-init"); lib_trace( 9179, "Command executed: '%s', output = '%s'", "$crsctl", "$ret"); if ($ret != 0) { lib_trace( 9178, "Return code = %s", "USM_FAIL"); return USM_FAIL; } else { lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); return USM_SUCCESS; } } # Deactivate the OKA drivers resource. sub deactivate_oka_drivers_resource { my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my $owner = "root"; lib_trace( 9176, "Entering '%s'", "deaoka drvsres"); my $ret = system($crsctl, "modify", "res", "ora.drivers.oka", "-attr", "ENABLED=0","-init"); lib_trace( 9179, "Command executed: '%s', output = '%s'", "$crsctl", "$ret"); if ($ret != 0) { lib_trace( 9178, "Return code = %s", "USM_FAIL"); return USM_FAIL; } else { lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); return USM_SUCCESS; } } # Start the OKA drivers resource. sub start_oka_drivers_resource { my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my @cmd = ($crsctl, "start", "resource", "ora.drivers.oka", "-init"); my $ret = system(@cmd); lib_trace( 9176, "Entering '%s'", "staoka drvsres"); lib_trace( 9179, "Command executed: '%s', output = '%s'", "@cmd", "$ret"); if ($ret != 0) { lib_error_print_noalert(9379, "Starting OKA drivers resource failed."); lib_trace( 9178, "Return code = %s", "USM_FAIL"); lib_trace( 9177, "Return from '%s'", "stoka drvsres"); return USM_FAIL; } else { lib_inform_print_noalert(9380, "Starting OKA drivers resource succeeded."); lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); lib_trace( 9177, "Return from '%s'", "stoka drvsres"); return USM_SUCCESS; } } # Stop the OKA drivers resource. sub stop_oka_drivers_resource { my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my @cmd = ($crsctl, "stop", "resource", "ora.drivers.oka", "-init"); my $ret = system(@cmd); lib_trace( 9176, "Entering '%s'", "stooka drvsres"); if ($ret != 0) { lib_trace( 9178, "Return code = %s", "USM_FAIL"); return USM_FAIL; } else { lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); return USM_SUCCESS; } } # Create the OKA type sub create_oka_drivers_resource_type { my $type = "ora.oka.type"; my $baseType = "ora.daemon.type"; my $templateFile = "oka.type"; my $ORACLE_HOME = $ENV{'ORACLE_HOME'}; my $CRS_HOME_TEMPLATE = catdir($ORACLE_HOME, "crs", "template"); my $file = catfile($CRS_HOME_TEMPLATE, $templateFile); my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my @cmd = ($crsctl, "add", "type", $type, "-basetype", $baseType, "-file", "$file", "-init"); my $ret = system(@cmd); lib_trace( 9176, "Entering '%s'", "creaoka type"); if ($ret != 0) { lib_trace( 9178, "Return code = %s", "USM_FAIL"); return USM_FAIL; } else { lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); return USM_SUCCESS; } } # Delete the OKA drivers resource. sub delete_oka_drivers_resource { my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my @cmd = ($crsctl, "delete", "resource", "ora.drivers.oka", "-f", "-init"); my $ret = system(@cmd); lib_trace( 9176, "Entering '%s'", "deoka drvsres"); lib_trace( 9179, "Command executed: '%s', output = '%s'", "@cmd", "$ret"); if ($ret != 0) { lib_error_print_noalert(9377, "Deleting OKA drivers resource failed."); lib_trace( 9178, "Return code = %s", "USM_FAIL"); lib_trace( 9177, "Return from '%s'", "deoka drvsres"); return USM_FAIL; } else { lib_inform_print_noalert(9378, "Deleting OKA drivers resource succeeded."); lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); lib_trace( 9177, "Return from '%s'", "deoka drvsres"); return USM_SUCCESS; } } # oka_resource_exists # returns USM_SUCCESS if the specified resource exists. # returns USM_FAIL if the specified resource does not exist. # returns USM_FAIL if en error is encountered. # sub oka_resource_exists { my ($resource) = @_; my ($which); my ($opt) = ""; my ($ret) = USM_SUCCESS; lib_trace( 9176, "Entering '%s'", "kres exists"); lib_trace( 9182, "Variable '%s' has value '%s'", "resource", "$resource"); if ($resource eq "drivers") { $which = "ora.drivers.oka"; $opt = "-init"; } if ($ret == USM_SUCCESS) { open CRSCTL, "$ORACLE_HOME/bin/crsctl stat res $which $opt |"; if ($?) { $ret = USM_FAIL; } else { while () { if (/CRS-2613/) { # "Could not find resource '%s'." $ret = USM_FAIL; last; } } close CRSCTL; } } if( $ret == USM_SUCCESS){ lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); }elsif( $ret == USM_FAIL){ lib_trace( 9178, "Return code = %s", "USM_FAIL"); }else{ lib_trace( 9178, "Return code = %s", "$ret"); } lib_trace( 9177, "Return from '%s'", "urest exists"); return $ret; } sub modify_oka_drivers_resource { my $crsctl = File::Spec->catfile($ORACLE_HOME, "bin", "crsctl"); my $grp = acfslib::getParam("ORA_DBA_GROUP"); my $CRSDUSER = acfslib::getParam("ORACLE_OWNER"); chomp $CRSDUSER; my $owner = "root"; chomp $grp; my @cmd; my $ret; my $ret1 = 0; lib_trace( 9176, "Entering '%s'", "modk drvrs res"); lib_trace( 9182, "Variable '%s' has value '%s'", "CRSDUSER", "$CRSDUSER"); lib_trace( 9182, "Variable '%s' has value '%s'", "grp", "$grp"); if (($CRSDUSER eq "") || ($grp eq "")) { # getParam failed. lib_error_print_noalert(9381, "Modification of OKA drivers resource failed."); lib_trace( 9178, "Return code = %s", "USM_FAIL"); lib_trace( 9177, "Return from '%s'", "modu drvrs res"); return USM_FAIL; } if ($OSNAME eq "Windows_NT" || $OSNAME eq "MSWin32") { $owner = "NT AUTHORITY\\SYSTEM"; } @cmd = ($crsctl, "modify", "resource", "ora.drivers.oka", "-attr", "ACL='owner:$owner:r-x,pgrp:$grp:r-x,user:$CRSDUSER:r-x,other::r--'", "-init"); $ret = system(@cmd); lib_trace( 9179, "Command executed: '%s', output = '%s'", "@cmd", "$ret"); $ret1 = ($ret) ? 1 : $ret1; if ($ret1 != 0) { lib_error_print_noalert(9381, "Modification of OKA drivers resource failed."); lib_trace( 9178, "Return code = %s", "USM_FAIL"); lib_trace( 9177, "Return from '%s'", "modu drvrs res"); return USM_FAIL; } lib_inform_print_noalert(9382, "Modification of OKA drivers resource succeeded."); lib_trace( 9178, "Return code = %s", "USM_SUCCESS"); lib_trace( 9177, "Return from '%s'", "modu drvrs res"); return USM_SUCCESS; } ########################################### ######## Local only static routines ####### ########################################### 1;