#
# $Header: usm/src/cmds/acfsroot/aix/osds_acfsroot.pm /st_usm_11.2/4 2011/07/20 18:54:10 certan Exp $
#
# osds_acfsroot.pm
# 
# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 
#
#
#    NAME
#      osds_acfsroot.pm - AIX OSD component of acfsroot.
#
#    DESCRIPTION
#      Purpose
#          Install/uninstall USM components.
#
#    NOTES
#      All user visible output should be done in the common code.
#      this will ensure a consistent look and feel across all platforms.
#
#    MODIFIED   (MM/DD/YY)
#    certan      07/20/11 - Backport certan_acfsroot_odmdir_check from main
#    averhuls    06/22/11 - For easily fixable errors, return
#                           USM_TRANSIENT_FAIL.
#    rwerme      05/02/11 - Install all AIX 7.x releases from dir
#                           AIX/V7x/powerpc.
#    averhuls    03/15/11 - Backport averhuls_bug-11849923 from main.
#    certan      09/29/10 - Fix paths displayed when failing to unlink
#                           $USER_COMMAND_COMPONENTS, $DRIVER_COMPONENTS
#                           and $DRIVER_UTIL_COMPONENTS during uninstall
#    averhuls    09/02/10 - Add the "preserve" argument to uninstall to
#                           allow the preservation of the tunable parameters.
#    certan      06/24/10 - Run aixsetup/rmaixsetup from distribution files
#                           instead of installing to $ORACLE_HOME/bin
#                         - During install, use cfgdata in distribution files
#                           instead of installing to $ORACLE_HOME/usm/cfgdata
#                         - Do not remove ODM entries when in development
#                           environment
#                         - Do not remove /etc/oradevgrp when in development
#                           environment
#                         - Set permissions of cfgadvmvol/ucfgadvmvol to
#                           4755 when in development environment
#                         - Fix osds_search_for_distribution_files to search
#                           for aixsetup/rmaixsetup and cfgdata
#                         - General cleanup to comments
#    jinjche     05/25/10 - Undo Aix setup as part of uninstall
#    certan      05/06/10 - Install acfsutil/advmutil binaries into /usr/sbin,
#                           create symlinks to binaries in /sbin
#    certan      04/30/10 - Create symlink to acfsutil.bin in /sbin
#    certan      04/23/10 - Skip aixsetup if running in ADE environment
#                         - Create extra link to acfsutil in /sbin
#                         - Make osds_search_for_distribution_files() search
#                           for startacfsctl/startadvmctl
#                         - Make osds_load_and_verify_usm_state() check for
#                           driver util binaries, not just shell scripts
#                         - Fix message 9325, 9326, 9356, 9358, 9359, 9362
#    jinjche     03/25/10 - Remove advmvol as well during uninstall
#    averhuls    03/15/10 - Fix typo in message 9363-4.
#    averhuls    03/15/10 - Fix typo in message 9363. 9364.
#    abakst      03/15/10 - Allow uninstallation to succeed if ACFS_COMMAND_DIR
#                           can't be removed because it is non-empty.
#    jinjche     02/18/10 - Add code to add ACFS FS-type to /etc/vfs
#    jinjche     02/09/10 - Fix file permission that caused installation to
#                           fail, changing from 500 to 755.
#    jinjche     01/22/10 - Fix a No-File-Found bug in the shiphome
#                           installation
#    abakst      11/06/09 - Fix mkdir permissions error
#    jinjche     11/02/09 - Fix a copy-paste-forgot-to-edit error in one error
#                           message
#    jinjche     10/29/09 - Add code to install/uninstall many things on AIX
#    abakst      09/08/09 - Port acfsroot lib to AIX
#
package osds_acfsroot;

use strict;
use osds_acfslib;
use acfslib;
use File::Copy;
require Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw(
                 osds_fix_wrapper_scripts
                 osds_get_kernel_version
                 osds_initialize
                 osds_install_from_distribution_files
                 osds_search_for_distribution_files
                 osds_load_and_verify_usm_state
                 osds_usm_uninstall
                 $MEDIA_FOUND
                 $ORACLE_HOME
                 $USM_DFLT_MEDIA_LOC
                 );

our ($ORACLE_HOME);                             # set by get_oracle_home()
our ($USM_DFLT_MEDIA_LOC);                      # location of the install media
our ($MEDIA_FOUND);                             # path name to media
                                                #   used for version_check
my ($MEDIA_PATH);

my ($ARCH) = `uname -p`;
chomp($ARCH);
my ($UNAME_R) = `uname -r`;
chomp($UNAME_R);
my ($UNAME_V) = `uname -v`;
chomp($UNAME_V);
my ($OSLEVEL) = `oslevel -s`;
chomp($OSLEVEL);

#
# Components to install
#  Append .bin to the command names 
#  JJ - TODO: When Replication is supported and umount is available,
#  we will need to add umount to this ACFS_COMMANDS list.
#
my (@ACFS_COMMANDS) = ("fsck", "mkfs", "acfsdbg", "mount");
my (@ACFS_COMMAND_COMPONENTS) = (@ACFS_COMMANDS, 
                                 map ($_.".bin", @ACFS_COMMANDS));

my (@USER_COMMANDS) = ("acfsutil", "advmutil");
my (@USER_COMMAND_COMPONENTS) = (@USER_COMMANDS,
                                 map ($_.".bin", @USER_COMMANDS));

my (@DRIVER_UTILS) = ("defadvmctl", "cfgadvmctl", "ucfgadvmctl", "udefadvmctl",
                      "defacfsctl", "cfgacfsctl", "ucfgacfsctl", "udefacfsctl",
                      "cfgadvmvol", "ucfgadvmvol");
my (@DRIVER_UTILS_NO_BIN) = ("startacfsctl", "startadvmctl" );
my (@DRIVER_UTIL_COMPONENTS) = (@DRIVER_UTILS, 
                                map ($_.".bin", @DRIVER_UTILS),
                                @DRIVER_UTILS_NO_BIN);

my (@COMMAND_COMPONENTS) = (@ACFS_COMMAND_COMPONENTS,
                            @USER_COMMAND_COMPONENTS,
                            @DRIVER_UTIL_COMPONENTS);

my (@AIXSETUPCMD) = ("aixsetup", "rmaixsetup");

my (@ODM_ENTRIES) = ("acfsctl", "advmctl", "advmvol");
my (@ODM_ENTRY_DATA) = map ($_.".dat", @ODM_ENTRIES);

#
# Directories for components
#
my ($DRIVER_DIR) = "/usr/lib/drivers";
my ($DRIVER_UTIL_DIR) = "/usr/lib/methods";
my ($ACFS_COMMAND_DIR) = "/sbin/helpers/acfs";
my ($USER_COMMAND_DIR) = "/usr/sbin";
my ($USER_COMMAND_LINK_DIR) = "/sbin";

my ($KVER);                              # kernel version being installed

# osds_initialize
#
# Perform OSD initialization.
#     set USM_DFLT_MEDIA_LOC - the location of the USM installation media.
#
sub osds_initialize
{
  my ($install_kver, $sub_command) = @_;
  my ($type);

  if (!defined($install_kver))
  {
    # use the current kernel version
    $KVER = $OSLEVEL;
  }
  else
  {
    # use the specified kernel version
    # TODO we'll want to do some sanity checking here.
    $KVER = $install_kver;
  }

  # we have already verified that we have a valid type via a call to
  # lib_usm_supported() by top level acfsroot code.
  $type = lib_osds_get_os_type();

  # default media location - over-ride with the -l option
  if (defined($ENV{SRCHOME}))
  {
    # we're in a development environment, we'll use that as the media source.
    
    $USM_DFLT_MEDIA_LOC = "$ENV{ADE_VIEW_ROOT}/usm/install/AIX/$type/$ARCH/bin/";
  }
  else
  {
    # we're in a production environment, use that as the source location.
    if (defined($ORACLE_HOME))
    {
      $USM_DFLT_MEDIA_LOC = "$ENV{ORACLE_HOME}/install/usm/$type/$ARCH/bin/";
    }
    else
    {
      lib_error_print(9318, "ORACLE_HOME is not set.");
      
      return USM_TRANSIENT_FAIL;
    }
  }

  if (($sub_command eq "install") || ($sub_command eq "uninstall"))
  {
    if (!defined($ENV{ODMDIR}))
    {
      lib_error_print(9395, "Environment variable ODMDIR is not set, " .
                            "unable to proceed with system configuration.");
      return USM_FAIL;
    }
    elsif(! -e $ENV{ODMDIR})
    {
      lib_error_print(9396, "Environment variable ODMDIR specifies a " .
                            "nonexistent path, unable to proceed with " .
                            "system configuration.");
      return USM_FAIL;
    }
  }

  return USM_SUCCESS;
}

# osds_fix_wrapper_scripts
#
# We need to resolve %ORA_CRS_HOME% in the command wrapper scripts.
#
sub osds_fix_wrapper_scripts
{
  # Fix all wrappers, append the correct directory to each program
  my (@progs) = ((map {"$USER_COMMAND_DIR/".$_} @USER_COMMANDS),
                 (map {"$ACFS_COMMAND_DIR/".$_} @ACFS_COMMANDS),
                 (map {"$DRIVER_UTIL_DIR/".$_} @DRIVER_UTILS),
                 (map {"$ORACLE_HOME/bin/".$_}
                     ("acfsload", "acfsregistrymount",
                      "acfsdriverstate", "acfssinglefsmount")));
                 
  my ($prog);
  my ($line);
  my (@buffer);
  
  foreach $prog (@progs)
  {
    my ($read_index, $write_index);
    
    $read_index = 0;
    open READ, "<$prog" or next;
    while ($line = <READ>)
    {
      if ($line =~ m/^ORA_CRS_HOME/)
      {
        $line = "ORA_CRS_HOME=$ORACLE_HOME\n";
      }
      $buffer[$read_index++] = $line;
    }
    close (READ);
    
    $write_index = 0;
    open WRITE, ">$prog" or next;
    while($write_index < $read_index)
    {
      print WRITE "$buffer[$write_index++]";
    }
    close (WRITE);
  }
}
# end osds_fix_wrapper_scripts

# osds_get_kernel_version
#
sub osds_get_kernel_version
{
  return $KVER
} # end osds_get_kernel_version


# osds_install_from_distribution_files
#
# Install the USM components from the specified distribution files
# The files have already been validated by the time we get here
# by osds_search_for_distribution_files(). Also, any previous USM installation
# will have been removed.
#
sub osds_install_from_distribution_files
{
  my ($component);                 # curent component being installed
  my ($command);                   # current command being executed by system()
  my ($return_code) = 0;

  if (! -d $DRIVER_DIR)
  {
    # This is really bad
    lib_error_print(9344, "Missing directory: %s.", $DRIVER_DIR);
    return USM_FAIL;
  }

  if (! -d $DRIVER_UTIL_DIR)
  {
    # This is also really bad
    lib_error_print(9344, "Missing directory: %s.", $DRIVER_UTIL_DIR);
    return USM_FAIL;
  }

  if (! -d $ACFS_COMMAND_DIR)
  {
    $return_code = mkdir($ACFS_COMMAND_DIR);
    $return_code = $return_code && chmod(0555, $ACFS_COMMAND_DIR);
    if (!$return_code)
    {
      lib_error_print(9345, "Unable to create directory: %s.", $ACFS_COMMAND_DIR);
      return USM_TRANSIENT_FAIL;
    }
  }

  if (! -d $USER_COMMAND_DIR)
  {
    # This is pretty bad
    lib_error_print(9344, "Missing directory: %s.", $USER_COMMAND_DIR);
    return USM_FAIL;
  }

  # install drivers
  foreach $component (@DRIVER_COMPONENTS)
  {
    my ($source) = "$MEDIA_PATH/$component";
    my ($target) = "$DRIVER_DIR/$component";

    $return_code = copy($source, $target);
    if(!$return_code)
    {
      lib_error_print(9346, "Unable to install file: '%s'.", $target);
      return USM_FAIL;
    }

    $return_code = chmod(oct("0555"), $target);
    if(!$return_code)
    {
      lib_error_print(9347, "Unable to set permission bits (%s) on: '%s'.",
                      "0555", $target);
      return USM_TRANSIENT_FAIL;
    }
  }

  # install driver loader/unloaders and start scripts
  foreach $component (@DRIVER_UTIL_COMPONENTS)
  {
    my ($source) = "$MEDIA_PATH/$component";
    my ($target) = "$DRIVER_UTIL_DIR/$component";

    $return_code = copy($source, $target);
    if(!$return_code)
    {
      lib_error_print(9346, "Unable to install file: '%s'.", $target);
      return USM_FAIL;
    }

    if (defined($ENV{ADE_VIEW_ROOT}) && $component =~ /advmvol\.bin/)
    {
      $return_code = chmod(oct("4755"), $target);
      if(!$return_code)
      {
        lib_error_print(9347, "Unable to set permission bits (%s) on: '%s'.",
                        "4755", $target);
        return USM_TRANSIENT_FAIL;
      }
    }
    else
    {
      $return_code = chmod(oct("0755"), $target);
      if(!$return_code)
      {
        lib_error_print(9347, "Unable to set permission bits (%s) on: '%s'.",
                        "0755", $target);
        return USM_TRANSIENT_FAIL;
      }
    }
  }

  # install commands
  # the commands have been verified to exist so the copy will not fail
  foreach $component (@ACFS_COMMAND_COMPONENTS)
  {
    my ($source) = "$MEDIA_PATH/$component";
    my ($target) = "$ACFS_COMMAND_DIR/$component";

    $return_code = copy($source, $target);
    if(!$return_code)
    {
      lib_error_print(9346, "Unable to install file: '%s'.", $target);
      return USM_FAIL; 
    }
    
    $return_code = chmod(oct("0755"), $target);
    if(!$return_code)
    {
      lib_error_print(9347, "Unable to set permission bits (%s) on: '%s'.",
                      "0755", $target);
      return USM_TRANSIENT_FAIL;
    }
  }
  
  foreach $component (@USER_COMMAND_COMPONENTS)
  {
    my ($source) = "$MEDIA_PATH/$component";
    my ($target) = "$USER_COMMAND_DIR/$component";

    $return_code = copy($source, $target);
    if(!$return_code)
    {
      lib_error_print(9346, "Unable to install file: '%s'.", $target);
      return USM_FAIL;
    }
    
    $return_code = chmod(oct("0755"), $target);
    if(!$return_code)
    {
      lib_error_print(9347, "Unable to set permission bits (%s) on: '%s'.",
                      "0755", $target);
      return USM_TRANSIENT_FAIL;
    }
  }

  # create symlinks to user commands
  foreach $component (@USER_COMMAND_COMPONENTS)
  {
    my ($source) = "$USER_COMMAND_DIR/$component";
    my ($target) = "$USER_COMMAND_LINK_DIR/$component";

    unlink($target);
    symlink($source, $target);
    if((! -l $target) || (readlink($target) ne $source))
    {
      lib_error_print(9350, 
                      "Failed to create a symbolic link from '%s' to '%s'.",
                      $target, $source);
      return USM_TRANSIENT_FAIL;
    }
  }

  # Add ACFS file system type to /etc/vfs. Continue even if error occurs.
  $return_code = addACFSType();

  # Do once-only setup
  # Sets up AIX ODM and RBAC, stores ASMADMIN group in /etc/oradevgrp
  $return_code = osds_doaixsetup();
  if ($return_code != USM_SUCCESS)
  {
    lib_error_print(9355, "Performing AIX setup failed with error code '%s'.", $return_code);
    return $return_code;
  }

  return USM_SUCCESS
} # end osds_install_from_distribution_files

# osds_search_for_distribution_files
#
# Search the location(s) specified by the user for valid media
# If a specific kernel and/or USM version is specified,
# look for that only that version.
#
sub osds_search_for_distribution_files
{
  my ($install_files_loc, $kernel_version, $usm_version) = @_;
  my ($retval) = USM_SUCCESS;
  my ($component);
  
  # test that all of our expected components exist in the distribution
  foreach $component (@DRIVER_COMPONENTS, @COMMAND_COMPONENTS, 
                      @AIXSETUPCMD, @ODM_ENTRY_DATA)
  {
    my ($target) = "$install_files_loc/$component";
    
    if (! -e $target)
    {
      lib_error_print(9320, "Missing file: '%s'.", $target);
      $retval = USM_FAIL;
    }
  }

  if ($retval == USM_SUCCESS)
  {
    $MEDIA_PATH = $MEDIA_FOUND = $install_files_loc;
    $MEDIA_FOUND .= "\n";
  }

  return $retval
} # end osds_search_for_distribution_files

# osds_load_and_verify_usm_state
#
# If the install was for the current kernel version, we load the drivers
# and test to see that the expected /dev entries get created.
#
sub osds_load_and_verify_usm_state
{
  my ($no_load) = @_;

  # Make sure that all components are in place
  my ($fail) = USM_SUCCESS;
  my ($component);
  my ($return_val);

  # Verify that the drivers reside in the target directory
  foreach $component (@DRIVER_COMPONENTS)
  {
    my ($driver_path) = "$DRIVER_DIR/$component";

    if (! -e $driver_path)
    {
      lib_error_print(9320, "Missing file: '%s'.", $component);
      $fail = USM_FAIL;
    }
  }

  foreach $component (@DRIVER_UTIL_COMPONENTS)
  {
    my ($util_path) = "$DRIVER_UTIL_DIR/$component";

    if (! -e $util_path)
    {
      lib_error_print(9320, "Missing file: '%s'.", $component);
      $fail = USM_FAIL;
    }
  }

  foreach $component (@ACFS_COMMAND_COMPONENTS)
  {
    my ($component_path) = "$ACFS_COMMAND_DIR/$component";

    if (! -e $component_path)
    {
      lib_error_print(9320, "Missing file: '%s'.", $component);
      $fail = USM_FAIL;
    }
  }

  foreach $component (@USER_COMMAND_COMPONENTS)
  {
    my ($component_path) = "$USER_COMMAND_DIR/$component";

    if (! -e $component_path)
    {
      lib_error_print(9320, "Missing file: '%s'.", $component);
      $fail = USM_FAIL;
    }
  }

  foreach $component (@USER_COMMAND_COMPONENTS)
  {
    my ($component_path) = "$USER_COMMAND_LINK_DIR/$component";

    if (! -l $component_path)
    {
      lib_error_print(9320, "Missing file: '%s'.", $component_path);
      $fail = USM_FAIL;
    }
  }

  if ($fail != USM_SUCCESS)
  {
    return $fail;
  }

  if ($no_load)
  {
    # We're installing USM for another kernel version - do not attempt to
    # load the drivers. The presumed scenario is that the user wants to
    # install USM for an about to be upgraded kernel. This way, USM can
    # be up and running upon reboot. Dunno if anyone will ever use this.
    lib_inform_print(9324, "Alternate drivers installed.");
    lib_inform_print(9325, "    Driver OS kernel version = %s.", $OSLEVEL);
    lib_inform_print(9326, "    Driver Oracle version = %s.", $KVER);
  }
  else
  {
    # Load the USM drivers
    $return_val = lib_load_usm_drivers();
    if ($return_val != USM_SUCCESS)
    {
      # load_usm_drivers() will print the specific error(s), if any;
      return $return_val;
    }

    # Make sure that the proper /dev files get created 
    lib_inform_print(9327, "Verifying ADVM/ACFS devices.");
    $return_val = lib_verify_usm_devices();
    if ($return_val != USM_SUCCESS)
    {
      # osds_verify_usm_devices() will print the specific error(s), if any;
      return $return_val;
    }

    $return_val = system("/usr/sbin/savebase");
    if ($return_val != 0)
    {
      lib_error_print(9356, "Saving the AIX ODM changes for '%s' failed with error code '%s'.",
          "ACFS drivers", $return_val);
      return $return_val;
    }
  }

  # see comments at the head of the routine
  osds_fix_wrapper_scripts();

  # should we unload the drivers at this point?

  return USM_SUCCESS;    
} # end osds_load_and_verify_usm_state

# osds_usm_uninstall
#
# remove the USM components and the udev file.
#
sub osds_usm_uninstall
{
  my ($install_files_loc, $preserve) = @_;
  my ($return_code) = 1; #Dealing with system commands where 1 is 'true'.
  my ($component);
  my ($dir_handle);
  my (@entries);

  if (!defined($ENV{ADE_VIEW_ROOT}))
  {
    #
    # Search for distribution files as we will run rmaixsetup from the
    # distribution files
    #
    $return_code = osds_search_for_distribution_files($install_files_loc);
    if ($return_code != USM_SUCCESS)
    {
      lib_error_print(9383, "ADVM/ACFS uninstall can not proceed");
      lib_error_print(9317, 
                      "No ADVM/ACFS distribution media detected at " .
                      "location: '%s'", $install_files_loc); 
      return $return_code;
    }

    # 
    # Run rmaixsetup, which removes RBAC setup
    #
    my ($paramfile) = $ORACLE_HOME . "/crs/install/crsconfig_params";
    my $UNAME1 = qx { /usr/bin/grep "^ORACLE_OWNER" $paramfile | /usr/bin/cut -d '=' -f 2 };
    chomp $UNAME1;
    system("/bin/sh $MEDIA_PATH/rmaixsetup $UNAME1");
  }

  # remove devices
  $return_code = system("/usr/lib/methods/udefacfsctl -l ofsctl");
  if ($return_code != 0)
  {
    lib_error_print(9361, "Removing device '%s' failed with error code '%s'.",
        "acfsctl", $return_code);
    return $return_code;
  }

  $return_code = system("/usr/lib/methods/udefadvmctl -l advmctl");
  if ($return_code != 0)
  {
    lib_error_print(9361, "Removing device '%s' failed with error code '%s'.",
        "advmctl", $return_code);
    return $return_code;
  }

  # remove symlinks to user commands
  foreach $component (@USER_COMMAND_COMPONENTS)
  {
    $return_code = unlink("$USER_COMMAND_LINK_DIR/$component");
    if(!$return_code && -e "$USER_COMMAND_LINK_DIR/$component")
    {
      lib_error_print(9348, "Unable to remove '%s'.",
                      "$USER_COMMAND_LINK_DIR/$component");
      return USM_TRANSIENT_FAIL;
    }
  }

  # remove commands
  foreach $component (@ACFS_COMMAND_COMPONENTS)
  {
    $return_code = unlink("$ACFS_COMMAND_DIR/$component");
    if(!$return_code && -e "$ACFS_COMMAND_DIR/$component")
    {
      lib_error_print(9348, "Unable to remove '%s'.",
                      "$ACFS_COMMAND_DIR/$component");
      return USM_TRANSIENT_FAIL;
    }
  }

  foreach $component (@USER_COMMAND_COMPONENTS)
  {
    $return_code = unlink("$USER_COMMAND_DIR/$component");
    if(!$return_code && -e "$USER_COMMAND_DIR/$component")
    {
      lib_error_print(9348, "Unable to remove '%s'.",
                      "$USER_COMMAND_DIR/$component");
      return USM_TRANSIENT_FAIL;
    }
  }

  # remove driver loader/unloaders and start scripts
  foreach $component (@DRIVER_UTIL_COMPONENTS)
  {
    $return_code = unlink("$DRIVER_UTIL_DIR/$component");
    if(!$return_code && -e "$DRIVER_UTIL_DIR/$component")
    {
      lib_error_print(9348, "Unable to remove '%s'.",
                      "$DRIVER_UTIL_DIR/$component");
      return USM_TRANSIENT_FAIL;
    }
  }

  # remove drivers
  foreach $component (@DRIVER_COMPONENTS)
  {
    $return_code = unlink("$DRIVER_DIR/$component");
    if(!$return_code && -e "$DRIVER_DIR/$component")
    {
      lib_error_print(9348, "Unable to remove '%s'.",
                      "$DRIVER_DIR/$component");
      return USM_TRANSIENT_FAIL;
    }
  }

  # remove acfs helper dir
  if (-e $ACFS_COMMAND_DIR)
  {
    if (!opendir($dir_handle, $ACFS_COMMAND_DIR))
    {
      lib_error_print(9348, "Unable to remove '%s'.", $ACFS_COMMAND_DIR);
      return USM_TRANSIENT_FAIL;
    }

    @entries = readdir($dir_handle);

    # Remove the directory if it only has "." and ".."
    if (grep(!/^\.{1,2}$/, @entries) == 0)
    {
      if (!rmdir($ACFS_COMMAND_DIR))
      {
        lib_error_print(9348, "Unable to remove '%s'.", $ACFS_COMMAND_DIR);
        return USM_TRANSIENT_FAIL;
      }
    }
    else
    {
      lib_inform_print(9365, "The directory '%s' is not being removed.",
                                                     $ACFS_COMMAND_DIR);
      closedir($dir_handle);
    }
  }

  if (!defined($ENV{ADE_VIEW_ROOT}))
  {
    # Remove ODM entries
    $return_code = system("/bin/odmdelete -o PdDv -q type=acfsctl");
    if ($return_code != 0)
    {
      lib_error_print(9362, "Warning: deleting the AIX ODM entry for '%s' failed with error code '%s'.",
          "acfsctl", $return_code);
    }
    $return_code = system("/bin/odmdelete -o PdDv -q type=advmctl");
    if ($return_code != 0)
    {
      lib_error_print(9362, "Warning: deleting the AIX ODM entry for '%s' failed with error code '%s'.",
          "advmctl", $return_code);
    }
    $return_code = system("/bin/odmdelete -o PdDv -q type=advmvol");
    if ($return_code != 0)
    {
      lib_error_print(9362, "Warning: deleting the AIX ODM entry for '%s' failed with error code '%s'.",
          "advmvol", $return_code);
    }
    $return_code = system("/usr/sbin/savebase");

    # Remove /etc/oradevgrp, which stores ASMADMIN group
    $return_code = unlink("/etc/oradevgrp");
    if(!$return_code && -e "/etc/oradevgrp")
    {
      lib_error_print(9348, "Unable to remove '%s'.",
                      "/etc/oradevgrp");
      return USM_TRANSIENT_FAIL;
    }
  }

  if (!$preserve)
  {
    my $ret;
    # Names MUST match the ASM_OSD_TUNABLE_FILE_NAME define in asmdefs.h
    # and OFS_OSD_TUNABLE_FILE_NAME in ofsXXXtunables.h
    my ($advm_tunables) = "/etc/advmtunables";
    my ($acfs_tunables) = "/etc/acfstunables";

    if (-e $advm_tunables)
    {
      $ret = unlink $advm_tunables;
      if ($ret != 1)
      {
        lib_inform_print(9348, "Unable to remove '%s'.", $advm_tunables);
      }
    }
    if (-e $acfs_tunables)
    {
      $ret = unlink $acfs_tunables;
      if ($ret != 1)
      {
        lib_inform_print(9348, "Unable to remove '%s'.", $acfs_tunables);
      }
    }
  } 

  return USM_SUCCESS;
} # end osds_usm_uninstall

# osds_doaixsetup
#
# Do once-only setup
# Sets up AIX ODM and RBAC, store ASMADMIN group in /etc/oradevgrp
#
sub osds_doaixsetup
{
  my ($retval) = 0;
  my ($datafile);
  my ($component);

  # Get the ASMADMIN group
  $retval = system("$ORACLE_HOME/bin/osdbagrp -a > /etc/oradevgrp");
  if ($retval != 0)
  {
    lib_error_print(9357, "Getting the ASMADMIN group failed with error code '%s'.",
        $retval);
    return $retval;
  }

  #
  # Add ODM entries
  #
  foreach $component (@ODM_ENTRIES)
  {
    $datafile = "$MEDIA_PATH/$component.dat";
    $retval = system("/bin/odmget PdDv | grep $component | grep type > /dev/null");
    if ($retval != 0)
    {
      $retval = system("/bin/odmadd $datafile");
      if ($retval == 0)
      {
        lib_inform_print(9359, "The AIX ODM entry for '%s' was successfully added.",
              $component);
        $retval = system("/usr/sbin/savebase");
        if ($retval != 0)
        {
          lib_error_print(9356, "Saving the AIX ODM changes for '%s' failed with error code '%s'.",
              $component, $retval);
          return $retval;
        }
      }
      else
      {
        lib_error_print(9358, "Adding the AIX ODM entry for '%s' failed with error code '%s'.",
            $component, $retval);
        return $retval;
      }
    }
  }

  #
  # Run aixsetup
  # This performs RBAC setup.  If in development environment, skip RBAC setup
  # as we run everything with root privileges
  #
  if (!defined($ENV{ADE_VIEW_ROOT}))
  {
    my ($paramfile) = $ORACLE_HOME . "/crs/install/crsconfig_params";
    my $UNAME1 = qx { /usr/bin/grep "^ORACLE_OWNER" $paramfile | /usr/bin/cut -d '=' -f 2 };
    chomp $UNAME1;

    $retval = system("/bin/sh $MEDIA_PATH/aixsetup $UNAME1");
    if ($retval != 0)
    {
      lib_error_print(9360, "The command aixsetup failed with error code '%s'.", $retval);
      return $retval;
    }
  }

  return USM_SUCCESS;
} #end osds_doaixsetup

#
# Add the ACFS file system type to /etc/vfs
#
sub addACFSType
{
  my $file = '/etc/vfs';
  my $acfs = "acfs  41    /sbin/helpers/acfs    none\n";

  if (open(VFSLIST, "<", $file))
  {
    while (<VFSLIST>) {
      if (my ($found) = m/(acfs)/o) {
        return USM_SUCCESS;
      }
    }
  } else {
    lib_error_print(9363, "Opening the file /etc/vfs for read failed.");
    return USM_FAIL;
  }
  close VFSLIST;

  if (open(VFSLIST, ">>", $file))
  {
    print VFSLIST $acfs;
  } else {
    lib_error_print(9364, "Opening the file /etc/vfs for append failed.");
    return USM_FAIL;
  }

  close VFSLIST;
  return USM_SUCCESS;
}

1;
