MINI MINI MANI MO

Path : /opt/oracle/product/18c/dbhomeXE/lib/
File Upload :
Current File : //opt/oracle/product/18c/dbhomeXE/lib/olfscmd.pl

# 
#
# olfsroot.pl
# 
# Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
#
#    NAME
#      olfsroot.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#      <short description of component this file declares/defines>
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
# 

my ($KVER);
my ($ARCH) = `uname -i`;                        # Machine architecture - i386
chomp($ARCH);
my ($UNAME_R) = `uname -r`;
chomp($UNAME_R);

our ($ORACLE_HOME) = $ENV{ORACLE_HOME};

my  ($SHIPHOME_BASE_DIR) = "$ORACLE_HOME/usm/install";
our ($OLFS_DFLT_CMD_LOC)  = "$SHIPHOME_BASE_DIR/cmds/bin";
our ($OLFS_DFLT_DRV_LOC);
my ($SBIN_DIR)         = "/sbin";
my ($DRIVER_DIR);
my ($COMMAND) = "No Command Specified";
my ($OLFS_PATCH_PREFIX) = ".olfs_patch_";
my ($OLFS_PATCH_PREFIX_LEN) = length($OLFS_PATCH_PREFIX);
my ($OLFS_HIDE_PREFIX) = ".olfs_hide_";

use constant USM_SUCCESS            => 0;
use constant USM_FAIL               => 1;

use strict;
use Getopt::Std;
use Cwd 'abs_path';
use File::Basename;
use English;
use Config;
use File::Path;

main();

sub get_olfs_driver_dir
{
    my ($driver_build_version); # version that the driver was linked for.

    $driver_build_version = $UNAME_R;

    return "/lib/modules/$driver_build_version/extra/oracle";
}

sub olfsroot_exit
{
  my ($ret) = @_;

  exit $ret;
}

sub main
{
  my ($sub_command);         # start or stop
  my ($return_code);         # as the name implies 
  # user options
  my (%opt);                 # user options hash - used by getopts()
                             # -h : help

  # user flags. See description above or usage message output
  my (%flags) = ( load       => 'h',
                  unload     => 'h',
                  repltree   => 'h',
                  beginphase => 'h',
                  endphase   => 'h',
                  delpatchfiles => 'h',
                );

  # process the command line for acfsutil cmdlog
  # We could just use "acfsutil cmdlog -s @ARGV"
  # but that wouldn't give us the absolute command path name;
  my ($opt, $opts);

  $opts = "";
  foreach $opt (@ARGV)
  {
    $opts = abs_path($0) if $opts eq "";  # command name
    $opts .= " $opt";
  }

  # supplied by the front end driver and 'guaranteed' to be there.
  # command is what the user actually typed in (sans directories).
  $COMMAND = shift(@ARGV);

  # supplied by user
  $sub_command = shift(@ARGV);

  print "sub command is $sub_command\n";

  # must be supplied by the user.
  if (defined($sub_command))
  {
    if (!(($sub_command eq 'load') ||
          ($sub_command eq 'unload') ||
          ($sub_command eq 'repltree') ||
          ($sub_command eq 'beginphase') ||
          ($sub_command eq 'endphase') ||
          ($sub_command eq 'delpatchfiles')))
    {
      # illegal sub-command
      print "invalid command\n";
      usage("invalid", 0);
      olfsroot_exit(USM_FAIL);
    }
  }
  else
  {
    # no sub-command
    print "No sub command found\n";
    usage("invalid", 0);
    olfsroot_exit(USM_FAIL);
  }

  # parse user options
  %opt=();
  getopts($flags{$sub_command}, \%opt) or usage($sub_command, 1);
  if ($opt{'h'})
  {
    # print help information
    usage($sub_command, 0);
    olfsroot_exit(USM_SUCCESS);
  }

  ##### command parsing complete #####

  if ($sub_command eq 'load')
  {
      $return_code = load();
  }
  else
  {
    if ($sub_command eq 'unload')
    {
        $return_code = unload();
    }
    else
    {
        if ($sub_command eq 'repltree')
        {
            my ($src, $dest);
            $src = shift(@ARGV);
            $dest = shift(@ARGV);

            repltree($src, $dest);
            $return_code = USM_SUCCESS;
        }
	else
	{
	  if (($sub_command eq 'beginphase') || ($sub_command eq 'endphase'))
	  {
	    my ($oh, $cmd);
	    $oh = shift(@ARGV);
        if ($sub_command eq 'beginphase')
        {
            $cmd = $ORACLE_HOME . "/bin/olfsctl phase $oh 1";
        }
        else
        {
            $cmd = $ORACLE_HOME . "/bin/olfsctl phase $oh 0";
        }

	    if (system($cmd) == 0)
        {
            $return_code = USM_SUCCESS;
        }
        else
        {
            $return_code = USM_FAIL;
        }
	  }
	  else
	  {
	    if ($sub_command eq 'delpatchfiles')
	    {
	      my ($agi_path);
	      $agi_path = shift(@ARGV);
	      delete_patch_files($agi_path);
	      $return_code = USM_SUCCESS;
	    }
	  }
	}
    }
  }

  olfsroot_exit($return_code);
} # end main

sub load()
{
    my $command;
    my $ret;
    my $return_code = USM_SUCCESS;

    $DRIVER_DIR = get_olfs_driver_dir();

    $command = "/sbin/insmod $DRIVER_DIR/oracleolfs.ko";
    $ret = system ($command);
    $return_code = USM_FAIL if $ret;

    return ($return_code);

}

sub unload()
{
    my $command;
    my $ret;
    my $return_code = USM_SUCCESS;

    $command = "/sbin/rmmod oracleolfs.ko";
    $ret = system ($command);
    $return_code = USM_FAIL if $ret;

    return ($return_code);
}

sub repltree {
    my $mysrc = $_[0];
    die "Incorrect source directory path ($mysrc) provided" 
        unless -d $mysrc;
    
    my $mydest = $_[1];    
    if (-d $mydest)
    {
        create_dir($mysrc, $mydest, 1);
    }
    else
    {
        if (-f $mydest)
        {
            die "Destination ($mydest) not a directory\n"
        }
        else
        {
            create_dir($mysrc, $mydest, 0);
        }
    }
}

# In addition to deleting the patch hidden files and corresponding generated
# files, libasmclntsh18.so also needs to be deleted from AGI, as it contains
# the patching information, but is not re-generated during clone phase. So,
# there is no hidden patch file for it and the corresponding file in AGI does
# not get deleted automatically. Due to this, the patched file in AUI remains
# hidden by the corresponding AGI file. Hence, it must deleted manually.
#
# The object file containing the patch information is 'skgfpmi.o', which is
# archived into 'libasmclntsh18.a'. So, this archive file also needs to deleted
# because it does NOT get re-generated during the clone phase.
#
# Bug-26441818: comps.xml file contains the patch information, which is read by
# Opatch to list the patches installed in the home. During initial provisioning,
# it is promoted to AGI outside of the clone operation.
#
# So, when patching is done on an OLFS-based home for the first time, it is not
# updated during the clone phase and AGI still contains the older comps.xml
# file. As clone does not update this, so we do not create a hidden patch file
# for it.
#
# Before clone is run on patched home, RHP needs to run 'delpatchfiles' command
# to delete the files from AGI created during previous clone run, so that the
# home picks up new files from patched AUI. Since, comps.xml does not have a
# corresponding hidden file, it does not get deleted by 'delpatchfiles' command.
# Hence, even though the software running on a patched OLFS home contains the
# patches, but when queried upon, it does not list them.
#
# When patch rollback is executed on a patched OLFS home, Opatch tries to list
# the patches installed on the home, but it does not list any patches as
# comps.xml file is old. So, the command fails saying that there is nothing to
# rollback.
#
# Also, applying a patch over the already patched OLFS home would also fail as
# this also checks for existence of already installed patch.
#
# So, this file has to be deleted manually from AGI as a part of 'delpatchfiles'
# command before execution of clone. This ensures that when Opatch queries to
# list the patches, it uses the latest comps.xml file from patched AUI.
#
# Also, applying a patch over the already patched LPM home would fail as this
# too checks for existence of already installed patch.

sub delete_patch_files {
    my $ag_path = $_[0];
    del_patch_files($ag_path);
    my $file = $ag_path . "/lib/libasmclntsh18.so";
    unlink $file;
    $file = $ag_path . "/lib/libasmclntsh18.a";
    unlink $file;
    $file = $ag_path . "/inventory/ContentsXML/comps.xml";
    unlink $file;
}

# This function deletes the files and their corresponding hidden files created
# during the clone phase.

sub del_patch_files {
    my $agi_dir = $_[0];
    opendir(my $DIR, $agi_dir);
    while (my $dirent = readdir $DIR) {
        next if $dirent eq '.' or $dirent eq '..';
        my $agi_path = $agi_dir . '/' . $dirent;
        if (-f $agi_path)
        {
            if (index($dirent, $OLFS_PATCH_PREFIX) != -1)
            {
                my $fname = substr($dirent, $OLFS_PATCH_PREFIX_LEN);
                my $fpath = $agi_dir . '/' . $fname;
                my $hidden_fpath = $agi_dir . '/' . $OLFS_HIDE_PREFIX . $fname;
                #print "File path to delete is: $fpath\n";
                #print "Hidden File path to delete is: $agi_path\n";
                #print "Hidden File path to delete is: $hidden_fpath\n";
                unlink $fpath;
                unlink $agi_path;
                unlink $hidden_fpath;
            }
        }
        elsif (-d $agi_path)
        {
            my $agi_path = $agi_dir . '/' . $dirent;
            del_patch_files($agi_path);
        }
    }
    closedir $DIR;
}

sub create_dir {
    my $src = $_[0];
    my $dest = $_[1];
    my $call_num = $_[2];
    if ($call_num == 0)
    {
        mkdir $dest;
        #print "Creating new directory $dest\n";
    }

    opendir(my $DIR, $src);
    while (my $dirent = readdir $DIR) {
        next if $dirent eq '.' or $dirent eq '..';
        my $new_src = $src . '/' . $dirent;
        my $new_dest = $dest . '/' . $dirent;
        next unless -d $new_src;
        if (-l $new_src)
        {
            #print "Symlink found $new_src and dest is $new_dest\n";
            my $new_link = readlink($new_src);
            #print "Symlink path $new_link\n";
            symlink($new_link, $new_dest);
        }
        elsif (-d $new_dest)
        {
            create_dir($new_src, $new_dest, 1);
        }
        else
        {
            if (-f $new_dest)
            {
                die "Destination ($new_dest) not a directory\n"
            }
            create_dir($new_src, $new_dest, 0);
        }
    }
    closedir $DIR;
}


sub usage
{
    my ($sub_command, $abort) = @_;

    if ($sub_command eq "load")
    {
        print "olfscmd load: Load OLFS kernel driver.\n";
        print "Usage: olfscmd load\n";
    }

    if ($sub_command eq "unload")
    {
        print "olfscmd load: Unload OLFS kernel driver.\n";
        print "Usage: olfscmd unload\n";
    }

    if ($sub_command eq "repltree")
    {
        print "olfscmd repltree: replicate directory structure from src to dest\n";
        print "Usage: olfscmd repltree <srcdir> <destdir>\n";
    }
    
    if ($sub_command eq "beginphase")
    {
        print "olfscmd beginphase: start the object regeneration phase\n";
        print "Usage: olfscmd beginphase <ohpath>";
    }

    if ($sub_command eq "endphase")
    {
        print "olfscmd endphase: end the object regeneration phase\n";
        print "Usage: olfscmd endphase <ohpath>";
    }

    if ($sub_command eq "delpatchfiles")
    {
        print "olfscmd delpatchfiles: delete hidden patch files created during object regeneration phase\n";
        print "Usage: olfscmd delpatchfiles <agpath>";
    }

    if ($sub_command eq "invalid")
    {
        print "olfscmd: Invalid command.\n";
        print "Usage: olfscmd {load | unload | repltree <srcdir> <destdir>} [-h]\n";
    }

    if ($abort)
    {
        olfsroot_exit(USM_FAIL);
    }
}

OHA YOOOO