#!/usr/local/bin/perl # # $Header: ob.pl 07-oct-2004.13:06:22 pfgavin Exp $ # # ob.pl # # Copyright (c) 2002, 2004, Oracle. All rights reserved. # # NAME # ob.pl - Perl script for Oracle Backup remote operations. # # DESCRIPTION # Remote execution routines for Oracle Backup. # # NOTES # # # MODIFIED (MM/DD/YY) # pfgavin 10/07/04 - rb->ob # pfgavin 05/28/04 - pfgavin_oracle-backup-init # pfgavin 03/17/04 - Creation # use FileHandle; use IPC::Open2; use vars qw/ $OS $NT $S $TEMP $CP $MV $PS $DF $DELIMITER/; require "emd_common.pl"; $ERROR_CODE = 8; # # set_ob_env() # # If the perl script is run in an ade environment then # look for the env script in the temp dir. This script fille # will set the nessessary environment variables to access # the ob administrative domain running in a view. # sub set_ob_env { EMD_PERL_DEBUG("ob.set_ob_env(): start"); $rbtmpfile = "/tmp/rbmapvars.sh"; open rbtmpfile or die "Can't find /tmp/rbmapvars.sh\n"; while () { ($xtra, $varname, $varvalue) = split / /; substr($varvalue, 0, 1) = ""; substr($varvalue, -2) = ""; $ENV{$varname} = $varvalue; } EMD_PERL_DEBUG("ob.set_ob_env(): end"); } # # runOb # # Run Oracle Backup CLI and pass output backup up to the OMS. # sub runOb() { EMD_PERL_DEBUG("ob.runOb(): start"); $? = 0; local $SIG{PIPE}; local $SIG{CHLD}; if (!$NT) { # Ignore PIPE signal which might be invoked by "print OB_WRITER .. " # If we don't catch it the signal will terminate the script $SIG{PIPE} = sub { }; $obExit = 0; # Reaper to collect ob exit status $SIG{CHLD} = sub { if (waitpid($pid, WNOHANG)) { $ob_result = $?; $obExit = 1; } }; } # Check for obtool in the ob_command string. ($rbpath, $other) = split / /, $ob_command; EMD_PERL_DEBUG("ob.runOb(): obpath: $rbpath"); if (!-e $rbpath) { print "No obtool found: $rbpath\n"; return -1; } # Look for ADE env file. if (!$NT) { if (-e "/tmp/rbmapvars.sh") { set_ob_env(); } } else { #TODO on Windows } EMD_PERL_DEBUG("ob.runOb(): open2: command: $ob_command"); $pid = open2(\*RDRFH, \*WRITER, "$ob_command 2>&1") || ((print "Unable to open the obtool process in run_ob().\n") && (return -1)); # Turn on autoflush for pipe output $old_fh = select(RDRFH); $| = 1; select($old_fh); if (!$NT) { # set RDRFH non-blocking my $flags = ''; fcntl(RDRFH, F_GETFL(), $flags) or die "Couldn't get flags for RDRFH : $!\n"; $flags |= O_NONBLOCK(); fcntl(RDRFH, F_SETFL(), $flags) or die "Couldn't set flags for RDRFH: $!\n"; } # Turn on autoflush for standard output $old_fh = select(STDOUT); $| = 1; select($old_fh); # Write the password to obtool print WRITER $ob_password; close WRITER; $MAX_OUT_SIZE = 7168; #7K $cur_out_size = 0; $timeout = 0; if (!$NT) { # Construct the data structure for select call vec($rin, fileno(RDRFH), 1) = 1; my $bufSize = 100; $fullBuf =""; while (1) { # wait for reading event on RDRFH, or timeout after 5 seconds $a = select($rout=$rin, undef, undef, 5); if ($a > 0 && vec($rout,fileno(RDRFH),1)) { # There are something in RDRFH for read $sysret = sysread RDRFH, $buf, $bufSize; if (defined($sysret)) { if ($sysret == 0) { # RDRFH is closed by ob last; } else { $fullBuf .= $buf; $cur_out_size += length($buf); print "$buf"; } } } else { # select() times out or detects an error if ($timeout > 15) { # ob has exited as detected by the reaper # we do a final non-blocking reading in case there are something # in the pipe left by obtool while ($sysret = sysread RDRFH, $buf, $bufSize) { $fullBuf .= $buf; $cur_out_size += length($buf); print "$buf"; } last; } $timeout = $timeout + 5; } } } else { # NT case $fullBuf =""; do { $sysret = sysread RDRFH, $buf, 100; if (defined($sysret)) { $cur_out_size += length($buf); print "$buf"; $fullBuf=$fullBuf.$buf; } else { print "An error ocurred when reading from ob: $? $!\n"; $ob_result = -1; } } while (defined($sysret) && $sysret != 0); } # xun: close RDRFH after reading is done close RDRFH; if ($NT) { # On NT, there is no reaper to collect the exit status of obtool. # We'll do it here. my $wpid = waitpid $pid, 0; if ($wpid != -1) { $ob_result = $?; } # if waitpid returns -1 (in which case it's a bug for perl), # we'll have to parse the obtool output to determine whether # the operation is successful or not } if ($ob_result != 0) { $ob_result = -1; } EMD_PERL_DEBUG("ob.runOb(): end"); return("0"); } #runOb();