#!/usr/local/bin/rxx /* daily.tape (c) copyright 1995, Paul Zarnowski and Cornell University (see "Legal Information", below) Look for bad tapes, insufficient free tapes, etc. Launch via 'cronrexx'. Pre-req's: adsmadm - external rexx function Make sure you set the parameters, below. Author Information: Paul Zarnowski Cornell Information Technologies Ithaca, NY 14853-2601 psz1@cornell.edu Update History: 9-Oct-95 psz1: Initial version */ mailto="adsm-maint" LOGDIR='/u/adsm-mon/log/tapelog' BINDIR='/u/adsm-mon/bin' call putenv('REXXPATH='BINDIR':'getenv(REXXPATH)) /* Parameters */ mountlim = 300 /* Flag if mounted more than this many times */ writepass = 9 /* Flag if > this many write passes */ file = "/tmp/adsm.daily.tape.query" G. = "" GVTARGET. = 6 /* Target # of good volumes in storage pool */ GVTARGET.BKP$TAP = 6 GVTARGET.ARC$TAP$CSR = 2 GVTARGET.TEST$TAP = 1 AVAILTARGET. = 5 /* Target free space (GB) in storage pool */ AVAILTARGET.BKP$TAP = 10 AVAILTARGET.ARC$TAP$CSR = 5 AVAILTARGET.TEST$TAP = 1 G.$WRERROR = 0 /* Flag if greater than this many write errors on a volume */ G.$RDERROR = 0 /* Flag if greater than this many read errors on a volume */ /* Eventually, we should enhance this code to obtain this est from ADSM. */ CAP.8MM = 5120 /* Capacity of 8MM volume */ /* End of Parameters */ "/bin/test -f" file if (rc=0) then "rm" file call popen('adsmadm query volume devclass=8mm format=detailed') do while (queued() > 0) pull x . if (x = "ANS5101I") then leave end GV. = 0 /* # of good volumes in storage pool */ GVV. = "" /* list of good volumes in storage pool */ BV. = 0 /* # of bad volumes in storage pool */ BVV. = "" /* list of bad volumes in storage pool */ AVAIL. = 0 /* available MB in storage pool */ stglist = "" W. = '' volume = 'oops' do while (queued() > 0) parse pull tag ":" data 1 parse value tag with x . if (x = "ANS5103I") then iterate select when (tag="") then nop when (tag="Volume Name") then do bad = 0; capacity = 0; util = 0; devclass = 8MM volume = data end when (tag="Storage Pool Name") then do stg = strip(translate(data,'$','.')) if (wordpos(stg,stglist)=0) then stglist = stglist stg end when (tag="Device Class Name") then do devclass = strip(data) end when (tag="Estimated Capacity (MB)") then do capacity = nocomma(data)/1000 end when (tag="%Util") then do util = data/100 end when (tag="Volume Status") then do if (data <> "Empty") & (data <> "Filling") then bad = 1 if (data = "Empty") then capacity = nocomma(CAP.devclass)/1000 end when (tag="Access") then do if (data <> "Read/Write") then bad = 1 end when (tag="Pct. Reclaimable Space") then nop when (tag="Scratch Volume?") then nop when (tag="In Error State?") then do if (data <> "No") then do W.error = W.error volume bad = 1 end end when (tag="Number of Writable Sides") then nop when (tag="Number of Times Mounted") then do nmounts = nocomma(data) if (nmounts > mountlim) then do W.mount = W.mount volume nmounts bad = 1 end end when (tag="Write Pass Number") then do npass = nocomma(data) if (npass > writepass) then W.write = W.write volume npass end when (tag="Approx. Date Last Written") then nop when (tag="Approx. Date Last Read") then nop when (tag="Number of Write Errors") then do nerr = nocomma(data) if (nerr > G.$WRERROR) then do W.wrerr = W.wrerr volume nerr bad = 1 end end when (tag="Number of Read Errors") then do nerr = nocomma(data) if (nerr > G.$RDERROR) then do W.rderr = W.rderr volume nerr bad = 1 end end when (tag="Last Update by (administrator)") then nop when (tag="Last Update Date/Time") then do if (bad) then do BV.stg = BV.stg + 1 BVV.stg = BVV.stg strip(volume) end else do GV.stg = GV.stg + 1 GVV.stg = GVV.stg strip(volume) AVAIL.stg = AVAIL.stg + ((1-util)*capacity) end end otherwise do call output "Unexpected output from QUERY VOLUME:" tag ":" data end end end if (W.error <> "") then do call output "WARNING: The following 8MM Tape Volumes are in ERROR STATE:" call volout W.error call output "" end If (W.mount <> "") then do call output "WARNING: The following 8MM Tape Volumes have been mounted >" , mountlim "times:" xx = W.mount do while (xx <> "") parse value xx with v n xx call output " "v "-" n "mounts" end call output "" end If (W.write <> "") then do call output "WARNING: The following 8mm Tape Volumes have >" writepass , "Write Passes:" xx = W.write do while (xx <> "") parse value xx with v n xx call output " "v "- Write Pass" n end call output "" end if (W.wrerr <> "") then do call output "WARNING: The following 8mm Tape Volumes have >" , G.$WRERROR "Write Errors:" xx = W.wrerr do while (xx <> "") parse value xx with v n xx call output " "v "-" n "Write Error(s)" end call output "" end if (W.rderr <> "") then do call output "WARNING: The following 8mm Tape Volumes have >" , G.$RDERROR "Read Errors:" xx = W.rderr do while (xx <> "") parse value xx with v n xx call output " "v "-" n "Read Error(s)" end call output "" end ss = stglist do while (ss <> "") parse value ss with s ss sx = translate(s,'.','$') if (GV.s < GVtarget.s) then do call output "WARNING: Only" GV.s "good volumes are left in Storage" , "Pool" sx"." if (GVV.s <> "") then call volout GVV.s call output " The target for this Storage Pool is" GVtarget.s , "good volumes." call output " There are" BV.s "other volumes in this Storage" , "Pool." if (BVV.s <> "") then do call volout BVV.s call output " (these are full, r/o, failing or old)." end call output " " end end ss = stglist do while (ss <> "") parse value ss with s ss sx = translate(s,'.','$') if (AVAIL.s < AVAILTARGET.s) then do a = format(AVAIL.s,,1) call output "WARNING: Only" a "GB of usable space" , "remains in Storage Pool" sx"." call output " The target for this Storage Pool is" , AVAILTARGET.s "GB of free space." call output " "GV.s "Empty or Filling volume(s);" , BV.s "other volume(s)." call output " " end end if (G.init = 1) then do call lineout file "/bin/cat" file "| mail -s ""ADSM Tape Problem(s)""" mailto "/bin/cp" file LOGDIR"/"date('S') "/bin/rm" file end else do "/bin/touch" LOGDIR"/"date('S') end exit output: procedure expose file G. parse arg line if G.init <> 1 then do G.init = 1 call lineout file, "Output from ADSM maintenance script:" , """daily.tape""." call lineout file, "" end call lineout file, line return nocomma: procedure parse arg x . do forever parse value x with a "," b if (b = "") then return x x = a||b end volout: parse arg vv do while (vv <> "") v. = "" parse value vv with v.1 v.2 v.3 v.4 v.5 v.6 v.7 v.8 vv xx = v.1 do i = 2 to 8 if v.i <> "" then xx = xx"," v.i end xx = "("xx")" call output " "xx end return /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Legal Information: Although copyrighted, this software is being licensed to you for your use free of charge. However, ownership of and interest in this software shall remain with the author. Use and distribution of this software is governed by the following terms. This software is owned by the author and contains valuable and proprietary information of the author. If you violate any part of this agreement, your right to use this software terminates automatically. In the event of termination of this agreement, you must destroy all copies of this software and derivatives of this software in your possession and cease distributing the same. This software is being licensed to you as provided by the terms of this agreement. You may: 1. Use this software on as many computers as you want at any given time. 2. Make as many backup copies of this software as you want. 3. Alter the software in any manner you see fit FOR YOUR OWN PERSONAL USE. Such altered versions should not be distributed. The creation of such derivatives shall not diminish the author's title to this software. 4. Terminate this agreement at any time by destroying all copies of this software and derivatives of this software and cease distributing the same. You may not: 1. Create any derivative works from this software for distribution. 2. Re-distribute this software for commercial (for-profit) purposes. Contact the author at the address within this document if you wish to distribute this software for commercial usage, or if you have any questions about its redistribution. Disclaimer of warranty: In using this software, you understand and agree that this software is provided "as is" without warranty of any kind. The entire risk as to the results of and performance of using this software lies entirely with you, the user. The author does not make any warranties, either expressed or implied, including but not limited to implied warranties of merchantability and fitness for a particular purpose, with respect to this software. In no event shall the author be liable for any consequential, incidental, or special damages whatsoever arising out of the use or inability to use this software. */