MINI MINI MANI MO
#
# osds_acfslib.pm
#
# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
#
#
# NAME
# osds_acfslib.pm - Linux OSD library components.
#
# DESCRIPTION
# Purpose
# Linux OSD library functions for the install/runtime scripts.
#
# NOTES
# All user visible output should be done in the common code.
# this will ensure a consistent look and feel across all platforms.
#
#
use strict;
use acfslib;
use osds_unix_linux_acfslib;
package osds_acfslib;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(
lib_osds_check_uninstall_required
lib_osds_check_driver_inuse
lib_osds_check_driver_installed
lib_osds_check_driver_loaded
lib_osds_check_loaded_drivers_mismatch
lib_osds_create_udev
lib_osds_exportfs
lib_osds_get_os_type
lib_osds_get_make_type
lib_osds_get_usm_udev_rules_file
lib_osds_load_driver
lib_osds_remove_exports
lib_osds_restore_exports
lib_osds_unload_driver
lib_osds_get_linux_vendor
lib_osds_is_mounted
lib_osds_validate_asmadmin_group
lib_osds_is_local_container
lib_osds_acfsr_configure
lib_osds_acfs_remote_supported
lib_osds_acfs_remote_installed
lib_osds_acfs_remote_loaded
lib_osds_get_home_driver_path
lib_osds_get_drivers_version
@DRIVER_COMPONENTS
%configuration
lib_osds_check_config
lib_osds_check_kernel
lib_osds_is_siha
lib_osds_uncompress_driver_files
);
use File::Copy;
our (@DRIVER_COMPONENTS) = (
"oracleadvm.ko", "oracleoks.ko", "oracleacfs.ko",
);
# We default to 0 = STANDALONE mode as the default install mode of the drivers
# This variable is used to write to the advmtunables file the asm_acfsr_mode
# tunable.
our ($DOM) = 0;
our $asm_storage_mode = "near";
our $udev_rules_location = "/etc/udev/rules.d/65-usm-acfsr-member.rules";
our $udev_script_location = "/usr/lib/udev/acfsr_member";
our $iscsi_conf_location = "/etc/iscsi/iscsid.conf"; # Location of the iSCSI
# configuration file
my ($CACHED_INSTALLED_DRIVERS); # saved find /lib/modules output
my ($CACHED_LOADED_DRIVERS); # saved find lsmod output
my ($EXPORTFS) = "/usr/sbin/exportfs";
my ($UNAME_R) = `uname -r`;
chomp ($UNAME_R);
my ($ARCH) = `uname -i`;
chomp ($ARCH); # e.g., "x86-64"
chomp ($UNAME_R);
my ($CGROUP) = "/proc/1/cgroup"; # LXC information file
#Declare a hash array to store configuration values
our (%configuration) = ();
# /sbin/fuser ... RH Enterprise Linux
# /bin/fuser ... Suse
# /usr/sbin/fuser ... AIX, HPUX, Solaris
# /usr/sbin/lsof ... RH Enterprise Linux
# /sbin/modprobe ... RH Enterprise Linux
$ENV{PATH} = $ENV{PATH} . ":/sbin:/bin:/usr/sbin";
# lib_osds_check_driver_inuse
#
# use lsmod to see if a driver is in use.
#
sub lib_osds_check_driver_inuse
{
my ($driver) = @_;
my ($ret_val) = 0;
# strip ".ko" from driver name
$driver =~ s/.ko//;
# USM drivers must be loaded.
# This should have happened in clsinitd when clusterware started.
open (INUSE, "lsmod |");
while (<INUSE>)
{
my ($name, $size, $use_count) = split;
if ($name eq $driver)
{
$ret_val = $use_count;
last;
}
}
close (INUSE);
return $ret_val;
} # end lib_osds_check_driver_inuse
use File::Basename;
# lib_osds_check_driver_installed()
#
sub lib_osds_check_driver_installed
{
my ($driver) = @_;
my ($usm_driver);
# only do the find(1) once.
if (!defined($CACHED_INSTALLED_DRIVERS))
{
#Change directory to tmp
if (defined($ENV{'TEMP'}) && (-d "$ENV{'TEMP'}"))
{
chdir $ENV{'TEMP'};
}
elsif (defined($ENV{'TMP'}) && (-d "$ENV{'TMP'}"))
{
chdir $ENV{'TMP'};
}
elsif (-d "/tmp/")
{
chdir "/tmp";
}
# search /lib/modules for the installed drivers.
$CACHED_INSTALLED_DRIVERS = "";
# conditional code for RAC KA product
if ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
open (USM, "find /lib/modules/ | grep oracle |");
}
elsif ($acfslib::USM_CURRENT_PROD eq "prod_oka")
{
open (USM, "find /lib/modules/ | grep oracka |");
}
else
{
open (USM, "find /lib/modules/ | grep usm |");
}
while ($usm_driver = <USM>)
{
$usm_driver = basename($usm_driver);
chomp($usm_driver);
$CACHED_INSTALLED_DRIVERS .= "$usm_driver ";
}
close(USM);
}
if ($CACHED_INSTALLED_DRIVERS =~ m/$driver/)
{
return 1;
}
# fail
return 0;
} # end lib_osds_check_driver_installed
# lib_osds_check_uninstall_required
#
sub lib_osds_check_uninstall_required
{
my ($previous_install_detected_msg) = @_;
my ($return_code);
$return_code = acfslib::lib_check_any_driver_installed();
if(($return_code) && ($previous_install_detected_msg))
{
acfslib::lib_inform_print(9312, "Existing ADVM/ACFS installation detected.");
}
return $return_code;
} # end lib_osds_check_uninstall_required
# lib_osds_check_driver_loaded
#
# use lsmod to see if a driver is loaded.
#
sub lib_osds_check_driver_loaded
{
my ($driver) = @_;
my ($ret_val) = 0;
my ($usm_driver);
my (@cached_loaded_drivers_array);
# strip ".ko" from driver name
$driver =~ s/.ko//;
# Linux Container configuration
# Host and Container are sharing '/proc/modules' and hence 'lsmod'
# shows that oracle modules are configured and loaded.
# Because ACFS/ADVM drivers are not supported on Linux Containers,
# return early
if ( acfslib::lib_is_local_container() )
{
return $ret_val;
}
# only do the lsmod(8) once.
if (!defined($CACHED_LOADED_DRIVERS))
{
$CACHED_LOADED_DRIVERS = "";
open (LOADED, "lsmod |");
while ($usm_driver = <LOADED>)
{
my ($module, $size, $used, $by) = split(/\s+ /, $usm_driver);
$CACHED_LOADED_DRIVERS .= "$module ";
}
close (LOADED);
}
@cached_loaded_drivers_array = split(/ /, $CACHED_LOADED_DRIVERS);
foreach $usm_driver (@cached_loaded_drivers_array)
{
if ($usm_driver eq $driver)
{
$ret_val = 1;
last;
}
}
return $ret_val;
} # end lib_osds_check_drivers_loaded
# lib_osds_check_loaded_drivers_mismatch
#
# Determine whether or not the installed drivers match the drivers that
# are loaded in the kernel.
sub lib_osds_check_loaded_drivers_mismatch
{
my $drvIKModule; #InstalledKModule
my $oskvers; #OS_KernelVersion
my $confpath = "/etc/sysconfig/oracledrivers.conf";
my @drvModule;
my $drvpath;
my $fhandle;
my $driver;
if ($acfslib::USM_CURRENT_PROD eq "prod_oka")
{
$driver = "OKA";
}
elsif ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
$driver = "AFD";
}
elsif ($acfslib::USM_CURRENT_PROD eq "prod_olfs")
{
$driver = "OLFS";
}
else
{
$driver = "ACFS";
}
if (-e $confpath)
{
open ($fhandle,"<",$confpath) or do
{
lib_error_print(9295,"failed to open file %s",$confpath);
return osds_unix_linux_acfslib::USM_SUCCESS;
};
# Get $driver kernel version
foreach (<$fhandle>)
{
if ($_ =~ /${driver}OS_KernelVersion/)
{
$oskvers = $_;
$oskvers = (split(/=/,$oskvers))[-1];
chomp ($oskvers);
$oskvers =~ s/^\s+|\s+$//g;
last;
}
elsif ($_ =~ /${driver}InstalledKModule/)
{
$drvIKModule = $_;
$drvIKModule = (split(/=/,$drvIKModule))[-1];
chomp ($drvIKModule);
$drvIKModule =~ s/^\s+|\s+$//g;
}
}
close ($fhandle);
}
# Compare the OS Kernel version of the Installed module against
# the current OS kernel version.
if (defined $oskvers)
{
# OS_KernelVersion(oracledrivers.conf) ne uname -r
if ($oskvers ne $UNAME_R)
{
# OS kernel version differs from the driver kernel version
# Compare the current kernel module to install vs the one installed.
$drvpath = lib_osds_get_home_driver_path ("$acfslib::_ORACLE_HOME".
"/usm/install", lib_osds_get_os_type(undef), `uname -i`,
$UNAME_R, undef);
# 2.6.39-400
$drvpath = (split(/\//,$drvpath))[-3];
# 2.6.39-400.211.1.el6uek.x86_64
@drvModule = split(/\./,$drvIKModule);
# 2.6.39-400
@drvModule = @drvModule[0..$#drvModule-4];
$drvIKModule = join('.',@drvModule);
if ($drvpath ne $drvIKModule)
{
return osds_unix_linux_acfslib::USM_FAIL;
}
}
}
return osds_unix_linux_acfslib::USM_SUCCESS;
}
# lib_osds_create_udev
#
# Create a USM udev file
#
sub lib_osds_create_udev
{
my ($asmadmin) = @_;
my ($udev_perm_file);
$udev_perm_file = lib_osds_get_usm_udev_rules_file();
# create the permissions file - replaces existing file (if any)
open PERM, ">$udev_perm_file" or die "can't create file: $!";
print PERM "#\n";
print PERM "# ADVM devices\n";
print PERM "KERNEL==\"asm/*\", GROUP=\"$asmadmin\", MODE=\"0770\"\n";
print PERM "KERNEL==\"asm/.*\", GROUP=\"$asmadmin\", MODE=\"0770\"\n";
print PERM "#\n";
print PERM "# ACFS devices\n";
print PERM "KERNEL==\"ofsctl\", GROUP=\"$asmadmin\", MODE=\"0664\"\n";
close PERM;
} # end lib_osds_create_udev
# lib_osds_exportfs
#
# called after a file system is mounted. If the mount point is in
# /etc/exports, we export the file system here.
#
sub lib_osds_exportfs
{
my ($mountpoint) = @_;
# TBD: parse /etc/exports and if $mountpoint is listed, export
# the file sustem.
#
# For now, we use brute force. Calling "exportfs -a" repeatedly is
# harmless and quick.
system("$EXPORTFS -a");
} # end lib_osds_exportfs
# lib_osds_get_os_type
#
# Add to this routine as USM supports new Linux variants
#
sub lib_osds_get_os_type
{
# conditional code for RAC KA product
if ($acfslib::USM_CURRENT_PROD eq "prod_oka")
{
return lib_osds_get_oka_os_type(@_);
}
# Check whether ACFS/AVD/AFD is supported
return lib_osds_get_acfs_os_type(@_);
}
# This api is for ACFS/ADVM/AFD.
sub lib_osds_get_acfs_os_type
{
my ($vers) = "unknown";
my ($kver) = $UNAME_R;
my ($release);
my ($supported) = 0;
my ($test_mode, $test_release,
$test_version, $test_patchlevel, $test_arch) = @_;
# during "acfsroot install" we get called 12 times (really).
if (!$test_mode &&
$configuration{version})
{
return $configuration{version};
}
# Check to see if we support this Linux release
# see - http://www.oracle.com/us/technologies/027626.pdf and
# see - http://www.oracle.com/us/technologies/linux6cert-400781.pdf
if (-e "/etc/oracle-release")
{
open (RPM_QF, "rpm -qf /etc/oracle-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
elsif (-e "/etc/redhat-release")
{
open (RPM_QF, "rpm -qf /etc/redhat-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
elsif (-e "/etc/SuSE-release")
{
open (RPM_QF, "rpm -qf /etc/SuSE-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
# Big distributions using systemd have to use os-release file.
# EL7/RHEL7 and SLES12 include this file and they can
# deprecate their own release files
# http://comments.gmane.org/gmane.comp.sysutils.systemd.devel/4401
# http://www.freedesktop.org/software/systemd/man/os-release.html
elsif (-e "/etc/os-release")
{
open (RPM_QF, "rpm -qf /etc/os-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
if (defined($release))
{
chomp($release);
}
if ($test_mode)
{
$release = $test_release;
$kver = $test_version;
$ARCH = $test_arch;
}
# Testing for "oraclelinux_release", etc prevents us from dropping
# into the code below from other RH based distros like CentOS, for example.
if ((defined($release)) && # Redhat or OEL if defined
(($release =~ /^redhat-release/) || # straight RH
($release =~ /^enterprise-release/) || # Oracle Enterprise Linux
($release =~ /^oraclelinux-release/))) # Oracle Linux
{
my ($major, $minor, $patch, $vendor, $variation) = split /\./, $kver;
my ($micro_number, $patch_level) = split /-/, $patch; # e.g., 100 and 32
if ($vendor =~ /\D/)
{
$vendor = 0;
}
if ($kver =~ /debug?/)
{
# we do not build drivers for debug kernels.
$vers = $kver;
$supported = 0;
}
elsif ($ARCH =~ /i[3-6]86/)
{
$vers = "i386"; # 32 bit kernels not supported
$supported = 0;
}
elsif ($release =~ /AXS/) # Asianux Not supported
{
$vers = "ASIANUX";
$supported = 0;
}
elsif ($release =~ /release-4/) # RH/EL 4 Not Supported
{
$vers = "Linux 2.4";
$supported = 0;
}
elsif ($release =~ /release-5/) # RH/OEL 5 Partially Supported
{
# We assume unsupported unless we specifically indicate otherwise.
$vers = $kver;
$supported = 0;
# Support for EL5 is removed in 12.2, support for 2.6.18 and
# the rest of EL5 is going away.
if ($kver =~ /2.6.18/)
{
$supported = 0;
$vers = "EL5";
}
elsif ($kver =~ /uek/)
{
if ($kver =~ /2.6.32-100/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.32-200/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.32-300/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.32-400/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.39-100/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.39-200/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.39-300/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.39-400/)
{
$vers = "EL5";
$supported = 0;
}
}
}
elsif (($release =~ /release-6/) || # OEL 6 Partially Supported
($release =~ /server-6/)) # RHEL 6 Partially Supported
{
# We assume unsupported unless we specifically indicate otherwise.
$vers = $kver;
$supported = 0;
#Oracle Linux 6 ships with two sets of kernel packages:
# Unbreakable Enterprise Kernel (Ex: kernel-uek-2.6.32-100.28.5.el6),
# which is available only on the x86_64 (64-bit) platform
#
# Red Hat compatible kernel (Ex: kernel-2.6.32-71.el6).
#So, We can find uek or rhel compatible kernels.
if ($kver =~ /uek/)
{
if ($kver =~ /2.6.39-100/)
{
$vers = "EL6";
$supported = 1;
}
elsif ($kver =~ /2.6.39-200/)
{
$vers = "EL6";
$supported = 1;
}
elsif ($kver =~ /2.6.39-300/)
{
$vers = "EL6";
$supported = 1;
}
elsif ($kver =~ /2.6.39-400/)
{
if ($vendor >= 278 &&
$vendor < 281)
{
$vers = "EL6";
$supported = 0;
}
else
{
$vers = "EL6";
$supported = 1;
}
}
elsif ($kver =~ /3.8.13/)
{
if (($patch_level == 118) &&
($vendor >= 5 &&
$vendor < 8))
{
$vers = "EL6";
$supported = 0;
}
else
{
$vers = "EL6";
$supported = 1;
}
}
elsif ($kver =~ /4.1.12/)
{
$vers = "EL6";
$supported = 1;
}
}
else #For RHEL Kernels. We only support GA, U1 and U2.
{
#For compatible RHEL6 Kernels, We check the number release
#We support 6.0, 6.1, 6.2 and 6.3
my $LSB_RELEASE;
if(-e "/usr/bin/lsb_release") {
$LSB_RELEASE = `/usr/bin/lsb_release -sr`;
}
if ($test_mode) {
$LSB_RELEASE = "6.0"; #By default
}
#### Split $LSB_RELEASE
my ($major_lsb, $minor_lsb);
if(defined($LSB_RELEASE)){
($major_lsb, $minor_lsb) = split /\./, $LSB_RELEASE;
}
#### $major_lsb has to be equal to 6 and $minor_lsb between 0 and 3
if ((defined($major_lsb) && defined($minor_lsb)) &&
($major_lsb == 6 && ($minor_lsb >= 0 and $minor_lsb <= 3)) &&
($kver =~ /2.6.32/))
{
#RHEL6 GA - Start in 71
#RHEL6 U1 - Start in 131
#RHEL6 U2 - Start in 220
#RHEL6 U3 - Start in 279
#RHEL6 U9 - Start in 696
#We check Build Number -XXX
my ($krelease, $kremainder) = split /-/, $kver;
my ($kvariation) = split /\./, $kremainder;
if ($kvariation != 100 &&
$kvariation >= 71 &&
$kvariation < 131)
{
$vers = "EL6";
$supported = 1;
}
elsif ($kvariation >= 131 &&
$kvariation < 220)
{
$vers = "EL6";
$supported = 1;
}
elsif ($kvariation >= 220 &&
$kvariation < 279)
{
$vers = "EL6";
$supported = 1;
}
elsif ($kvariation >= 279 &&
$kvariation < 696)
{
$vers = "EL6";
$supported = 1;
}
elsif ($kvariation >= 696)
{
$vers = "EL6";
$supported = 1;
}
}
else {
# For RHEL6. We are supporting all the number releases.
# But we are not sure, if we can load or not the drivers.
# Installation process has to do a validation to predict success
# loading the drivers
$vers = "EL6";
$supported = 1;
}
}
} # release-6
elsif (($release =~ /release-7/) || # OEL 7 Supported
($release =~ /server-7/)) # RHEL 7 Supported
{
# We assume unsupported unless we specifically indicate otherwise.
$vers = $kver;
$supported = 0;
#Oracle Linux 7 ships with two sets of kernel packages:
# Unbreakable Enterprise Kernel
# (Ex: kernel-uek-3.8.13-35.el7uek.x86_64).
#
# Red Hat compatible kernel (Ex: kernel-3.10.0-123.el7.x86_64).
#
#So, We can find uek or rhel compatible kernels.
if ($kver =~ /uek/)
{
if ($kver =~ /3.8.13/)
{
if ($patch_level >= 35)
{
if (($patch_level == 118) &&
($vendor >= 5 &&
$vendor < 8))
{
$vers = "EL7";
$supported = 0;
}
else
{
$vers = "EL7";
$supported = 1;
}
}
}
elsif ($kver =~ /4.1.12/)
{
if ($patch_level >= 32)
{
$vers = "EL7";
$supported = 1;
}
}
}
else #For RHEL Kernels.
{
#For compatible RHEL7 Kernels, We check the number release
#We support 7.0, 7.1. 7.2, 7.3 and 7.4
# RHEL 7.0 3.10.0-123
# RHEL 7.1 3.10.0-229
# RHEL 7.2 3.10.0-327
# RHEL 7.3 3.10.0-514
# RHEL 7.4 3.10.0-693
# RHEL 7.5 3.10.0-862
my $LSB_RELEASE;
if(-e "/usr/bin/lsb_release") {
$LSB_RELEASE = `/usr/bin/lsb_release -sr`;
}
if ($test_mode) {
$LSB_RELEASE = "7.0"; #By default
}
#### Split $LSB_RELEASE
my ($major_lsb, $minor_lsb);
if(defined($LSB_RELEASE)){
($major_lsb, $minor_lsb) = split /\./, $LSB_RELEASE;
}
#### $major_lsb has to be equal to 7 and $minor_lsb between 0 and 1
if ((defined($major_lsb) && defined($minor_lsb)) &&
($major_lsb == 7 && ($minor_lsb >= 0 and $minor_lsb <= 4)) &&
($kver =~ /3.10.0/))
{
#We check Build Number -XXX
my ($krelease, $kremainder) = split /-/, $kver;
my ($kvariation) = split /\./, $kremainder;
if (($kvariation >= 123) &&
($kvariation < 210))
{
$vers = "EL7";
$supported = 1;
}
elsif (($kvariation >= 210) &&
($kvariation < 327))
{
$vers = "EL7";
$supported = 1;
}
elsif (($kvariation >= 327) &&
($kvariation < 514))
{
$vers = "EL7";
$supported = 1;
}
elsif (($kvariation >= 514) &&
($kvariation < 693))
{
$vers = "EL7";
$supported = 1;
}
elsif (($kvariation >= 693) &&
($kvariation < 862))
{
$vers = "EL7";
$supported = 1;
}
elsif ($kvariation >= 862)
{
$vers = "EL7";
$supported = 1;
}
}
elsif (($major == 3) && ($minor == 10))
{
# For RHEL7. We are supporting all the number releases.
# But we are not sure, if we can load or not the drivers.
# Installation process has to do a validation to predict success
# loading the drivers
$vers = "EL7";
$supported = 1;
}
}
} # release-7
} # RH/OEL
elsif (defined($release) && $release =~ /^sles-release/)
{
my ($major, $minor, $patch, $vendor, $variation) = split /\./, $kver;
my ($micro_number, $patch_level) = split /-/, $patch; # e.g., 100 and 32
my ($line);
my ($SPnumber) = 0;
if ($test_mode)
{
$SPnumber = $test_patchlevel;
}
else
{
if (-e "/etc/SuSE-release")
{
open (RELEASE, "/etc/SuSE-release");
while ($line = <RELEASE>)
{
if ($line =~ /PATCHLEVEL/)
{
# format: "PATCHLEVEL = 3"
my ($patchlevel, $equals, $number) = split(/ /, $line);
chomp ($number);
$SPnumber = $number;
last;
}
}
close (RELEASE);
}
elsif (-e "/etc/os-release")
{
open (RELEASE, "/etc/os-release");
while ($line = <RELEASE>)
{
if ($line =~ /VERSION_ID/)
{
# format: VERSION_ID="12"
my ($version_id, $number) = split(/=/, $line);
chomp ($number);
$number =~ s/\"//g;
my ($nversion, $patchnumber) = split(/\./, $number);
if (defined($patchnumber))
{
$SPnumber = $patchnumber;
}
last;
}
}
close (RELEASE);
}
}
# We assume unsupported unless we specifically indicate otherwise.
$vers = "$kver SP$SPnumber";
$supported = 0;
if ($kver =~ /debug?/)
{
# we do not build drivers for debug kernels.
$vers = $kver;
$supported = 0;
}
elsif ($ARCH eq "i386")
{
$supported = 0;
$vers = "i386";
}
elsif ($release =~ /^sles-release-11/)
{
if (($kver =~ /2.6.32/) && ($SPnumber == 1))
{
$supported = 0;
$vers = "SLES11";
}
elsif (($kver =~ /^3.0/) && ($SPnumber == 2))
{
$supported = 0;
$vers = "SLES11";
}
elsif (($kver =~ /^3.0/) && ($SPnumber == 3))
{
# For SP3, We don't support all the 3.0.*Kernels
# SuSe just releases the 3 following kernels:
# SP3-July-2013 3.0.76-0.11.1
# July-11-2013 3.0.82-0.7.9
# Sept-21-2013 3.0.93-0.8.2
# So, We support greater than 3.0.76-0
if ($micro_number >= 76) {
$supported = 0;
$vers = "SLES11";
}
}
elsif (($kver =~ /^3.0/) && ($SPnumber == 4))
{
# For SP4. SuSe release Kernel 3.0.101-63.1
if ($micro_number >= 101) {
$supported = 0;
$vers = "SLES11";
}
}
}
elsif ($release =~ /^sles-release-12/)
{
if (($kver =~ /^3.12/) && ($SPnumber == 0))
{
# SLES 12 was released with the kernel version
# 3.12.28-4.6.
if ($micro_number >= 28) {
$supported = 1;
$vers = "SLES12";
}
}
elsif (($kver =~ /^3.12/) && ($SPnumber == 1))
{
# SLES 12 SP1 was released with the kernel version
# 3.12.49-11.1
if ($micro_number >= 49) {
$supported = 1;
$vers = "SLES12";
}
}
elsif (($kver =~ /^4.4/) && ($SPnumber == 2))
{
# SLES 12 SP2 was released with the kernel version
# 4.4.21-69.1
if ($micro_number >= 21) {
$supported = 1;
$vers = "SLES12";
}
}
elsif (($kver =~ /^4.4/) && ($SPnumber == 3))
{
# SLES 12 SP3 was released with the kernel version
# 4.4.73-5
if ($micro_number >= 73) {
$supported = 1;
$vers = "SLES12";
}
}
}
}
else
{
# Not Redhat, OEL, SUSE, etc.
$vers = $release;
$supported = 0;
}
if (defined($release))
{
$configuration{release} = $release;
}
$configuration{env_var} = (defined($ENV{_ORA_USM_NOT_SUPPORTED})? "yes" : "no");
if (($supported) && (not defined($ENV{_ORA_USM_NOT_SUPPORTED})))
{
# Required by usm_root - $vers MUST be a sub-directory in the install path
# e.g., install/Oracle/EL5/i386/2.6.18-8/2.6.18-8.el5PAE-i686/bin
# ^^^
$configuration{version} = $vers;
return $vers;
}
if ( defined($ENV{_ORA_USM_NOT_SUPPORTED}))
{
$vers .= " (via ENV VARIABLE)";
}
if (! $test_mode)
{
if ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
afdlib::lib_error_print_noalert(620,
"AFD is not supported on this operating system version: '%s'",
$vers);
}
else
{
acfslib::lib_error_print_noalert(9459,
"ADVM/ACFS is not supported on this OS version: '%s'",
$vers);
}
}
if ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
$configuration{version} = "AFD is not supported on $vers";
return "AFD is not supported on $vers";
}
$configuration{version} = "ADVM/ACFS is not supported on $vers";
return "ADVM/ACFS is not supported on $vers";
} # end get_os_type
# RAC KA install - related
sub lib_osds_get_oka_os_type
{
my ($vers) = "unknown";
my ($kver) = $UNAME_R;
my ($release);
my ($supported) = 0;
my ($test_mode, $test_release, $test_version, $test_patchlevel) = @_;
# during "okaroot install" we get called 12 times (really).
if (!$test_mode &&
$configuration{version})
{
return $configuration{version};
}
# Check to see if we support this Linux release
# see - http://www.oracle.com/us/technologies/027626.pdf
if (-e "/etc/oracle-release")
{
open (RPM_QF, "rpm -qf /etc/oracle-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
elsif (-e "/etc/redhat-release")
{
open (RPM_QF, "rpm -qf /etc/redhat-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
elsif (-e "/etc/SuSE-release")
{
open (RPM_QF, "rpm -qf /etc/SuSE-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
elsif (-e "/etc/os-release")
{
open (RPM_QF, "rpm -qf /etc/os-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
if ($test_mode)
{
$release = $test_release;
$kver = $test_version;
}
if(!defined($release))
{
$vers = $kver;
$supported = 0;
}
# Testing for "oraclelinux_release", etc prevents us from dropping
# into the code below from other RH based distros like CentOS, for example.
elsif (($release =~ /^redhat-release/) || # straight RH
($release =~ /^enterprise-release/) || # Oracle Enterprise Linux
($release =~ /^oraclelinux-release/)) # Oracle Linux
{
my ($major, $minor, $patch, $subpatch1, $subpatch2) = split /\./, $kver;
my ($micro_number, $patch_level) = split /-/, $patch; # e.g., 100 and 32
$vers = $kver; # We default to $kvers
if ($kver =~ /debug?/)
{
# we do not build drivers for debug kernels.
$vers = $kver;
$supported = 0;
}
elsif ($ARCH eq "i386")
{
$vers = "i386"; # 32 bit kernels not supported
$supported = 0;
}
elsif ($release =~ /AXS/) # Asianux Not supported
{
$vers = "ASIANUX";
$supported = 0;
}
elsif ($release =~ /release-4/) # RH/EL 4 Not Supported
{
$vers = "Linux 2.4";
$supported = 0;
}
elsif ($release =~ /release-5/) # RH/OEL 5 Partially Supported
{
if ($kver =~ /2.6.18/)
{
$supported = 0;
$vers = "EL5";
}
elsif ($kver =~ /uek/)
{
if ($kver =~ /2.6.32/)
{
$vers = "EL5";
$supported = 0;
}
elsif ($kver =~ /2.6.39/)
{
$vers = "EL5";
# we support starting with 2.6.39_400.205 since in this version
# rds netfilter support was added Bug 17082619
if ((acfslib::lib_is_number($patch_level) && $patch_level == 400) &&
(acfslib::lib_is_number($subpatch1) && $subpatch1 >= 205))
{
$supported = 0;
}
if (acfslib::lib_is_number($patch_level) && $patch_level > 400)
{
$supported = 0;
}
}
}
}
elsif ($release =~ /release-6/) # RH/OEL 6 Partially Supported
{
if ($kver =~ /uek/)
{
if ($kver =~ /2.6.32/)
{
$vers = "EL6";
$supported = 0;
}
elsif ($kver =~ /2.6.39/)
{
$vers = "EL6";
# we support starting with 2.6.39_400.205 since in this version
# rds netfilter support was added Bug 17082619
if ((acfslib::lib_is_number($patch_level) && $patch_level == 400) &&
(acfslib::lib_is_number($subpatch1) && $subpatch1 >= 205))
{
$supported = 1;
}
if (acfslib::lib_is_number($patch_level) && $patch_level > 400)
{
$supported = 1;
}
}
elsif ($kver =~ /4.1.12/)
{
$vers = "EL6";
$supported = 1;
}
}
} # release-6
} # RH/OEL
elsif ($release =~ /^sles-release/)
{
my ($line);
my ($SPnumber);
if ($test_mode)
{
$SPnumber = $test_patchlevel;
}
else
{
open (RELEASE, "/etc/SuSE-release");
while ($line = <RELEASE>)
{
if ($line =~ /PATCHLEVEL/)
{
# format: "PATCHLEVEL = 3"
my ($patchlevel, $equals, $number) = split(/ /, $line);
chomp ($number);
$SPnumber = $number;
}
}
close (RELEASE);
}
# We assume unsupported unless we specifically indicate otherwise.
$vers = "$kver SP$SPnumber";
$supported = 0;
if ($kver =~ /debug?/)
{
# we do not build drivers for debug kernels.
$vers = $kver;
$supported = 0;
}
elsif ($ARCH eq "i386")
{
$supported = 0;
$vers = "i386";
}
elsif ($release =~ /^sles-release-11/)
{
if (($kver =~ /2.6.32/) && ($SPnumber == 1))
{
$supported = 0;
$vers = "SLES11";
}
elsif (($kver =~ /^3.0/) && ($SPnumber == 2))
{
$supported = 0;
$vers = "SLES11";
}
}
}
else
{
# Not Redhat, OEL, SUSE, etc.
$vers = $release;
$supported = 0;
}
if ($supported)
{
# Required by okaroot - $vers MUST be a sub-directory in the install path
# e.g., install/Oracle/EL5/i386/2.6.18-8/2.6.18-8.el5PAE-i686/bin
# ^^^
$configuration{version} = $vers;
return $vers;
}
if (! $test_mode)
{
okalib::lib_error_print(620,
"OKA is not supported on this operating system version: '%s'",
$vers);
}
$configuration{version} = "OKA is not supported on $vers";
return "OKA is not supported on $vers";
} # end lib_osds_get_oka_os_type
# lib_osds_get_make_type
#
# THIS IS CALLED ONLY BY THE MAKEFILES
#
# Add to this routine as USM supports new Linux variants
# This routine determines what platforms ACFS will build on.
# This is not the same as the platforms we run on, and is
# provided for the convenience of our makefiles so that they
# know how to setup various variables. This was easier than
# implementing this logic in the make script itself.
#
# Note that this is almost a copy of the lib_osds_get_os_type
# function, with some vers and supported changes - as
# not all supported platforms for building are supported for
# running on.
#
sub lib_osds_get_make_type
{
my ($vers) = "unknown";
my ($kver) = $UNAME_R;
my ($release);
my ($supported) = 0;
# Check to see if we support this Linux release
# see - http://www.oracle.com/us/technologies/027626.pdf
if (-e "/etc/oracle-release")
{
open (RPM_QF, "rpm -qf /etc/oracle-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
elsif (-e "/etc/redhat-release")
{
open (RPM_QF, "rpm -qf /etc/redhat-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
elsif (-e "/etc/SuSE-release")
{
open (RPM_QF, "rpm -qf /etc/SuSE-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
# Big distributions using systemd have to use os-release file.
# EL7/RHEL7 and SLES12 include this file and they can
# deprecate their own release files
# http://comments.gmane.org/gmane.comp.sysutils.systemd.devel/4401
# http://www.freedesktop.org/software/systemd/man/os-release.html
elsif (-e "/etc/os-release")
{
open (RPM_QF, "rpm -qf /etc/os-release 2>&1 |");
$release = <RPM_QF>;
close (RPM_QF);
}
# Testing for "oraclelinux_release", etc prevents us from dropping
# into the code below from other RH based distros like CentOS, for example.
if ((defined($release)) && # Redhat or OEL if defined
(($release =~ /^redhat-release/) || # straight RH
($release =~ /^enterprise-release/) || # Oracle Enterprise Linux
($release =~ /^oraclelinux-release/))) # Oracle Linux
{
my ($major, $minor, $patch, $vendor, $variation) = split /\./, $kver;
my ($micro_number, $patch_level) = split /-/, $patch; # e.g., 100 and 32
if ($vendor =~ /\D/)
{
$vendor = 0;
}
if ($release =~ /AXS/) # Asianux Not supported
{
$vers = "ASIANUX";
$supported = 0;
}
elsif ($release =~ /release-4/) # RH/EL 4 Supported
{
# Uses the same build infrastructure as EL5.
$vers = "EL5";
$supported = 0;
}
elsif ($release =~ /release-5/) # RH/OEL 5 Supported
{
# We support only 2.6.18, 2.6.32, and 2.6.39
if (($kver =~ /2.6.18/) || ($kver =~ /2.6.32/) || ($kver =~ /2.6.39/))
{
if ($kver =~ /2.6.32-100/)
{
$vers = "EL5UEK32_100";
$supported = 0;
}
elsif ($kver =~ /2.6.32-200/)
{
$vers = "EL5UEK32_200";
$supported = 0;
}
elsif ($kver =~ /2.6.32-300/)
{
$vers = "EL5UEK32_300";
$supported = 0;
}
elsif ($kver =~ /2.6.32-400/)
{
$vers = "EL5UEK32_400";
$supported = 0;
}
elsif ($kver =~ /2.6.39-100/)
{
$vers = "EL5UEK39_100";
$supported = 0;
}
elsif ($kver =~ /2.6.39-200/)
{
$vers = "EL5UEK39_200";
$supported = 0;
}
elsif ($kver =~ /2.6.39-300/)
{
$vers = "EL5UEK39_300";
$supported = 0;
}
elsif ($kver =~ /2.6.39-400/)
{
$vers = "EL5UEK39_400";
$supported = 0;
}
else
{
my @end;
my @numbers_before_first_period;
# Need to check for RH5U4 or later
# kver = 2.6.18-9.el5
@end=split '-', $kver;
# @end = 2.6.18, 9.el5
@numbers_before_first_period=split '\.', $end[1];
# @numbers_before_first_period = 9, el5
if ($numbers_before_first_period[0] >= 164)
{
if ($kver =~ /xen/ )
{
$vers = "EL5XEN164";
}
else
{
$vers = "EL5164";
}
}
else
{
$vers = "EL5";
}
$supported = 0;
}
}
else
{
# Unsupported RH/OEL 5 kernel
$vers = $kver;
$supported = 0;
}
}
elsif ($release =~ /release-6/) # RH/OEL 6 Partially Supported
{
# ensure 64 bit system
if ($ARCH eq "x86_64")
{
# First, we check support for 2.6.32 and 2.6.39
if (($kver =~ /2.6.32/) || ($kver =~ /2.6.39/))
{
if ( $kver =~ /uek/ )
{
if ($kver =~ /39-100/)
{
$vers = "EL6UEK39_100";
$supported = 1;
}
elsif ($kver =~ /39-200/)
{
$vers = "EL6UEK39_200";
$supported = 1;
}
elsif ($kver =~ /39-300/)
{
$vers = "EL6UEK39_300";
$supported = 1;
}
elsif ($kver =~ /39-400/)
{
if ($vendor >= 278 &&
$vendor < 281)
{
$vers = "EL6UEK39_400_16K";
$supported = 0;
}
else
{
$vers = "EL6UEK39_400";
$supported = 1;
}
}
}
else
{
# This is a pretty simplistic way of looking at things.
# Basically, patch levels aren't fixed, so anything
# from 71 to 220 is ga build, etc.
# We'll take this view for now, and if things get bad later,
# beef it up.
# Defaulting to latest RH kernel build (u3) for now.
if ($micro_number == 32)
{
if ($patch_level >= 71 &&
$patch_level < 220)
{
$vers = "EL6";
$supported = 1;
}
elsif ($patch_level >= 220 &&
$patch_level < 279)
{
$vers = "EL6U2";
$supported = 1;
}
elsif ($patch_level >= 279 &&
$patch_level < 573)
{
$vers = "EL6U3";
$supported = 1;
}
else
{
$vers = "EL6U7_16K";
$supported = 1;
}
}
}
}
#now check for kernel series 3.x.x
elsif($kver =~ /3.8.13/)
{
if (($patch_level == 118) &&
($vendor >= 5 &&
$vendor < 8))
{
$vers = "EL6UEK3813_16K";
$supported = 0;
}
else
{
$vers = "EL6UEK3813";
$supported = 1;
}
}
elsif($kver =~ /4.1.12/)
{
if (($patch_level < 94) ||
($patch_level == 94 &&
$vendor < 8))
{
$vers = "EL6UEK4";
$supported = 1;
}
elsif (($patch_level < 112) ||
($patch_level == 112 &&
$vendor < 16))
{
$vers = "EL6UEK4_94";
$supported = 1;
}
else
{
$vers = "EL6UEK4_112";
$supported = 1;
}
}
else
{
$vers = $kver;
$supported = 0;
}
}
else
{
# 32-bit EL6 is not supported
$vers = $kver;
$supported = 0;
}
}
elsif ($release =~ /release-7/)
{
# ensure 64 bit system
if ($ARCH eq "x86_64")
{
#Check for kernel series 3.x.x
if($kver =~ /3.8.13/)
{
if (($patch_level == 118) &&
($vendor >= 5 &&
$vendor < 8))
{
$vers = "EL7UEK3813_16K";
$supported = 0;
}
else
{
$vers = "EL7UEK3813";
$supported = 1;
}
}
elsif ($kver =~ /3.10.0/)
{
if ($patch =~ /0-229/) #U1
{
$vers = "EL7U1";
$supported = 1;
}
elsif ($patch =~ /0-327/) #U2
{
$vers = "EL7U2";
$supported = 1;
}
elsif ($patch =~ /0-514/) #U3
{
$vers = "EL7U3";
$supported = 1;
}
elsif ($patch =~ /0-693/) #U4
{
$vers = "EL7U4";
$supported = 1;
}
else
{
$vers = "EL7";
$supported = 1;
}
}
elsif($kver =~ /4.1.12/)
{
if (($patch_level < 94) ||
($patch_level == 94 &&
$vendor < 8))
{
$vers = "EL7UEK4";
$supported = 1;
}
elsif (($patch_level < 103))
{
$vers = "EL7UEK4_94";
$supported = 1;
}
elsif (($patch_level < 112) ||
($patch_level == 112 &&
$vendor < 16))
{
$vers = "EL7UEK4_103";
$supported = 1;
}
else
{
$vers = "EL7UEK4_112";
$supported = 1;
}
}
}
else
{
# Any other architecture EL7 is not supported
$vers = $kver;
$supported = 0;
}
}
else
{
# Unsupported RH/OEL release
$vers = $release;
$supported = 0;
}
}
elsif (defined($release) && $release =~ /^sles-release/)
{
if ($release =~ /^sles-release-11/)
{
# ensure 64 bit system
if ($ARCH eq "x86_64")
{
if ($kver =~ /2.6.32/)
{
$supported = 0;
$vers = "SLES11SP1";
}
elsif ($kver =~ /^3.0.13-0.27/)
{
$supported = 0;
$vers = "SLES11SP2";
}
elsif ($kver =~ /^3.0.76-0.11/)
{
$supported = 0;
$vers = "SLES11SP3";
}
elsif ($kver =~ /^3.0.101-63/)
{
$supported = 0;
$vers = "SLES11SP4";
}
else
{
# Don't report supported for other variants
$vers = $kver;
$supported = 0;
}
}
else
{
# not 64 bit
$supported = 0;
$vers = "SLES11 ($ARCH)";
}
}
elsif ($release =~ /^sles-release-12/)
{
# ensure 64 bit system
if ($ARCH eq "x86_64")
{
if ($kver =~ /^3.12.28/)
{
# SLES 12 was released with the kernel version
# 3.12.28-4.6.
$supported = 1;
$vers = "SLES12";
}
elsif ($kver =~ /^3.12.49/)
{
# SLES 12 SP1 was released with the kernel version
# 3.12.49-11.1
$supported = 1;
$vers = "SLES12SP1";
}
elsif ($kver =~ /^4.4.21/)
{
# SLES 12 SP2 was released with the kernel version
# 4.4.21-69
$supported = 1;
$vers = "SLES12SP2";
}
elsif ($kver =~ /^4.4.73/)
{
# SLES 12 SP3 was released with the kernel version
# 4.4.73-5
$supported = 1;
$vers = "SLES12SP3";
}
elsif ($kver =~ /^4.4.120/)
{
# SLES 12 SP3 Rerpoline was released with the kernel
# version 4.4.120-94
$supported = 1;
$vers = "SLES12SP3RETPOLINE";
}
else
{
# Don't report supported for other variants
$vers = $kver;
$supported = 0;
}
}
else
{
# not 64 bit
$supported = 0;
$vers = "SLES12 ($ARCH)";
}
}
else
{
# non supported SUSE release
$supported = 0;
$vers = $release;
}
}
else
{
# Not Redhat, OEL, SUSE, etc.
$vers = $release;
$supported = 0;
}
# $vers MUST be a sub-directory in the install path
# e.g., install/Oracle/EL5/i386/2.6.18-8/2.6.18-8.el5PAE-i686/bin
# ^^^
# required by usm_root.
return $vers;
} # end get_make_type
# lib_osds_get_linux_vendor
#
# Get the vendor string for this Linux version:
# e.g. usm/install/$vendor/EL5/...
# ^^^ this directory name
sub lib_osds_get_linux_vendor
{
my ($vers);
# conditional code for KA product
if ($acfslib::USM_CURRENT_PROD eq "prod_oka")
{
$vers = lib_osds_get_oka_os_type();
}
# Check if ADVM/ACFS/AFD is supported
else
{
$vers = lib_osds_get_os_type(@_);
}
if ($vers =~ /^el/i)
{
return "Oracle";
}
elsif ($vers =~ /^sles/i)
{
return "Novell";
}
return $vers;
}
# lib_osds_get_usm_udev_rules_file
#
# get USM udev rules directory and file used by both install/uninstall
#
sub lib_osds_get_usm_udev_rules_file
{
return get_udev_common("/etc/udev/rules.d", "udev_rules", "55-usm.rules");
}
# lib_osds_load_driver()
#
# use modprobe to load the specified driver
#
sub lib_osds_load_driver
{
my ($driver, $COMMAND, $test, $tdriver_installed,
$tdriver_match, $force_test) = @_;
my ($result) = 0;
my ($vendor) = lib_osds_get_linux_vendor();
# USM_INSTALL_ON_NEWER_DRIVER_ALWAYS is set
my ($USM_INSTALL_ON_NEWER_DRIVER_ALWAYS) = 1;
# We'll force the install process in some special case
# that we need it. Force install is disabled by default,
# But if for some reason, we want to force the install
# process, we need to set USM_FORCE_INSTALL_ON_LOAD,
# environment variable.
my ($force_install) = 0;
if ((defined($ENV{'USM_FORCE_INSTALL_ON_LOAD'})) ||
($test && $force_test))
{
$force_install = 1;
}
if ($vendor eq "Novell")
{
# if this is a different kernel than the last that we ran on, we need
# to make symlinks to the drivers in the correct lib/modules directory.
$result = lib_osds_sles_mklinks();
if ($result)
{
return $result;
}
}
else # RH or OEL
{
my ($ref) = acfslib::lib_get_drivers_version();
if ( $COMMAND eq "acfsload" ||
$COMMAND eq "okaload" ||
$COMMAND eq "afdload" ||
(($COMMAND eq "test") &&
(defined $ref || $test)) )
{
my %drvdata = %{$ref} if (defined($ref));
# Before loading the driver, we need to check that installed drivers
# in "/lib/modules", match with the Available drivers in "usm/install".
# Available drivers comes from function lib_osds_get_home_driver_path,
# same function used for "acfsroot install/version_check" or
# "acfsdriverstate supported" for selecting the drivers to install
# according to the installed kernel.
# So, we need to compare Installed vs Available,"KERNVERS" is extracted
# using modinfo for reading the vermagic, so it should be an exact match
# for this variable, if not we'll run "acfsroot install".
# We have other information available BugHash, VSNFULL, BuildNo.
# So, in the future we can do a more thorough match.
# Installed -> KERNVERS = '4.1.12-32.el7uek.x86_64', vermagic value in
# modinfo from the driver installed in /lib/modules.
# vermagic: 4.1.12-32.el7uek.x86_64 SMP mod_unload modversions
my ($drelease) = $drvdata{"Installed"}{"KERNVERS"};
# Available -> KERNVERS = '4.1.12-112.16.4.el7uek.x86_64', vermagic value
# in modinfo from the best match driver in our usm/install directory.
# vermagic: 4.1.12-112.16.4.el7uek.x86_64 SMP mod_unload modversions
my ($krelease) = $drvdata{"Available"}{"KERNVERS"};
chomp($drelease) if (defined($drelease));
chomp($krelease) if (defined($krelease));
if ($test)
{
$drelease = $tdriver_installed;
$krelease = $tdriver_match;
}
if ( ($drelease ne $krelease) ||
($force_install) )
{
#Just for testing, we return INSTALL
if ($COMMAND eq "test")
{
return "INSTALL";
}
elsif ($COMMAND eq "acfsload")
{
# the kernel and the drivers are not both 2.6.18, for example.
acfslib::lib_inform_print(9226,
"ADVM/ACFS drivers not correct for this OS - cannot load.");
acfslib::lib_inform_print(9399,
"Calling 'acfsroot install' to install compatible ADVM/ACFS drivers.");
system("${acfslib::_ORACLE_HOME}/bin/acfsroot install");
exit $?;
}
elsif($COMMAND eq "afdload")
{
# the kernel and the drivers are not both 2.6.18, for example.
acfslib::lib_inform_print(9226,
"AFD drivers not correct for this OS - cannot load.");
acfslib::lib_inform_print(9399,
"Calling 'afdroot install' to install compatible AFD drivers.");
system("${acfslib::_ORACLE_HOME}/bin/afdroot install");
exit $?;
}
else
{
# the kernel and the drivers are not both 2.6.18, for example.
acfslib::lib_inform_print(9226,
"OKA drivers not correct for this OS - cannot load.");
acfslib::lib_inform_print(9399,
"Calling 'okaroot install' to install compatible OKA drivers.");
system("${acfslib::_ORACLE_HOME}/bin/okaroot install");
exit $?;
}
}
else
{
# DEBUG
# print "continue to load using the existing installation\n";
}
}
}
#Just for testing, we return LOAD
if ($test)
{
return "LOAD";
}
# strip ".ko" from driver name
my ($driver_less_ko) = $driver;
$driver_less_ko =~ s/.ko//;
$result = system("modprobe $driver_less_ko");
if ($result)
{
return osds_unix_linux_acfslib::USM_FAIL;
}
if ($driver_less_ko eq 'oracleacfs')
{
my $result = 0;
my $return_code = 0;
my $storage_mode = acfslib::getParam("ASM_CONFIG");
if ($storage_mode ne '')
{
if ($storage_mode eq 'near')
{
$storage_mode = 0;
}
else
{
$storage_mode = 1;
}
# Set the ACFS Remote storage mode tunable (AcfsRemoteStorageMode).
$result = system("$acfslib::ACFSUTIL tune " .
"AcfsRemoteStorageMode=$storage_mode " .
"1>/dev/null"); # Only hide 'success'
if($result != 0)
{
acfslib::lib_error_print(3099, "error updating driver tunables");
return osds_unix_linux_acfslib::USM_FAIL;
}
}
}
return osds_unix_linux_acfslib::USM_SUCCESS;
} # end lib_osds_load_driver
# lib_osds_remove_exports
#
# Called before unmounting a file system to remove any NFS exports.
# Returns a list of removed exports. The list is triply subscripted, the
# first being the mountpoint, the second the client, the third, options.
# If the unmount fails, the removed exports are restored from this list.
#
# Note that an exportfs output entry may be more than one line
#
# Note that you can have the following exports
# /test
# /test/123
# /test123
# If the mountpoint to be unexported is "/test", we remove
# "/test" and "/test/123", but not "/test123".
#
sub lib_osds_remove_exports
{
my ($mountpoint) = @_; # mount point to remove export.
my ($mountpoint_slash); # mount point, "/" terminated
my ($line); # a line of output from "exportfs".
my ($exportfs_mountpoint); # mountpoint from exportfs output.
my ($exportfs_client); # client from exportfs output.
my ($exportfs_options); # options from exportfs output.
my (@export_list); # returned list of items we unexported.
my ($index) = 0; # index into the export_list.
open EXPORT, "$EXPORTFS -v |"
or warn ("failed to read exportfs list: $!"), return @export_list;
while ($line = <EXPORT>)
{
# replace tabs with spaces, lose the <CRLF>
$line =~ s/\t/ /g;
chomp($line);
# an exportfs entry may be more than one line
if ($line =~ /^\//)
{
my (@array) = split /\s+/, $line;
my ($last_element) = $#array;
if ($last_element == 0)
{
# There is more than one line for the entry.
# This is the first line and has only the mountpoint.
$exportfs_mountpoint = $line;
next;
}
# The line contains both mount point and client.
chomp ($array[0]);
chomp ($array[1]);
$exportfs_mountpoint = $array[0];
$exportfs_client = $array[1];
}
else
{
# this is the second part of the entry - the line has only the client
$line =~ s/ //g;
$exportfs_client = $line;
}
# This is so we can differentiate between
# "/test", "/test/123", and "/test123".
$mountpoint_slash = $mountpoint . "/";
if (($exportfs_mountpoint eq $mountpoint) ||
($exportfs_mountpoint =~ $mountpoint_slash))
{
# We have a match! Unexport the entry and record it in export_list.
# Separate the options from $exportfs_client.
# Format: <node>.<domain>(ro,wdelay,....,anongid=65534)
my (@array) = split /\(/,$exportfs_client;
$exportfs_client = $array[0];
$exportfs_options = $array[1];
$exportfs_options =~ s/\)//;
# exportfs prints "<world>" if the /etc/exports client field is "*".
if ($exportfs_client =~ "^<world>")
{
$exportfs_client =~ s/<world>/\\*/;
}
$export_list[$index][0] = $exportfs_mountpoint;
$export_list[$index][1] = $exportfs_client;
$export_list[$index][2] = $exportfs_options;
$index++;
system("$EXPORTFS -u $exportfs_client:$exportfs_mountpoint");
}
}
close (EXPORT);
return @export_list;
} # end lib_osds_remove_exports
# lib_osds_restore_exports
#
# This is called if an unmount fails.
# If we removed any exports, before the failed unmount, restore them here.
#
sub lib_osds_restore_exports
{
my (@export_list) = @_;
my ($index) = 0;
while(defined($export_list[$index]))
{
my ($exportfs_mountpoint) = $export_list[$index][0];
my ($exportfs_client) = $export_list[$index][1];
my ($exportfs_options) = $export_list[$index++][2];
system(
"$EXPORTFS -o $exportfs_options $exportfs_client:$exportfs_mountpoint");
}
} #end lib_osds_restore_exports
# lib_osds_unload_driver()
#
# use modprobe to unload the specified driver
#
sub lib_osds_unload_driver
{
my ($driver) = @_;
# strip ".ko" from driver name
my ($driver_less_ko) = $driver;
$driver_less_ko =~ s/.ko//;
my @lsmod_result = "";
my $result = 0;
#
# In the (very rare) case where we are running the LRGs with the ODA
# SHIM capabilities enabled, we need to shutdown the SHMU portion by
# hand. To that end we will attempt to invoke the 'shim_unload' option
# to advmutil. Note: if (a) advmutil does not "understand" 'shim_unload'
# or (b) the SHIM stuff is not being used, then this command will fail
# silently. If, on the other hand, we are indeed using the ADVM SHIM
# stuff and this command fails, well then the driver unload will fail
# and eventually the LRG will be killed... C'est la vie...
#
if ($driver_less_ko eq "oracleadvm")
{
system("advmutil shml_shutdown 1>/dev/null 2>/dev/null");
}
# If module is not listed try to unload the next one
if (! system("lsmod | grep $driver_less_ko > /dev/null 2>&1"))
{
$result = system("modprobe -r $driver_less_ko");
if ($result != 0)
{
# Command modprobe could not unload the driver.
# We will try with rmmod
$result = system("rmmod $driver_less_ko");
}
}
# remove driver from the cache
if ($result == 0)
{
$CACHED_LOADED_DRIVERS =~ s/$driver_less_ko//g;
}
return $result;
} # end lib_osds_unload_driver
# lib_osds_sles_mklinks
#
# acfsroot for Suse placed the drivers in the /lib/modules directory for
# which the driver was created - e.g., /lib/modules/2.6.16.60-0.54.5-smp
# If that's what the user is running, all is good. For other kernels, we need
# the drivers under /lib/modules/`uname -r` - in effect, /sbin/weak-modules,
# which does not exist in SuSe. We'd like to do this in acfsroot but
# there's a problem if the user upgrades the kernel and does not re-install
# USM. The subsequent acfsload would fail because modprobe would not find
# the drivers. This routine is called from the driver load routine and checks
# to see if there are proper links under /lib/modules/`uname -r`, if required,
# and creates them if not.
#
sub lib_osds_sles_mklinks
{
my ($src_dir);
my ($dst_dir) = "/lib/modules/$UNAME_R/extra/usm";
my ($component);
my ($return_val) = 0;
my ($checkdriver) = "$dst_dir/$DRIVER_COMPONENTS[0]";
my ($findmodule) = "oracleoks";
if ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
$dst_dir = "/lib/modules/$UNAME_R/extra/oracle";
$checkdriver = "$dst_dir/oracleafd.ko";
$findmodule = "oracleafd";
}
if (! -d $dst_dir)
{
# create the destination directory if needed.
`mkdir -p $dst_dir`;
if ($?)
{
acfslib::lib_error_print(9345,
"Unable to create directory: '%s'.", $dst_dir);
return 1;
}
}
else
{
# check to name sure that a driver is there
# (assume that the rest will be there too.
if (-e "$checkdriver")
{
# This is the typical case and we leave without having serious work to do.
return 0;
}
}
# The USM driver that is *not* a symlink is our source base. This is where
# "acfsroot install" placed the drivers.
my ($file);
my ($basedir);
open FIND, "find /lib/modules | grep $findmodule |";
while ($file = <FIND>)
{
chomp($file);
if (! -l $file )
{
# file is not a symlink
my (undef, $lib, $modules, $version) = split /\//, $file;
$basedir = $version;
last;
}
}
close (FIND);
if (!defined($basedir))
{
# "can not happen" since we checked for an existing install
# well before we got here.
acfslib::lib_error_print(9344,
"Missing directory: '%s'.", "<driver base>");
return 1;
}
# Now create the symlinks.
$src_dir = "/lib/modules/$basedir/extra/usm";;
if ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
$src_dir = "/lib/modules/$basedir/extra/oracle";;
}
# src_dir is where the acfsroot/afdroot placed the drivers.
if ($src_dir ne $dst_dir)
{
if ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
$component = "oracleafd.ko";
`ln -sf "$src_dir/$component" "$dst_dir/$component"`;
if ($?)
{
$return_val = 1;
acfslib::lib_error_print (9350,
"Failed to create a symbolic link from '%s' to '%s'.",
"$src_dir/$component", "$dst_dir/$component");
}
}
else
{
foreach $component (@DRIVER_COMPONENTS)
{
`ln -sf "$src_dir/$component" "$dst_dir/$component"`;
if ($?)
{
$return_val = 1;
acfslib::lib_error_print (9350,
"Failed to create a symbolic link from '%s' to '%s'.",
"$src_dir/$component", "$dst_dir/$component");
}
}
}
if ($return_val == 1)
{
return 1;
}
# Run depmod so that modprobe(8) can find the drivers.
my ($cmd) = "/bin/bash -c \"/sbin/depmod $UNAME_R 2>&1\"|";
my ($print_header) = 1;
open (MOD, $cmd);
while (<MOD>)
{
if ($_ =~ /^WARNING:/ ||
$_ =~ /KsSetThreadPriority*.*$DRIVER_COMPONENTS[1]$/ ||
$_ =~ /KsRwLockReadTry*.*$DRIVER_COMPONENTS[1]$/ ||
$_ =~ /KsGetLogSize*.*$DRIVER_COMPONENTS[1]$/ ||
$_ =~ /acfs*.*$DRIVER_COMPONENTS[1]$/ ||
$_ =~ /advm*.*$DRIVER_COMPONENTS[1]$/ ||
$_ =~ /oks*.*$DRIVER_COMPONENTS[1]$/ ||
$_ =~ /afd*.*$findmodule$/ )
{
next;
}
if ($print_header)
{
acfslib::lib_print_cmd_header($cmd);
$print_header = 0;
}
acfslib::lib_inform_print (9999, "$_");
}
close (MOD);
}
return 0;
} # end lib_osds_sles_mklinks
# lib_osds_is_mounted
#
# check to see if the specified mount point is active
#
sub lib_osds_is_mounted
{
my ($mount_point) = @_; # mount point to test
my ($mounted) = 0; # assume not mounted
my ($line);
# Remove trailing slash, if any, so that grep will work.
$mount_point =~ s/\/$//;
# Bug 9589426 - ACFS DBHOME resource fails to start in Linux
# Print an error if relative pathname is provided for a mountpoint
# to reflect review comments instead of making it work.
my $slash = '/';
my $idx = index($mount_point, $slash);
if ( ! acfslib::lib_is_abs_path ( $mount_point ) )
{
acfslib::lib_error_print(9366,
"Relative path for mount point '%s' is not supported.", $mount_point);
return $mounted;
}
# Use /proc/mounts on Linux. /etc/mtab can be stale (see man page).
open (CHK_MOUNT, "grep \" $mount_point \" /proc/mounts |");
while ($line = <CHK_MOUNT>)
{
# Format hint where mount_point = "/mymount":
# /dev/asm/crsdg1vol1-23 /mymount acfs rw,device,rootsuid 0 0
$mounted = 1 if ( $line =~ /^[\S]+ +$mount_point +/ );
last;
}
close (CHK_MOUNT);
return $mounted;
} # end lib_osds_is_mounted
# lib_osds_get_current_installed_version
#
# Get the currently installed kernel build and USM driver versions
#
sub lib_osds_get_current_installed_version
{
my ($line);
my ($driver);
my ($instdriver);
my (@array);
my ($driver_version); # USM driver version (label date)
my ($kernel_version);
my ($release_version);
my ($abuild_number); # Available build number
my ($abuild_version); # Available build version
my ($oradrvpath);
# conditional code for RAC KA product
if ($acfslib::USM_CURRENT_PROD eq "prod_oka")
{
open(DRIVER, "find /lib/modules/ | grep oracka |");
}
elsif ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
open(DRIVER, "find /lib/modules/ | grep oracleafd |");
}
else
{
open(DRIVER, "find /lib/modules/ | grep oks |");
}
$driver = <DRIVER>;
close(DRIVER);
open (STRINGS, "strings $driver |");
while ($line = <STRINGS>)
{
if ($line =~ /vermagic/)
{
$kernel_version = $line;
}
elsif ($line =~ /USM BUILD LABEL: (\S+)/)
{
# The usm_label_info[] global contains:
# usm_ade_label_info_make_header.pl: USM BUILD LABEL: USM_MAIN_LINUX.X64_100506
$driver_version = $1;
}
# got all of our info?
if (defined($driver_version) && defined($kernel_version))
{
last;
}
}
close(STRINGS);
return $oradrvpath if (!defined($acfslib::_ORACLE_HOME));
$oradrvpath = lib_osds_get_home_driver_path ("${acfslib::_ORACLE_HOME}/usm/install",
lib_osds_get_os_type(undef), `uname -i`, `uname -r`, undef);
return $oradrvpath if (!defined $oradrvpath);
acfslib::lib_uncompress_all_driver_files($oradrvpath);
$driver = "";
# conditional code for RAC KA product
if ($acfslib::USM_CURRENT_PROD eq "prod_oka")
{
open(DRIVER, "find $oradrvpath | grep oracka |");
}
elsif ($acfslib::USM_CURRENT_PROD eq "prod_afd")
{
open(DRIVER, "find $oradrvpath | grep oracleafd |");
}
else
{
open(DRIVER, "find $oradrvpath | grep oracleoks |");
}
$driver = <DRIVER>;
close(DRIVER);
open (STRINGS, "strings $driver |");
while ($line = <STRINGS>)
{
# The usm_label_info[] global contains:
# usm_ade_label_info_make_header.pl: USM BUILD LABEL: USM_MAIN_LINUX.X64_100506
if ($line =~ /USM BUILD LABEL: (\S+)/)
{
$abuild_number = $1;
}
# got all of our info?
if (defined($abuild_number))
{
last;
}
}
close(STRINGS);
# Return an undefined variable if we don't have all of our info.
# That signals failure to the caller.
return $driver_version if (!defined($driver_version));
return $kernel_version if (!defined($kernel_version));
return $abuild_number if (!defined($abuild_number));
# vermagic=2.6.18-8.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
@array = split(/ /, $kernel_version);
$kernel_version = $array[0];
$kernel_version =~ s/vermagic=//;
# We don't want to export to the user the label info so we strip
# that from the driver_version, leaving only the date.
# so, USM_MAIN_LINUX_090112 becomes 090112.
@array = split (/_/, $driver_version);
$driver_version = $array[3];
# Returning release version
$release_version = $array[1];
# Check if the label is patched
if ($release_version =~ /^((\d+\.){3}\d+)(\.\d*(.*))$/) {
# It is, strip the patch number
# 11.2.0.4.0ACFSPSU becomes 11.2.0.4 (ACFSPSU)
# untouched otherwise
$release_version = "$1 ($4).";
}
# USM_MAIN_LINUX_090112 becomes 090112.
@array = split (/_/, $abuild_number);
$abuild_number = $array[3];
# Get release version from label name MAIN
$abuild_version = $array[1];
# Check if the label is patched
if ($abuild_version =~ /^((\d+\.){3}\d+)(\.\d*(.*))$/) {
# It is, strip the patch number
# 11.2.0.4.0ACFSPSU becomes 11.2.0.4 (ACFSPSU)
# untouched otherwise
$abuild_version = "$1 ($4).";
}
return ($kernel_version, $driver_version, $release_version,
$abuild_number, $abuild_version);
} # end lib_osds_get_current_installed_version
# lib_osds_validate_asmadmin_group
#
# Make sure that the $asmadmin group name actually exists.
#
sub lib_osds_validate_asmadmin_group
{
my ($asmadmin) = @_;
my ($retcode) = osds_unix_linux_acfslib::USM_SUCCESS;
my ($cmd) = "/usr/bin/getent group $asmadmin";
my ($val);
acfslib::lib_trace(9176, "Entering '%s'", "va admin group");
$val = system("$cmd > /dev/null");
if ($val)
{
# Despite the minimal Linux getent(1) man page, the exit codes are
# identical to Solaris.
acfslib::lib_trace(9179, "Command executed: '%s', output = '%s'",
$cmd, (($val & 0xff00) >> 8));
$retcode = osds_unix_linux_acfslib::USM_FAIL;
}
acfslib::lib_trace(9178, "Return code = %s", $retcode);
acfslib::lib_trace(9177, "Return from '%s'", "va admin group");
return $retcode;
} #end lib_osds_validate_asmadmin_group
####### internal only functions #########
# get_udev_common
#
# common code for get_usm_RH5_udev_rules_file() and
# get_usm_RH5_udev_permissions_file()
sub get_udev_common
{
my ($default_dir, $config_param, $file_name) = @_;
my ($line); # line from the udev.conf file
# We get the rules directory from the udev.conf file
# and then append the file name.
my ($udev_perm_dir) = $default_dir; # default directory name
# open file for read
open (CONF, "</etc/udev/udev.conf");
while ($line = <CONF>)
{
my ($line_org) = $line;
# strip off the parameter name, if it exists, leaving only the set value
$line =~ s/^$config_param=//;
# did we find the right line in the file?
# we know it's the right line if the substitution worked.
if ($line ne $line_org)
{
# remove the double quotes
$line =~ s/"//g;
# remove the carriage return
chomp($line);
$udev_perm_dir = $line;
last;
}
}
close CONF;
# avoid "//" - just to make it pretty as it works fine as is
$udev_perm_dir =~ s/\/$//;
return ($udev_perm_dir . "/" . $file_name);
} # end get_udev_common
# lib_osds_is_local_container
# LXC: Linux Container
# Check if this is a LXC environment
# i.e. /proc/1/cgroup
# <num>:<text>://<lxc>/<name>
# Return 1 if it is a local container 0 any other case
#
sub lib_osds_is_local_container
{
# Assume is not a LXC environment
my $lxccontainerflag = 0;
if (defined($ENV{'LXC_FRM_TST'}))
{
# Simulating a LXC environment, where ACFS/ADVM is not supported
$lxccontainerflag = 1;
}
else
{
if (-e "$CGROUP")
{
chomp(my @container = `cat $CGROUP`); # Control group info
foreach my $cgroupvector (@container)
{
if ($cgroupvector =~ /lxc/)
{
# Inside a LXC environment, where ACFS/ADVM is not supported
$lxccontainerflag = 1;
last;
}
}
}
}
if ($lxccontainerflag)
{
acfslib::lib_error_print(9430,
"ADVM/ACFS is not supported on this OS configuration: '%s'",
"Linux Container");
}
return $lxccontainerflag;
}# end lib_osds_is_local_container
=cut
Sets the AcfsRemoteStorageMode tunable depending on the ASM_CONFIG
parameter retrieved from crsconfig_params.
Member Cluster Mode
Edits the iscisd.conf file for the parameters we need.
Starts the iscsid service if we detect an ACFS Remote
installation in Member Cluster Mode.
Creates:
/etc/udev/rules.d/65-usm-acfsr-member.rules
/etc/udev/acfsr_member
These new files will contain the udev rules and script for acfs remote.
Domain Services Mode
Starts target.service if we are in Domain Services Mode, are on el7uek
3.8 kernel or are in test mode.
=cut
sub lib_osds_acfsr_configure
{
acfslib::lib_trace( 9860, "Configuring ACFS Remote");
my $result = 0;
my $return_code = 0;
my ($ORACLE_HOME) = $ENV{ORACLE_HOME};
$asm_storage_mode = acfslib::getParam("ASM_CONFIG");
if ($asm_storage_mode ne '')
{
if ($asm_storage_mode eq 'near')
{
$asm_storage_mode = 0;
}
else
{
$asm_storage_mode = 1;
}
# Set the ACFS Remote storage mode tunable (AcfsRemoteStorageMode).
$result = system("$acfslib::ACFSUTIL tune " .
" AcfsRemoteStorageMode=$asm_storage_mode" .
"2>1 1>/dev/null");
if($result != 0)
{
lib_error_print(3099, "error updating driver tunables");
$return_code = osds_unix_linux_acfslib::USM_FAIL;
}
}
my $kernel = $UNAME_R;
my $cluster_class = acfslib::getParam("CLUSTER_CLASS");;
if ( $cluster_class ne '')
{
acfslib::lib_trace( 9999, "Cluster class is $cluster_class");
$cluster_class = uc($cluster_class);
if ($cluster_class eq 'DOMAINSERVICES' ||
(defined ($ENV{'ADE_VIEW_ROOT'}) && $cluster_class eq 'SHMI'))
{
# TODO create a get_dc_supported_transport function for
# when we support more variations.
if ($cluster_class eq 'SHMI' ||
(($kernel =~ /3.8/) && ($kernel =~ /el7uek/)))
{
acfslib::lib_trace( 9999,
"ACFS Remote is supported in this kernel." .
" Setting up target.service.");
`/bin/systemctl enable target.service`;
`/bin/systemctl start target.service`;
}
else
{
acfslib::lib_trace( 9999, "ACFS Remote is not supported in this "
. "kernel. Skipping target.service enable.");
}
}
else
{
acfslib::lib_trace( 9999, "Skipping target.service setup.");
}
acfslib::lib_trace( 9999, "Class = $cluster_class");
if ($cluster_class eq 'MEMBER' ||
(defined ($ENV{'ADE_VIEW_ROOT'}) && $cluster_class eq 'SHMI'))
{
# Start iscsid setup
my %iscsi_settings =
('node.session.queue_depth' => '1024',
'node.session.timeo.replacement_timeout' => '15',
'node.session.cmds_max' => '1024');
acfslib::lib_trace( 9999, "Reading iscsid configuration");
open (IN_FILE, "<$iscsi_conf_location") ||
return osds_unix_linux_acfslib::USM_FAIL;
local $/ = undef;
my $iscsi_conf = <IN_FILE>;
close (IN_FILE);
acfslib::lib_trace( 9999, "Read iscsid configuration");
acfslib::lib_trace( 9999, "Tuning iscsid configuration");
while (my ($key, $value) = each %iscsi_settings )
{
acfslib::lib_trace( 9999, "Setting $key to $value ");
$iscsi_conf =~ s/$key = .*/$key = $value/g;
}
acfslib::lib_trace( 9999, "Finished tuning iscsid configuration");
acfslib::lib_trace( 9999, "Writing to iscsid configuration file");
open (OUT_FILE, ">$iscsi_conf_location") ||
return osds_unix_linux_acfslib::USM_FAIL;
print OUT_FILE $iscsi_conf;
close (OUT_FILE);
acfslib::lib_trace( 9999, "Wrote to iscsid configuration file");
acfslib::lib_trace( 9999, "Restart iscsid service");
`/sbin/service iscsid restart`;
acfslib::lib_trace( 9999, "Verify iscsid status");
`/sbin/service iscsid status`;
# End iscsid setup
# Copy udev rules
copy("$ORACLE_HOME/lib/65-usm-acfsr-member.rules",
$udev_rules_location);
# Copy udev script
copy("$ORACLE_HOME/lib/acfsr_member",
$udev_script_location);
chmod 0755, $udev_script_location;
}
}
else
{
acfslib::lib_trace( 9999,
"CLUSTER_CLASS is NULL.");
$return_code = osds_unix_linux_acfslib::USM_FAIL;
}
}
# This function will modify the values of the acfslib::acfsr hash.
# The first value is 'True' when ACFS Remote is supported, 'False' otherwise.
# In order to determine if it is supported we
# - Retrieve the passed argument. It will either be "DOMAINSERVICES"
# or "MEMBER".
# - Depending on cluster class, determine if the current OS is supported.
# If it is supported, other values will be pushed into the array
# Is ISCSI supported? 'True' or 'False'.
sub lib_osds_acfs_remote_supported
{
my $cluster_class = uc(shift);
if($cluster_class eq 'MEMBER')
{
$acfslib::acfsr{'ACFS Remote'} = 'True';
}
elsif($cluster_class eq 'DOMAINSERVICES')
{
my $kernel_name = `uname -s`;
my $kernel_release = $UNAME_R;
chomp($kernel_name);
if($kernel_name eq 'Linux' && $kernel_release =~ /^3\.8.*el7uek.*/)
{
$acfslib::acfsr{'ACFS Remote'} = 'True';
}
}
# Check ISCSI support
# Allan said this is always supported.
$acfslib::acfsr{'iSCSI'} = 'True';
=head2 For now, don't check this
# Check if this is an ODA
if(acfslib::isODA())
{
# Xen Blkfrnt/blkback support
$acfslib::acfsr{'xen blkfrnt/blkback'} = 'True';
}
=cut
}
# This function will modify the values of the acfslib::acfsr hash.
# The first value is 'True' when ACFS Remote is installed, 'False' otherwise.
# In order to determine if it is installed we need to look for
# /etc/modprobe.d/oracleadvm.conf (Linux location, this may vary in other OS)
# If found, read it and look for asm_acfsr_mode option
# As of 2/3/16 modes are:
# DOMAINSERVICES = 1
# MEMBER = 2
# SHMI = 3 (ADE-only)
# The list can be found in acfsroot.pl.
# Perhaps I should move that list somewhere else?
# Any of those modes mean 'installed'. Any other value (or a lack of one)
# means not installed.
# If it is supported, other values will be pushed into the array
# Is ISCSI setup? 'True' or 'False'.
sub lib_osds_acfs_remote_installed
{
my $cluster_class = shift;
my $mode = '0';
my $conf_location = "/etc/modprobe.d/oracleadvm.conf";
my $fh;
my $line;
if(-f $conf_location)
{
open ($fh,"<$conf_location") or die "$!";
while($line = <$fh>)
{
if($line =~ /asm_acfsr_mode=(\d)/)
{
$mode = $1;
}
}
close $fh;
}
if($cluster_class eq 'MEMBER' && $mode eq '2')
{
$acfslib::acfsr{'ACFS Remote'} = 'True';
}
elsif($cluster_class eq 'DOMAINSERVICES' && $mode eq '1')
{
$acfslib::acfsr{'ACFS Remote'} = 'True';
}
# Determine is iscsi is installed.
my $iscsi_inst = `/sbin/service iscsid status`;
# Could be running or stopped, so check if it's not there.
# This check might break if we run in a shell in another language
if($iscsi_inst =~ /unrecognized service/)
{
$acfslib::acfsr{'iSCSI'} = 'False';
}
else
{
$acfslib::acfsr{'iSCSI'} = 'True';
}
=head2
# We would check for xen blkfrnt/blkback support via isODA.
# For now, we aren't going to check/show that.
if(acfslib::isODA())
{
# Xen Blkfrnt/blkback support
$acfslib::acfsr{''} = 'True';
}
else
{
$acfslib::acfsr{''} = 'True';
}
=cut
}
# This function will modify the values of the acfslib::acfsr hash.
# The first value is 'True' when ACFS Remote is loaded, 'False' otherwise.
# Is ISCSI setup and running? 'True' or 'False'.
sub lib_osds_acfs_remote_loaded
{
my $cluster_class = shift;
my $mode = 0;
my $conf_location = "/etc/modprobe.d/oracleadvm.conf";
my $fh;
my $line;
if(-e $conf_location)
{
open ($fh,"<$conf_location") or die "$!";
while($line = <$fh>)
{
if($line =~ /asm_acfsr_mode=(\d)/)
{
$mode = $1;
}
}
close $fh;
}
if($cluster_class eq 'MEMBER' && $mode eq 2)
{
$acfslib::acfsr{'ACFS Remote'} = 'True';
}
elsif($cluster_class eq 'DOMAINSERVICES' && $mode eq 1)
{
$acfslib::acfsr{'ACFS Remote'} = 'True';
}
else
{
$acfslib::acfsr{'ACFS Remote'} = 'False';
}
# Determine is iscsi is installed.
my $iscsi_inst = `/sbin/service iscsid status`;
# This check might break if we run in a shell in another language
if($iscsi_inst =~ /running/)
{
$acfslib::acfsr{'iSCSI'} = 'True';
}
else
{
$acfslib::acfsr{'iSCSI'} = 'False';
}
=head For now, don't check this.
if(acfslib::isODA())
{
# Xen Blkfrnt/blkback support
$acfslib::acfsr{''} = 'True';
}
else
{
$acfslib::acfsr{''} = 'True';
}
=cut
}
# Get the ORACLE_HOME driver install path
# base = $ENV{ORACLE_HOME}/usm/install
# type = lib_osds_get_os_type
# ARCH = uname -i
# KVER = uname -r (different for test env)
# $test_mode = an array provided by acfsroot for test environments
sub lib_osds_get_home_driver_path
{
my ($base, $type, $ARCH, $KVER, $test_mode) = @_;
my ($subdir);
my ($lastdir) = "0";
my (@var);
my ($variation);
my ($minor);
my (@kver_bydash) = split(/\-/, $KVER);
my (@kver_bydot) = split(/\./, $KVER);
my @subdir_bydash;
my @subdir_bydot;
my @lastdir_bydash;
my @subkver_bydash;
my $subdirstr;
my $major;
my $midver;
my $valid_variation;
my $kverstr = $KVER;
my $machine_type;
my @test_args;
return 1 if (!defined $base);
chomp ($KVER);
chomp ($type);
chomp ($ARCH);
if (defined($test_mode))
{
if ($test_mode == 1)
{ # Will probably send uname -r instead of kernel version
@test_args = @_[4..8];
# We can't use KVER for 2.6.18, we look for el5 at the end.
@kver_bydash = split(/\-/, $test_args[2]);
@kver_bydot = split(/\./, $test_args[2]);
#$test_args[2] = $KVER;
}
}
$machine_type = lib_osds_get_os_type(@test_args);
if ($machine_type =~ /EL5/ ||
$machine_type =~ /EL6/ ||
$machine_type =~ /EL7/)
{
$base .= "/Oracle";
#We check if this is a uek kernel
if ($KVER =~ /uek/) {
$type .= "UEK";
}
if (-d "$base/$type/$ARCH")
{
open (LS, "ls -v $base/$type/$ARCH |");
while ($subdir = <LS>)
{
chomp($subdir);
@subdir_bydot = split(/\./, $subdir);
$subdirstr = $subdir;
if ($subdirstr eq $kverstr)
{
$lastdir = $subdir;
last;
}
@subdir_bydash = split(/\-/, $subdir);
#Compare dir names, which are kernel versions, and kver numerically
if ((osds_unix_linux_acfslib::lib_osds_krncmp($subdirstr, $kverstr) <= 0) &&
(osds_unix_linux_acfslib::lib_osds_krncmp($subdir, $lastdir) >=0))
{
$lastdir = $subdir;
}
}
close(LS);
}
if ($lastdir eq "0")
{
# no error because the user may have supplied -l (location)
# which over-rides.
return;
}
# Set the global kernel version
($variation) = $kver_bydot[$#kver_bydot]; # el5 or el5PAE, etc.
chomp($variation);
#Sometimes you got the arch instead the type in the latest position.
#Sample: 2.6.32-71.el6.x86_64
if ($variation eq $ARCH) {
($variation) = $kver_bydot[$#kver_bydot - 1]; # el5 or el5PAE, etc.
chomp($variation);
}
#Try to find variation by matching any of el,uek,xmp,xen
#If we have 2.6.32-71.el6.x86_64, we pop x86_64 and then match el6.
#TODO[AG] - Consider replacing the above gymnastics with this simple
#piece of code to get the variation
my @kcp = @kver_bydot;
while($kcp[$#kcp] !~ /el/ &&
$kcp[$#kcp] !~ /uek/ &&
$kcp[$#kcp] !~ /smp/ &&
$kcp[$#kcp] !~ /xen/ &&
$#kcp > 3) {
pop @kcp;
}
if($#kcp > 3){
#We don't want to take major, minor, mid versions [3]
$variation = $kcp[$#kcp];
}
($major) = $kver_bydot[0];
($midver) = $kver_bydot[1];
($minor) = $kver_bydot[2];
# We currently build kernels for variations ending in "el5", "el5PAE",
# "el5xen", and "el6". We also build 2.6.32-100.
# If the variation/minor here is none of the above, we need to
# either build additional drivers or massage the variation here. In either
# case, it's an internal error that should have been caught before we got
# here and so we just bail. We don't want to fail the entire oracle install
# and so return USM_NOT_SUPPORTED so that OUI can complete sans USM.
$valid_variation = 0;
if($major eq "2")
{
if($midver eq "6")
{
if(($minor eq "32-100") || ($minor eq "32-71") ||
($variation eq 'el5') || ($variation eq 'el5PAE') ||
($variation eq 'el5xen') || ($variation eq 'el6') ||
($minor eq "32-200") || ($minor eq "32-300") ||
($minor eq "32-400") ||
($minor eq "39-100") || ($minor eq "39-200") ||
($minor eq "39-300") || ($minor eq "39-400")
)
{
$valid_variation = 1;
}
}
}
elsif ($major eq "3")
{
if($midver eq "8")
{
#We have support for 3.8.13 for el6uek and el7uek
if(($minor =~ /^13/) ||
($variation eq "el6uek") ||
($variation eq "el7uek"))
{
$valid_variation = 1;
}
}
elsif ($midver eq "10")
{
#We have support for 3.10 for el7
if($variation eq "el7")
{
$valid_variation = 1;
}
}
}
elsif ($major eq "4")
{
if($midver eq "1")
{
#We have support for 4.1.12 for el6uek and el7uek
if(($minor =~ /^12/) ||
($variation eq "el6uek") ||
($variation eq "el7uek"))
{
$valid_variation = 1;
}
}
}
# Now create a base directory to look for the adequate modules
if($major eq "4")
{
if($midver eq "1")
{
# If we are here, we have a 4.1 kernel as supported.
# We don't need to check for minor version
# osds_is_kabi_compatible function will check for
# any different minor version
$base .= "/$type/$ARCH/$lastdir/$lastdir";
}
} #end if($major eq "4")
elsif($major eq "3")
{
if($midver eq "8" ||
$midver eq "10")
{
# If we are here, we have a 3.8 or 3.10 kernel as supported.
# We don't need to check for minor version
# osds_is_kabi_compatible function will check for
# any different minor version
$base .= "/$type/$ARCH/$lastdir/$lastdir";
}
} #end if($major eq "3")
elsif($major eq "2")
{
if($midver eq "6")
{
if (
($minor eq "32-100") || ($minor eq "32-200") ||
($minor eq "32-300") || ($minor eq "32-400") ||
($minor eq "39-100") || ($minor eq "39-200") ||
($minor eq "39-300") || ($minor eq "39-400")
)
{
# "32-100" has no variation (el5PAE, for example).
$base .= "/$type/$ARCH/$lastdir/$lastdir";
if (!($variation =~ /uek/)) # Unless it's RedHat
{
$base .= ".$variation";
}
}
else
{
$base .= "/$type/$ARCH/$lastdir/$lastdir.$variation";
}
} #if($midver eq "6")
} #end elsif($major eq "2")
if ($ARCH eq "x86_64")
{
$base .= "-x86_64/bin";
}
else
{
$base .= "-i686/bin";
}
}# end if (RHEL)
elsif ( $machine_type =~ /SLES/ )
{
my ($line);
my ($SPnumber) = 0;
$base .= "/Novell";
#We add the PATCH LEVEL
if ($test_mode)
{
$SPnumber = $test_args[3];
}
else
{
if (-e "/etc/SuSE-release")
{
open (RELEASE, "/etc/SuSE-release");
while ($line = <RELEASE>)
{
if ($line =~ /PATCHLEVEL/)
{
# format: "PATCHLEVEL = 3"
my ($patchlevel, $equals, $number) = split(/ /, $line);
chomp ($number);
$SPnumber = $number;
last;
}
}
close (RELEASE);
}
elsif (-e "/etc/os-release")
{
open (RELEASE, "/etc/os-release");
while ($line = <RELEASE>)
{
if ($line =~ /VERSION_ID/)
{
# format: VERSION_ID="12"
my ($version_id, $number) = split(/=/, $line);
chomp ($number);
$number =~ s/\"//g;
my ($nversion, $patchnumber) = split(/\./, $number);
if (defined($patchnumber))
{
$SPnumber = $number;
}
last;
}
}
close (RELEASE);
}
}
open (LS, "ls $base/$type/$ARCH/SP$SPnumber |");
while ($subdir = <LS>)
{
@subdir_bydash = split(/\-/, $subdir);
chomp($subdir);
@subdir_bydot = split(/\./, $subdir);
$subdirstr = "$subdir_bydot[0]".".".
"$subdir_bydot[1]".".".
"$subdir_bydot[2]";
#Compare dir names, which are kernel versions, and kver numerically
if ((osds_unix_linux_acfslib::lib_osds_krncmp($subdirstr, $kverstr) <= 0) &&
(osds_unix_linux_acfslib::lib_osds_krncmp($subdir, $lastdir) >=0))
{
$lastdir = $subdir;
}
}
close(LS);
if ($lastdir eq "0")
{
# no error because the user may have supplied '-l' (location)
# which over-rides.
return;
}
($variation) = $kver_bydash[$#kver_bydash];
# smp, xen, or default
if ($variation =~ /smp/)
{
$base .= "/$type/$ARCH/SP$SPnumber/$lastdir/smp/bin";
}
elsif ($variation =~ /xen/)
{
$base .= "/$type/$ARCH/SP$SPnumber/$lastdir/xen/bin";
}
else
{
$base .= "/$type/$ARCH/SP$SPnumber/$lastdir/default/bin";
}
} #end if (SLES)
elsif (defined($test_mode))
{
# Make sure base is illegal since we measure success just by checking
# if the install directory exists.
undef $base;
}
return $base;
}
# See acfslib.pm lib_get_drivers_version
sub lib_osds_get_drivers_version
{
}
# Check if configuration machine is ready to install and load ACFS/ADVM drivers
# return true or false
sub lib_osds_check_config()
{
if( !osds_acfsroot::osds_symvers_exists() )
{
return 0;
}
return 1;
}
# Check if machine supports ACFS/ADVM drivers
# return true or false
sub lib_osds_check_kernel()
{
return 1;
}
# Check if we are running in a SIHA installation.
# Per Rajesh Dasari, the only way to know for now is via an EMPTY CLUSTER_NAME
# attribute in the crsconfig_params file. This may change in the future.
sub lib_osds_is_siha()
{
if(acfslib::getParam("CLUSTER_NAME") eq "")
{
return 1;
}
else
{
return 0;
}
}
#Uncompress driver files in Linux
sub lib_osds_uncompress_driver_files
{
my ($path) = @_;
my ($cwd) = Cwd::cwd();
my ($unzip) = "/usr/bin/unzip";
my @all_files;
if (!chdir($path))
{
acfslib::lib_error_print_noalert(9999, "Cannot change to $path: $! \n");
}
(@all_files) = glob("*.zip");
if (!chdir($cwd))
{
acfslib::lib_error_print_noalert(9999, "Cannot change to $cwd: $! \n");
}
#Check the unzip command
if (!-e $unzip) {
# If the absolute path doesn't exist, try with the command
if (system("unzip >/dev/null") == 0)
{
# If we are able to execute unzip tool
$unzip = "unzip";
}
else
{
#Return the user has to unzip the file manually.
acfslib::lib_inform_print (9999, "Tool for uncompress files ('unzip') " .
"doesn't exist.");
acfslib::lib_inform_print (9999, "Trying to uncompress manually.");
return;
}
}
#Uncompress Driver files
foreach my $compress (@all_files)
{
if (-e "$path/$compress")
{
`$unzip -ojq $path/$compress -d $path`;
}
}
}
OHA YOOOO