# # osds_afdlib.pm # # Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. # # # NAME # osds_afdlib.pm - Linux OSD library components for AFD. # # 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 afdlib; use osds_unix_linux_afdlib; package osds_afdlib; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw( lib_osds_afd_verify_devices lib_osds_afd_load_driver lib_osds_afd_unload_driver lib_osds_afd_create_udev lib_osds_get_afd_udev_rules_file lib_osds_afd_copy_library lib_osds_afd_post_load_setup lib_osds_afd_delete_oracleafd_disks @AFD_DRIVER_COMPONENTS ); our (@AFD_DRIVER_COMPONENTS) = ( "oracleafd.ko" ); my ($CACHED_INSTALLED_DRIVERS); # saved find /lib/modules output my ($UNAME_R) = `uname -r`; chomp ($UNAME_R); my ($ARCH) = `uname -i`; chomp ($ARCH); # e.g., "x86-64" my $ORACLE_HOME = $ENV{ORACLE_HOME}; use constant UID => 4; use constant GID => 5; # /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"; # AFD Library name my ($LIBAFD) = "libafd12.so"; # lib_osds_get_afd_udev_rules_file # # get AFD udev rules directory and file used by both install/uninstall # AFD Udev rules file. sub lib_osds_get_afd_udev_rules_file { return get_udev_common("/etc/udev/rules.d", "udev_rules", "53-afd.rules"); } # lib_osds_afd_create_udev # # Create a AFD udev file # sub lib_osds_afd_create_udev { my ($asmadmin) = @_; my ($udev_perm_file); my ($user) = acfslib::getParam("ORACLE_OWNER"); $udev_perm_file = lib_osds_get_afd_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 "# AFD devices\n"; print PERM "KERNEL==\"oracleafd/.*\", OWNER=\"$user\", GROUP=\"$asmadmin\", MODE=\"0775\"\n"; print PERM "KERNEL==\"oracleafd/*\", OWNER=\"$user\", GROUP=\"$asmadmin\", MODE=\"0775\"\n"; print PERM "KERNEL==\"oracleafd/disks/*\", OWNER=\"$user\", GROUP=\"$asmadmin\", MODE=\"0664\"\n"; close PERM; } # end lib_osds_afd_create_udev # lib_osds_afd_verify_devices # # Verify that the AFD drivers are loaded and running by checking the # existence of the device control files for the drivers. # sub lib_osds_afd_verify_devices { my $ret; $ret = osds_unix_linux_afdlib::lib_osds_verify_afd_devices(); return $ret; } sub lib_osds_afd_load_driver { my($driver, $COMMAND) = @_; my $result; $result = osds_acfslib::lib_osds_load_driver($driver, $COMMAND); return $result; } sub lib_osds_afd_unload_driver { my($driver) = @_; my $result; $result = osds_acfslib::lib_osds_unload_driver($driver); return $result; } # get_udev_common # # get afd 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, ") { 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 sub lib_osds_afd_copy_library { my ($source); my ($ret); my ($return_code) = osds_unix_linux_acfslib::USM_SUCCESS; my ($whatbit) = `grep flags /proc/cpuinfo`; my ($target) = $ENV{_vendor_lib_loc}; my ($asmadmin) = acfslib::lib_get_asm_admin_name(); my ($user) = acfslib::getParam("ORACLE_OWNER"); my ($uid); my ($gid); my ($libpath); if(!defined($target)) { # Target should be of the type # /opt/oracle/extapi/[32,64]/{API}/{VENDOR}/{VERSION}/lib. # if($whatbit =~ /lm/) { $target = "/opt/oracle/extapi/64/asm/orcl/1/"; } elsif($whatbit =~ /tm/) { $target = "/opt/oracle/extapi/32/asm/orcl/1/"; } } # libafd12.so goes to /opt/oracle/extapi/64/asm $source = "$ORACLE_HOME/lib/$LIBAFD"; $libpath = $target.$LIBAFD; # Get Owner and group of source # get the owner/group of the original file ($uid, $gid) = (stat($source))[UID,GID]; if($user) { $uid = getpwnam($user); } $gid = getgrnam($asmadmin); if(!(-e $target)) { `mkdir -m 755 -p $target`; if ($?) { acfslib::lib_error_print(9345, "Unable to create directory: '%s'.", $target); return osds_unix_linux_acfslib::USM_FAIL; } } # Give 755 to /opt/oracle/extapi/* system("chmod 755 /opt/oracle"); system("chmod -R 755 /opt/oracle/extapi"); acfslib::lib_verbose_print (9504, "Copying file '%s' to the path '%s'", $source, $target); $ret = system ("cp -f $source $target"); $return_code = osds_unix_linux_acfslib::USM_FAIL if $ret; if($return_code == osds_unix_linux_acfslib::USM_SUCCESS) { system("chmod 755 $libpath"); $ret = chown $uid, $gid, $libpath; if($ret != 1) { acfslib::lib_error_print(9426, "unable to set the file attributes for file '%s'", $libpath); return osds_unix_linux_acfslib::USM_FAIL; } } return $return_code; } sub lib_osds_afd_post_load_setup { my ($disks_dir) = osds_unix_linux_afdlib::lib_osds_fetch_afd_disks_dir(); my ($return_val) = osds_unix_linux_acfslib::USM_SUCCESS; my ($asmuser) = acfslib::getParam("ORACLE_OWNER"); # Get the name of the ASM adminisrator my ($asmadmin) = acfslib::lib_get_asm_admin_name(); # Make sure that the proper /dev files get created by udevd acfslib::lib_inform_print(649, "Verifying AFD devices."); $return_val = lib_osds_afd_verify_devices(); if ($return_val != osds_unix_linux_acfslib::USM_SUCCESS) { # osds_verify_afd_devices() will print the specific error(s), if any; return $return_val; } # Give read permissions for 'others' to access AFD devices `mkdir -m 775 -p $disks_dir`; if ($?) { acfslib::lib_error_print(9345, "Unable to create directory: '%s'.", $disks_dir); return osds_unix_linux_acfslib::USM_FAIL; } if($asmuser) { system("chown $asmuser $disks_dir"); } system("chgrp $asmadmin $disks_dir"); # Enable logging `$ORACLE_HOME/bin/afdtool -log -d`; if ($?) { acfslib::lib_inform_print(9225, "Failed to start AFD logging."); # Though failed, continue with rest of the flow } # Scan devices and send other persistent states to AFD Driver `$ORACLE_HOME/bin/afdboot -scandisk`; return $return_val; } sub lib_osds_afd_delete_oracleafd_disks { my ($disksdir) = osds_unix_linux_afdlib::lib_osds_fetch_afd_disks_dir(); if(opendir (DIR, $disksdir)) { while (my $file = readdir(DIR)) { if($file ne "." && $file ne "..") { my $filepath = $disksdir."/".$file; if(-e $filepath) { unlink("$filepath"); } } } closedir(DIR); } } ####### internal only functions #########