Yes.  I've been using Hiarc's jukebox software for few months now.  Below is the script
I wrote for Amanda to use the hiarc jukebox software to interact with our autochanger.

You can copy and paste the script below into a file called "chg-hiarcjb".  If you have
any problems with it, send me an output of jbstatus in various states (e.g. tape not
loaded, one tape loaded in the drive, some empty slots, etc) and I'll try to fix the
script for you unless you want to hack it yourself, feel free to do so.

Josh Huston
Unix Systems Administrator
Analysts International
Minneapolis, MN

--------------------------------------

#! /usr/bin/perl

# Catch for sh/csh on systems without #! ability.
eval '(exit $?0)' && eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
        & eval 'exec /usr/bin/perl -S $0 $argv:q'
                if 0;

# 
# This changer script controls tape libraries on operating systems that have a
# jbstatus and movejb program from HIARC company, www.hiarc.com.
#
# The numbering of the slots is by the way from 1 to n with slots. 
# 
# This script is built up out of bits and pieces of the other scripts
# and no credits are claimed. Most notably the chg-rth.pl script was used. That
# script was written by Erik Frederick, <[EMAIL PROTECTED]> and chg-chio
# script by Nick Hibma, <[EMAIL PROTECTED]>
#
# Permission to freely use and distribute is granted (by me and was granted by
# the original authors).
#
# Josh Huston - [EMAIL PROTECTED]
#

require 5.001;

($progname = $0) =~ s#/.*/##;

use English;
use Getopt::Long;

$| = 1;

if (-d "/tmp/amanda") {
        $logfile = "/tmp/amanda/$progname.debug";
} else {
        $logfile = "/dev/null";
}
die "$progname: cannot open $logfile: $ERRNO\n"
        unless (open (LOG, ">> $logfile"));

#
# Path to jbstatus, movejb
#

$jbstatus = "/opt/HIARCjb/bin/jbstatus";
$movejb = "/opt/HIARCjb/bin/movejb";
$mtpath = "/bin/mt";
$sleep_seconds = 45;                    # number of seconds to sleep after
                                        # loading a tape

#
# Globals
#

$currentTape = 0;

#
# get the information from the configuration file
#

$prefix="/usr/local";
$exec_prefix="${prefix}";
$sbindir="${exec_prefix}/sbin";
$libexecdir = "${exec_prefix}/libexec";
if ( "no" eq "yes" ) {
    $SUF = "-2.4.2";
} else {
    $SUF = "";
}

chomp ($tapeDevice = `$sbindir/amgetconf$SUF tapedev 2>&1`);
die "tapedev not found in amanda.conf"
        if !$tapeDevice or $tapeDevice =~ m/BUGGY/;
chomp ($changerDevice = `$sbindir/amgetconf$SUF changerdev 2>&1`);
chomp $changerDevice;
die "changerdev not found in amanda.conf"
        if !$changerDevice or $changerDevice =~ m/BUGGY/;
#
# Initialise a few global variables
#

@slots = ();
@drives = ();
$max_slot = 0;
$max_drive = 0;
$nr_tapes = 0;

@dow = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
@moy = ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

sub do_time {
        my (@t);
        my ($r);

        ###
        # Get the local time for the value.
        ###

        @t = localtime (time ());

        ###
        # Return the result.
        ###

        $r = sprintf "%s %s %2d %2d:%02d:%02d %4d",
          $dow[$t[6]],
          $moy[$t[4]],
          $t[3],
          $t[2], $t[1], $t[0],
          1900 + $t[5];

        return $r;
}

sub getJukeboxInfo {
        print LOG &do_time(), ": enter: getJukeboxInfo\n";

        #
        # Sets $nr_tapes, @slots, @drives, $current_tape
        #

        my($type,$num,$status);

        print LOG &do_time(), ": running: $jbstatus\n";
        if ( !(open(FH,"$jbstatus|")) ) {
                print "$progname: '$jbstatus' failed, $!\n";
                exit(2);
        }

        #
        # This routine requires the format of the output of 'jbstatus' to 
        # be as follows:
        #
        #   Mode Sense: status 0
        #   Storage Slots 1 - 7
        #   Import/Export Slots 0 - -1
        #   Data Transfer Elements 82 - 82
        #   MTE
        #             ElemAddr 86 
        #   SE
        #             ElemAddr 1 Full Access OK    SrcAddr 1 
        #             ElemAddr 2 Access OK 
        #             ElemAddr 3 Full Access OK    SrcAddr 3 
        #             ElemAddr 4 Full Access OK    SrcAddr 4 
        #             ElemAddr 5 Full Access OK    SrcAddr 5 
        #             ElemAddr 6 Full Access OK    SrcAddr 6 
        #             ElemAddr 7 Full Access OK    SrcAddr 7 
        #   DTE
        #             ElemAddr 82 Full Access OK SCSI 3    SrcAddr 2 


        @slots=();
        @drives=();

        #
        # Get slot identifier numbers
        #

        $foundse = 0;

        while(!$foundse) {
                $line = <FH>;
                if ( $line =~ m/^se$/i ) {
        #               print("found SE\n");
                        $foundse = 1;
                        next;
                }
                elsif ( $line =~ m/medium/i ) {
                        $line =~ m/Medium Transports (\d+) - (\d+)/;
                        $max_picker = ($2 - $1) + 1;            
        #               print ("max_picker: $max_picker\n");
                }
                elsif ( $line =~ m/storage/i ) {
                        $line =~ m/Storage Slots (\d+) - (\d+)/;
                        $max_slot = ($2 - $1) + 1;
        #               print ("max_slot: $max_slot\n");
                }
                elsif ( $line =~ m/data/i ) {
                        $line =~ m/Data Transfer Elements (\d+) - (\d+)/;
                        $max_drive = ($2 - $1) + 1;
        #               print ("max_drive: $max_drive\n");
                }
        }       

        $founddte = 0;
        while(!$founddte) {
                $line = <FH>;
                chomp( $line );
                print LOG &do_time(), ": $line\n";
                if ( $line =~ m/^dte$/i) {
        #               print("found DTE\n");
                        $founddte = 1;
                        next;
                }
                $line =~ m/\s+ElemAddr (\d+)/;
                $num = $1;
                $slots[$num] = ( $line =~ m/full/i ) ? 1 : 0;
                if ($slots[ $num ]) { $nr_tapes++ }
        #       print("\$slots[$num] = $slots[$num]\n");
        }
        
        #
        # We are at DTE block now and getting drive identifier
        #

        $line = <FH>;
        chomp($line);

        if ( $line =~ m/full/i ) {
                $line =~ m/\s+ ElemAddr (\d+) Full Access OK SCSI \d+\s+ SrcAddr
(\d+)/;
                ($drives[0],$currentTape) = ($1,$2);
                $nr_tapes++;
        #       print("drive: $1 currentTape: $2\n");
        }
        else {
        #       print("empty drive\n");
                $line =~ m/\s+ ElemAddr (\d+)[\w\s]+/;
                $drives[0]=$1;
                $currentTape = 0;
        #       print("drive: $1 currentTape: $currentTape\n");
        }               
                
        close(FH);

        if ( $nr_tapes == 0 ) {
                print "$progname: No tapes in changer!\n";
                exit(2);
        }

        print LOG &do_time(), ": leave: getJukeboxInfo: $nr_tapes\n";
        return($nr_tapes);
}

sub testTape {
        my($tape) = @_;

        #
        # Check a few parameters to avoid the most serious problems
        #

        return
                if $currentTape == $tape;

        if( $slots[$tape] == 0 ) {
                print "<none> $progname: no tape in slot requested\n";
                exit(1);
        }
        if( $tape > $max_slot ) {
                print $tape," $progname: requested a tape > $max_slot\n";
                exit(2);
        }
        if( $tape < 1 ) {
                print $tape," $progname: requested a tape < 1\n";
                exit(2);
        }
        return;
}

sub Load {
        my($tape) = @_;
        print LOG &do_time(), ": enter: Load: $tape\n";

        #
        # Load tape $tape into drive 0
        #

        print LOG &do_time(), ": running: $movejb $changerDevice $tape $drives[0]\n";
        if ( system("$movejb $changerDevice $tape $drives[0] >>
/tmp/amanda/movejb.debug") ) {
                print "$progname: cannot '$movejb $changerDevice $tape $drives[0]' tape
$tape into drive 0\n";
                exit(2);
        }
        print LOG &do_time(), ": sleeping $sleep_seconds seconds to calibrate the
tape\n";
        sleep($sleep_seconds);
        print LOG &do_time(), ": leave: Load\n";
}

sub Unload {
        my($tape) = @_;
        print LOG &do_time(), ": enter: Unload: $tape\n";

        #
        # Unload the tape from drive 0 and put it into the slot specified by
        # $tape.
        #

        system ("$mtpath -f $tapeDevice rewoffl")
                unless $currentTape == 0;

        print LOG &do_time(), ": running: $movejb $changerDevice $tape $drives[0]\n";

        if ( system("$movejb $changerDevice $drives[0] $tape >>
/tmp/amanda/movejb.debug") ) {
                print "$progname: cannot '$movejb $changerDevice $drives[0] $tape' tape
$tape from drive 0\n";
                exit(2);
        }
        print LOG &do_time(), ": leave: Unload\n";
}

sub changeTape {
        my($tape) = @_;
        print LOG &do_time(), ": enter: changeTape: $tape\n";

        #
        # Unload current tape and load a new tape from slot $tape.
        #

        if ($tape != $currentTape) {

                &testTape($tape);

                if( $currentTape != 0 ) {
                        &Unload($currentTape);
                }
                &Load($tape);
                $currentTape = $tape;
        }
        print LOG &do_time(), ": leave: changeTape\n";
}


#
# Main program
#

#
# Initialise
#

$nr_tapes = &getJukeboxInfo();

$opt_slot = 0;                                  # perl -w fodder
$opt_info = 0;                                  # perl -w fodder
$opt_reset = 0;                                 # perl -w fodder
$opt_eject = 0;                                 # perl -w fodder

GetOptions("slot=s", "info", "reset", "eject"); 

#
# Before we do anything with the tape changer we'll have to rewind the tape
#

system ("$mtpath -f $tapeDevice rewind")
        unless $currentTape == 0;


if ( $opt_slot ) {
        if ( $opt_slot =~ /first/ ) {
                &changeTape(1);
                print LOG &do_time(), ": $currentTape $tapeDevice\n";
                print "$currentTape $tapeDevice\n";
        }
        if ( $opt_slot =~ /last/ ) {
                &changeTape($max_slot);
                print LOG &do_time(), ": $currentTape $tapeDevice\n";
                print "$currentTape $tapeDevice\n";
        }
        if ( $opt_slot =~ /current/ ) {
                &changeTape($currentTape);
                print LOG &do_time(), ": $currentTape $tapeDevice\n";
                print "$currentTape $tapeDevice\n";
        }
        if ( $opt_slot =~ /next/ ) {
                $tape = $currentTape+1;
                while ( $slots[$tape] == 0 ) {        # there is at least 1 
                        if ( ++$tape > $max_slot ) {
                                $tape = 1;
                        }
                }
                &changeTape($tape);
                print LOG &do_time(), ": $currentTape $tapeDevice\n";
                print "$currentTape $tapeDevice\n";
        }
        if ( $opt_slot =~ /prev/ ) {
                $tape = $currentTape-1;
                while ( $slots[$tape] == 0 ) {        # there is at least 1
                        if ( --$tape < 1 ) {
                                $tape = $max_slot;
                        }
                }
                &changeTape($tape);
                print LOG &do_time(), ": $currentTape $tapeDevice\n";
                print "$currentTape $tapeDevice\n";
        }
        if ( $opt_slot =~ /^\d+$/ ) {
                &changeTape($opt_slot);
                print LOG &do_time(), ": $currentTape $tapeDevice\n";
                print "$currentTape $tapeDevice\n";
        }
        if ( $opt_slot =~ /advance/ ) {
                $tape=$currentTape+1;
                if ( $tape > $max_slot ) {
                        $tape = 1;
                }
                if ( $currentTape ) { 
                        &Unload($currentTape);
                }
                print LOG &do_time(), ": $currentTape $tapeDevice\n";
                print "$currentTape , /dev/null\n";
        }

        exit 0;
}

if ( $opt_info ) {
        if ( $currentTape == 0 ) {
                &Load(1);                       # load random tape
                $currentTape = 1;
        }

        print LOG &do_time(), ": $currentTape $max_slot 1\n";
        print "$currentTape $max_slot 1\n";
        exit 0;
}

if ( $opt_reset ) {
        &changeTape(1);
        print LOG &do_time(), ": $currentTape $tapeDevice\n";
        print "$currentTape $tapeDevice\n";
        exit 0;
}

if ( $opt_eject ) {
        if ( $currentTape ) { 
                &Unload($currentTape);
                print "0 $tapeDevice\n";
                exit 0;
        } else {
                print "$progname: drive was not loaded\n";
                exit 1;
        }
}

print "$progname: No command was received.  Exiting.\n";
exit 1;

Reply via email to