Networker

Re: [Networker] Automated Tape Loading/Unloading

2004-11-19 16:46:47
Subject: Re: [Networker] Automated Tape Loading/Unloading
From: Tim Mooney <mooney AT DOGBERT.CC.NDSU.NODAK DOT EDU>
To: NETWORKER AT LISTMAIL.TEMPLE DOT EDU
Date: Fri, 19 Nov 2004 15:45:59 -0600
In regard to: [Networker] Automated Tape Loading/Unloading, Morehead, Lee...:

Hello all,
       What I would like is the ability to unload a batch of tapes from
the library that is greater than the capacity of my load port.
Currently I have a script that uses mminfo to determine what tapes I
need but I have to make several trips into the data center to unload the
load port.  I would like to be able to run the script stand in front of
the library (STK L700) empty the cap.  Close the cap and have the rest
of the tapes load into the cap then it open back up for me to remove the
remaining tapes and repeat as many times as necessary.  Loading tapes
the same way in reverse.  I know I probably need the exercise but :)...
       Has anyone aready done something like this?

I have (withdraw only, not deposit).  I've recently received permission to
share all my NetWorker-related scripts under a GPL license, but I haven't
had time to package them up or even clean up some of the scary areas in
the code.  :-|

Since the list doesn't include attachments, the script is included inline
after my sig.  If your email client mangles it (line wrap, etc.), contact
me off-list and I'll resend.

It's distributed under the GNU Public License, no warranty, use at your
own risk, etc.

You use it by creating a file with all the volume *names* you want to
withdraw, and then feed it to the program like

       ./nsr_batch_withdraw.pl --file withdraw_these.txt

Let me know if you encounter problems with it.

Tim
--
Tim Mooney                              mooney AT dogbert.cc.ndsu.NoDak DOT edu
Information Technology Services         (701) 231-1076 (Voice)
Room 242-J6, IACC Building              (701) 231-8541 (Fax)
North Dakota State University, Fargo, ND 58105-5164


#! /local/bin/perl -w

# Author: Tim Mooney <Tim.Mooney AT ndsu.NoDak DOT edu>

# Copyright: This file is copyright 2001, 2004 North Dakota State University.
# This file is distributed under the terms of the GNU Public License,
# Version 2.  See  http://www.gnu.org/licenses/licenses.html for more
# information.

#PATH=/usr/bin:/usr/sbin:/sbin:/usr/ccs/bin:/usr/opt/networker/bin
#export PATH

use Getopt::Long;
use strict;

#
#
# The subroutines
#
#

# usage() takes one parameter, the value it should pass to exit().  This
# value should be 0 if the invoker asked for --help, it should be > 0
# to indicate that the program was invoked incorrectly.
sub usage($);

#
# The variables we use:
#

# External commands we call -- having them all in a commands hash is
# convenient.
my %CMD = (
#       'nsrjb' =>      '/usr/opt/networker/bin/nsrjb'
       'nsrjb' =>      '/usr/bin/nsrjb'
);

# $pos is used only for path trimming of $0.
my $pos = '';

# $ret_val holds the return value from various calls, for error checking.
my $ret_val = 0;

my $file_with_volume_names  = '';
my $num_slots_in_loadport = 14;

#
# variables that control how this program acts, $verbose to make it more
# chatty, $quiet to make it less chatty, $debugging to indicate we want it
# to tell us debugging info about what it *would* do, rather than actually
# doing it.
my $verbose   = 0;
my $quiet     = 0;
my $debugging = 0;
my $help      = 0;

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#
#
# Execution starts here.
#
#
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


#
# shorten our name, for use in error messages, in case we were called with
# path specification.
# $0 is used by usage(), and possibly elsewhere.
#
if (($pos=rindex($0, '/')) >= $[) {
    $0=substr($0, $pos+1, length($0) - $pos);
}

#
# parse our command line options.
#

$ret_val = GetOptions(
       'help'          =>      \$help,
       'verbose'       =>      \$verbose,
       'quiet'         =>      \$quiet,
       'loadport-slots=i'      =>      \$num_slots_in_loadport,
       'file=s'        =>      \$file_with_volume_names
);

#
# Argument processing didn't go so well.  Tell them all about what we like
# to see on the command line.
#
if ($ret_val != 1) {
       usage(1);
}

if (defined($help) and ($help == 1)) {
       #
       # they asked for help, give them some
       #
       usage(0);
}

#
# Make sure all commands we need are available.
#
my $key;
foreach $key (keys(%CMD)) {
       if (! -f $CMD{$key}) {
               print STDERR "$0: ", $CMD{$key}, ": Not found\n";
               exit(1);
       } elsif (! -x $CMD{$key}) {
               print STDERR "$0: ", $CMD{$key}, ": Not executable\n";
               exit(1);
       }
}

my $volumes_moved_to_loadport=0;
open(VOLFILE, "$file_with_volume_names") or die
       "$0: Can't open the file containing the volumes to withdraw: $!\n";

my @vols_to_withdraw = <VOLFILE>;
close(VOLFILE) or die "$0: close failed for $file_with_volume_names: $!\n";

#
# Build a map of what volumes are in what slots
#
my $cmd = $CMD{'nsrjb'} . " -C";
open(NSRJB, "$cmd |") or die
       "$0: Can't read from $cmd pipe: $!\n";

my %toc;
while (<NSRJB>) {

       my $line;
       chomp($line = $_);

       next if ($line =~ /^drive /);
       next if ($line =~ /^$/);
       next if ($line =~ /^Jukebox/);
       next if ($line =~ /^\s*slot\s*volume\s*pool/);
       # empty slots
       next if ($line =~ /^\s*\d+:\s*$/);
       # unlabelled/unknown volumes
       next if ($line =~ /^\s*\d+: -\*\s*-\s*$/);
       next if ($line =~ /\s*\*not registered in the.*media data base/);
       # cleaning tape
       next if ($line =~ /^\s*\d+: Cleaning Tape.*$/);

       if ($line =~ /^\s*(\d+):\s*(.*)(:|\.)(\d+)\s*/) {
               my $volname="$2$3$4";
               my $slot=$1;

               $toc{$volname} = $slot;
       } else {
               warn "$0: odd looking line->$line<-\n";
       }
}

my $tape;
foreach $tape (sort(keys(%toc))) {
#       print $toc{$tape}, " : $tape\n"

       if ($volumes_moved_to_loadport == $num_slots_in_loadport) {
               print "$0: Exiting, we've filled the loadport\n";
               exit(0);
       }

       # if the tape is in the @vols_to_withdraw list, do so.
       if (scalar(grep(/^$tape/, @vols_to_withdraw)) > 0) {
               my @cmd = ($CMD{'nsrjb'}, '-w', '-S', $toc{$tape});
               print "$0: Withdrawing $tape from slot ", $toc{$tape}, "\n";
               my $ret_val = system(@cmd)/256;
               die "$0: @cmd returned $ret_val: $!\n" if ($ret_val != 0);
               $volumes_moved_to_loadport++;
       }
}








sub usage ($) {
       #
       # print a usage message, and exit with whatever value we were passed.
       #
       my $exit_val = $_[0];

       print STDERR "$0: usage:\n\t[--help] [ --verbose | --quiet ]\n";
       print STDERR "\t--file inputfile [--loadport-slots N]\n\n";
       print STDERR "where:\ninputfile contains a list of volume names, ";
       print STDERR "one per line.\n";
       print STDERR "--loadport-slots N can be used to specify a different\n";
       print STDERR "number of slots to use in the load port.  Default is 
14.\n";

       exit($exit_val);
}

--
Note: To sign off this list, send a "signoff networker" command via email
to listserv AT listmail.temple DOT edu or visit the list's Web site at
http://listmail.temple.edu/archives/networker.html where you can
also view and post messages to the list. Questions regarding this list
should be sent to stan AT temple DOT edu
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

<Prev in Thread] Current Thread [Next in Thread>