On Wed, 22 Aug 2001, Mark Holm wrote:

>       Qualstar TLS-4220 Tape Jukebox with 20 slots and 1 AIT-1 tape drive
> 
> It appears as if the changer mechanism and the tape drive are not
> releasing the SCSI bus in a timely manner to allow the commands to complete
> when you switch devices.
> 
> Has anybody else seen this behavior? How do I fix it? Does anybody else have
> a Qualstar working with Amanda on RedHat 7.1?


I have a Qualstar TLS-4212 that I have not yet started interfacing
to Amanda, but will be doing so soon.  What I have found with this
library, as well as with an Overland library I used in a previous
job, is that there is a delay between when a tape is loaded by the
library into the tape drive and when the tape drive becomes ready to
accept tape commands.  Commands issued to the tape drive during this
period receive errors.

The Overland I used with a system that didn't at that time have a
supported changer script, so I wrote my own.  I found I had to insert
a delay after loading a tape until the drive became ready before
returning to the calling program.  Amanda tape changing worked
flawlessly in this manner.

I haven't yet begun setting up my Qualstar with Amanda but from
initial testing with a perl script it appears the same trick will be
necessary.  Below is a copy of my test script, which illustrates how
I was able to get the Qualstar to behave itself under program control.

Note in particular the wait_for_drive_ready subroutine.  This is stolen
more or less directly from my changer script for the Overland, except
for the open() test that worked the Overland's DLT drive but failed
to work with the Qualstar's AIT2 drive.  This is replaced with a
rather kludgy (but working) routine called tape_online.  I'd like to
think there's a better way to do this bit but in the short time I've
spent on it so far it hasn't come to me.

-Mitch

---------


#!/usr/local/bin/perl

# qtest: some preliminary testing of qualstar tape library

# configuration data
$CHANGER = '/dev/sg4';          # device file for changer mechanism
$TAPE = '/dev/nst0';            # device file for tape drive
$MT = "/bin/mt -t $TAPE";       # path to mt
$MTX = "/sbin/mtx -f $CHANGER"; # path to mtx
$MAXDELAY = 200;                # max delay to insert after tape load
                                # to allow tape drive to become ready.
$FIRST_SLOT = 1;
$LAST_SLOT = 10;

#$slot = 10;
#while (1) {
#       &load_tape($slot++);
#       if ($slot > $LAST_SLOT) { $slot = $FIRST_SLOT; }
#}

while (1) {
        $loaded_tape = &tape_loaded;
        print "Current loaded tape: $loaded_tape\n";
        &next_tape;
}

exit 0;


#
# load_tape: load tape from specified slot
#
sub load_tape {
        local($new_slot) = @_;
        local($response,$result);

        # first see if a tape is already loaded that needs to be put away
        $loaded_slot = &tape_loaded;

        # put away loaded tape
        if ($loaded_slot > 0) {
                if (&tape_online) {
                        print "ejecting tape from drive...\n";
                        system "$MT offl";
                }
                print "returning tape to slot $loaded_slot...\n";
                system "$MTX unload >/dev/null 2>&1";
        }

        # load requested tape
        print "loading tape from slot $new_slot...\n";
        system "$MTX load $new_slot";

        # wait for tape loading to complete and drive to become ready
        &wait_for_drive_ready;
}

#
# next_tape: load next tape in sequence
#
sub next_tape {
        local $loaded_slot = &tape_loaded;

        # if tape is in drive, eject first
        if (&tape_online) {
                print "ejecting tape from drive...\n";
                system "$MT offl";
        }

        # if current tape is from last slot, load tape from first slot
        if ($loaded_slot == $LAST_SLOT) {
                &load_tape( $FIRST_SLOT );

        } else {
        # load next tape
        print "loading next tape\n";
        system "$MTX next >/dev/null 2>&1";
        }

        # wait for tape loading to complete and drive to become ready
        &wait_for_drive_ready;
}

#
# tape_loaded: returns slot currently loaded tape came from, -1 if none
#
sub tape_loaded {
        local ($loaded_slot);

        open(MTX, "$MTX status|");
        while (<MTX>) {
                if ( /Data Transfer Element 0:Full/ ) {
                        ($loaded_slot) = /Storage Element (\d+) Loaded/;
                        last;
                } elsif ( /Data Transfer Element 0:Empty/ ) {
                        $loaded_slot = -1;
                        last;
                }
        }
        close MTX;
        return $loaded_slot;
}

#
# wait_for_drive_ready: test/sleep loop to wait till tape drive
#       becomes ready
#
sub wait_for_drive_ready {
        local $remaining;

        # see if tape drive is ready.  if not, sleep a while and check again
        $remaining = $MAXDELAY;
# this test works for DLT4000 but not for AIT2
#       while (!open(TAPE,$TAPE) && $remaining > 0) {
# this test works for AIT2
        while (!&tape_online && $remaining > 0) {
                $remaining -= sleep 5;
        }
        if ($remaining <= 0) {
                print "$0 drive $TAPE timed out, not responding\n";
                exit 2;
        }
#       close TAPE;
}

#
# tape_online: test a AIT2 tape drive to see if it's ready for some work
#
sub tape_online {

# do an 'mt status' command and throw away all but the last line
# of output.  See if last line contains "ONLINE".

        open(MT,"$MT status|");
        while (<MT>) {
                last if (/General status bits on/);
        }
        $_ = <MT>;
        if (/ONLINE/) {
                return 1;
        } else {
                return 0;
        }
}


Reply via email to