Showing posts with label Scripts. Show all posts
Showing posts with label Scripts. Show all posts

Friday, May 05, 2017

TSM Menu - Bash Shell Scripting

For years I have maintained a shell script on our jump server that was a menu for accessing all the TSM servers in our environment. It was a nice interface and great for noobies. It allowed for you to set your password and ID variables before the menu loaded so anyone could run the menu under their ID, then presented them with a nice menu to pick which TSM server they wished to access. It was nice and easy. The only problem was when servers were added or decommissioned. When that occurred I would then have to go out and revise the menu. This was a pain and soon to be more painful as we plan to add a lot more TSM servers in the near future. I remember seeing someone post that they had created a menu system based off of the dsm.sys file so I decided to write my own.

Before:

 ################################################################## 
 #                                                                # 
 #                        Infocrossing                            # 
 #                    UNIX ADMINISTRATION                         # 
 #                         TSM  MENU                              # 
 #                                                                # 
 ################################################################## 
                            Omaha                                   
     0)   ouax000                         1)  ouax001               
     2)   ouax002                         3)  ouax003               
     4)   OTSM01                          5)  OTSM02                
 ------------------------------------------------------------------ 
                           Phoenix                                  
     6)   puax001                         7)  puax002               
     8)   puax008                         9)  PTSM01                
     10)  PTSM02                         11)  PTSM20                
 ------------------------------------------------------------------ 
                           Singapore                                
     20)  SIN01ZZ                        99)  STSM01                
 ------------------------------------------------------------------ 
                            Germany                                 
     21)  DTSM01                         22)  DTSM02                
     23)  DTSM03                         24)  DTSM20                
 ------------------------------------------------------------------ 
                            Kings Mtn                               
     25)  CTSM01                         26)  CTSM20                
     27)  CTSM30                         28)  CTSM40                
 ------------------------------------------------------------------ 
                                                                    
                     X/x)  Cross Server                             
                                                                    
                     S/s)  Cmd Prompt                               
                                                                    
                   DD/dd)  Data Domain Admin                        
                                                                    
                     Q/q)  Return to Main Menu                      
                                                                    
                                                                    
     Selection:                                                    

 After (Notice servers listed here that were not in above menu):

 ################################################################
 #                                                              #
 #                         Infocrossing                         #
 #                       Recovery Services                      #
 #                           TSM  MENU                          #
 #                                                              #
 ################################################################
                                                                 
 1) C1IF            12) LABTSM            23) PTSM01             
 2) C1KDC2          13) LUAX001           24) PTSM02             
 3) CTSM01          14) LUAX002           25) PTSM20             
 4) CTSM20          15) LTSM01            26) PTSM25-Arch        
 5) CTSM30          16) NTSM01            27) SIN01ZZ            
 6) CTSM40          17) OUAX003           28) STSM01             
 7) CTSM46-Arch     18) OUAX000           29) Cross Server       
 8) DTSM01          19) OUAX001           30) Refresh Menu       
 9) DTSM02          20) OTSM01            31) Exit               
10) DTSM03          21) OTSM02                                   
11) DTSM20          22) PESTSM01                                   
                                                                 
 Please enter your choice:     

Ok, so the Before is more organized by region but as new servers come in I wanted the menu to update dynamically. So this new menu is built around the BASH shell's select menu function. The script pulls all the TSM server names from the dsm.sys and populates an array that the select statement reads and generates this menu. Make sure the variables the script declares work for you and your dsm.sys. My dsm.sys looks like this if I grep servername:

SERVERNAME         DTSM01          * Germany      LIB-MAN
SERVERNAME         DTSM02          * Germany             
SERVERNAME         DTSM03          * Germany             
SERVERNAME         DTSM20          * Germany      LIB-MAN
SERVERNAME         CTSM01          * Kings_Mnt    LIB-MAN
SERVERNAME         C1KDC2          * Kings_Mnt           
SERVERNAME         C1IF            * Kings_Mnt           
SERVERNAME         CTSM20          * Kings_Mnt           
SERVERNAME         CTSM30          * Kings_Mnt           
SERVERNAME         CTSM40          * Kings_Mnt           
SERVERNAME         CTSM46-Arch     * Kings_Mnt           
SERVERNAME         LUAX001         * Leonia       LIB-MAN
SERVERNAME         LUAX002         * Leonia              
SERVERNAME         LTSM01          * Leonia              
SERVERNAME         NTSM01          * Norcross     LIB-MAN
SERVERNAME         OUAX000         * Omaha        LIB-MAN
SERVERNAME         OUAX001         * Omaha               
SERVERNAME         OUAX003         * Omaha               
SErvername         OTSM01          * Omaha        LIB-MAN
SErvername         OTSM02          * Omaha               
SERVERNAME         PESTSM01        * PEST         LIB-MAN
SERVERNAME         PTSM01          * Tempe        LIB-MAN
SERVERNAME         PTSM02          * Tempe               
SERVERNAME         PTSM20          * Tempe               
SERVERNAME         PTSM25-Arch     * Tempe               
SERVERNAME         STSM01          * Singapore           
SERVERNAME         SIN01ZZ         * Singapore           

SERVERNAME         LABTSM                                

With the dsm.sys file formated this way I can use grep and awk to get specific data. This allows the script to build my menus according to my needs. Especially with the Cross Server sub menu that allows me to run a command across multiple servers at once. In the sub-menu it groups by distinct location which I placed in the servername line. Leave me a comment if you have any comments, questions, or suggestions.

See the script below:

#!/bin/bash
#set -x

### Set Color Variables ###

NORMAL=`echo "\033[0m"`
WHITE=`echo "\033[37m"` #Blue
YELLOW=`echo "\033[33m"` #yellow
GREEN=`echo "\033[32m"`
RED=`echo "\033[31m"`
PURPLE=`echo "\033[35m"`

##### Declare Variables & Arrays ############

prompt="
 Please enter your choice: "

TSM_SYS="/opt/tivoli/tsm/client/ba/bin/dsm.sys"
all_servers=(`cat $TSM_SYS | grep -i servername | awk -v OFS='\t' '{print $2}' | sort`)
xservers=(`cat $TSM_SYS | grep -i servername | awk -v OFS='\t' '{print $4}' | sort -u`)
Germany=(`cat $TSM_SYS | grep -i servername | grep -i germany |awk -v OFS='\t' '{print $2}'`)
Omaha=(`cat $TSM_SYS | grep -i servername | grep -i omaha |awk -v OFS='\t' '{print $2}'`)
Norcross=(`cat $TSM_SYS | grep -i servername | grep -i norcross |awk -v OFS='\t' '{print $2}'`)
Tempe=(`cat $TSM_SYS | grep -i servername | grep -i tempe |awk -v OFS='\t' '{print $2}'`)
PEST=(`cat $TSM_SYS | grep -i servername | grep -i pest |awk -v OFS='\t' '{print $2}'`)
Leonia=(`cat $TSM_SYS | grep -i servername | grep -i leonia |awk -v OFS='\t' '{print $2}'`)
Kings_Mnt=(`cat $TSM_SYS | grep -i servername | grep -i kings_mnt |awk -v OFS='\t' '{print $2}'| sort`)
Singapore=(`cat $TSM_SYS | grep -i servername | grep -i singapore |awk -v OFS='\t' '{print $2}'`)
lib_man=(`cat $TSM_SYS | grep -i servername | grep -i lib-man | awk -v OFS='\t' '{print $2}'`)

export COLUMNS=70
########################

######################
function clearlogin
######################
{
echo "Please wait while I clear all login information."|while read x;do for((i=0;i<${#x};i++));do echo -n "${x:$i:1}";sleep .03;done;echo;done;
unset TSMID
unset TSMPA
unset DDID
echo "."|while read x;do for((i=0;i<${#x};i++));do echo -n "${x:$i:1}";sleep .16;done;echo;done;
echo "."|while read x;do for((i=0;i<${#x};i++));do echo -n "${x:$i:1}";sleep .16;done;echo;done;
echo "Logins have been cleared! "|while read x;do for((i=0;i<${#x};i++));do echo -n "${x:$i:1}";sleep .03;done;echo;done;
sleep 1
}
######################
#  end clearlogin    #
######################

###############
#END MAIN-MENU#
###############

#########################
function tsmadmin
#########################
{
clear
if [ -z "${TSMID}" ]; then
echo ""
echo -e "$YELLOW Enter your TSM Admin ID: $GREEN \c"
read TSMID
echo ""
echo -e "$YELLOW Enter your TSM Admin Password: \c "
#stty -echo
read -s TSMPA
#stty $stty_orig
fi
clear
  tsm-menu
exit
}
####################
#  end tsmadmin    #
####################

#####################
function tsm-menu
#####################
{
all_done=0
export COLUMNS=70
while ((!all_done )); do
clear
echo -e "$WHITE ################################################################$NORMAL "
echo -e "$WHITE #                                                              #$NORMAL "
echo -e "$WHITE #                       $YELLOW  Infocrossing                        $WHITE #"
echo -e "$WHITE #                       Recovery Services                      #"
echo -e "$WHITE #                          $RED TSM  MENU                         $WHITE #"
echo -e "$WHITE #                                                              #$NORMAL "
echo -e "$WHITE ################################################################$NORMAL "
echo -e " "
length=`echo "$((${#all_servers[@]} + 4))"`
PS3="$prompt "
 select host in "${all_servers[@]}" "Cross Server" "Reset Login" "Refresh Menu" "Exit"; do
   if [ "$host" = "Exit" ]; then
      all_done=1; clear; exit
   elif [ "$host" = "Refresh Menu" ]; then
      all_done=1; tsm-menu
   elif [ "$host" = "Reset Login" ]; then
      all_done=1; clearlogin; tsmadmin
   elif [ "$host" = "Cross Server" ]; then
      all_done=1; xmenu
   elif [ "$REPLY" -gt "$length" ]; then
      echo ""
      echo "You chose option $REPLY which is invalid. Try again! "
      echo ""
   else
       clear
       echo -e "$GREEN "
       dsmadmc -id=$TSMID -pa=$TSMPA -servern="$host"
       all_done=1; tsm-menu
   fi
 done
done
}
##########################
# end function tsm-menu  #
##########################

#####################
function xmenu
#####################
{
all_done=0
export COLUMNS=50
while ((!all_done )); do
clear
echo -e "$WHITE ################################################################$NORMAL "
echo -e "$WHITE #                                                              #$NORMAL "
echo -e "$WHITE #                       $YELLOW  Infocrossing                        $WHITE #"
echo -e "$WHITE #                       Recovery Services                      #"
echo -e "$WHITE #            $RED     TSM Cross Server Command MENU               $WHITE # "
echo -e "$WHITE #                                                              #$NORMAL "
echo -e "$WHITE ################################################################$NORMAL "
echo -e " "
length=`echo "$((${#xservers[@]} + 4))"`
PS3="$prompt "
 select host in "${xservers[@]}" "All Servers" "Library Managers" "Refresh Menu" "Exit"; do
   if [ "$host" = "Exit" ]; then
      all_done=1; tsm-menu
   elif [ "$host" = "Refresh Menu" ]; then
      all_done=1; xmenu
   elif [ "$host" = "Library Managers" ]; then
       clear
       echo -e "$GREEN "
       xserver $TSMID $TSMPA lib_man
       all_done=1; xmenu
   elif [ "$host" = "All Servers" ]; then
       clear
       echo -e "$GREEN "
       xserver $TSMID $TSMPA all_servers
       all_done=1; xmenu
   elif [ "$REPLY" -gt "$length" ]; then
       echo ""
       echo "You chose option $REPLY which is invalid. Try again! "
       echo ""
   else
       clear
       echo -e "$GREEN "
       xserver $TSMID $TSMPA "$host"
       all_done=1; xmenu
   fi
 done
done
}
##########################
# end function xmenu     #
##########################


###################
function xserver
###################
{
  DC=$3
  echo -e " "
  echo -e "     $YELLOW Enter the command to process: $NORMAL \c"
  read CMD
  echo ""
    echo -e "     $YELLOW Do you want to save the data to a commadelimited csv file? (Yes or No [N])  $NORMAL \c"
    read ANSWER
    case $ANSWER
     in
      y|Y|YES|Yes|yes)
       echo ""
       echo -e "     $YELLOW Enter the file name to save the data: $NORMAL \c"
       read FILE
       echo ""
       touch $FILE
       cat /dev/null > $FILE
        eval varAlias=\${$DC[@]}
        for Server in ${varAlias[@]}
        do
         echo ""
          echo -e "Processing TSM server $Server "
          echo ""
          dsmadmc -id=$1 -pa=$2 -dataonly=yes -commadelimited -servern=$Server $CMD | grep -v ANR | grep -v ANS >> $FILE
         echo ""
        done
       xmenu
      ;;
      n|N|*)
       echo ""
        eval varAlias=\${$DC[@]}
        for Server in ${varAlias[@]}
        do
         echo ""
          echo -e "Processing TSM server $Server "
          echo ""
          dsmadmc -id=$1 -pa=$2 -dataonly=yes -servern=$Server $CMD
         echo ""
        done
        sleep 2
       xmenu
      ;;
      *)
       echo ""
        eval varAlias=\${$DC[@]}
        for Server in ${varAlias[@]}
        do
         echo ""
          echo -e "Processing TSM server $Server "
          echo ""
          dsmadmc -id=$1 -pa=$2 -dataonly=yes -servern=$Server $CMD
         echo ""
        done
        sleep 2
       xmenu
      ;;
    esac
}
########################
# end xserver function #
########################
clear
echo -e "$GREEN"
echo "Please Wait Loading Menu....."|while read x;do for((i=0;i<${#x};i++));do echo -n "${x:$i:1}";sleep .03;done;echo;done;
sleep 2

tsmadmin


                                   

Tuesday, March 24, 2015

A Better Q MOUNT?

I was playing around with my QDRV script which I feel gives a better showing than Q DRIVE and realized that I could technically produce a better Q MOUNT display than the built in TSM command provides. FYI - Unlike the Q MOUNT command my QMNT script shows the device definition for the current DRIVE_OWNER, so a storage agent or library client.  I have provided both my scripts for you, let me know what you think. Suggestions are welcome.

QDRV Script

select cast((library_name)as char(15)) as LIBRARY_NAME, -
cast((DRIVE_NAME)as char(16)) as DRIVE_NAME, -
cast((drive_state)as char(10)) as DRIVE_STATE, -
cast((volume_name)as char(8)) as VOL_NAME, cast((online)as char(10)) as ONLINE, -
cast((ALLOCATED_TO)as char(20)) as DRV_OWNER from drives order by library_name, drive_name







QDRV Macro

DEFINE SCRIPT  QDRV DESC="Show tape drive status"
UPDATE SCRIPT  QDRV "select cast((library_name)as char(15)) as LIBRARY_NAME, -"
UPDATE SCRIPT  QDRV "cast((DRIVE_NAME)as char(16)) as DRIVE_NAME, -"
UPDATE SCRIPT  QDRV "cast((drive_state)as char(10)) as DRIVE_STATE, -"
UPDATE SCRIPT  QDRV "cast((volume_name)as char(8)) as VOL_NAME, cast((online)as char(10)) as ONLINE, -"
UPDATE SCRIPT  QDRV "cast((ALLOCATED_TO)as char(20)) as DRV_OWNER from drives order by library_name, drive_name"





QMNT Script

select varchar(a.library_name,15) as LIB_NAME, -
cast((a.DRIVE_NAME)as char(16)) as DRIVE_NAME, -
cast((a.drive_state)as char(10)) as DRIVE_STATE, -
cast((a.volume_name)as char(8)) as VOL_NAME, -
varchar(b.device,12) as device, cast((a.online)as char(10)) as ONLINE, -
cast((a.ALLOCATED_TO)as char(20)) as DRV_OWNER from drives a, paths b -
where a.library_name=b.library_name and a.drive_name=b.destination_name -
and b.source_name=a.ALLOCATED_TO order by a.drive_name



QMNT Macro

DEFINE SCRIPT  QMNT DESC="Show tape mount status"
UPDATE SCRIPT  QMNT "select varchar(a.library_name,15) as LIB_NAME, -"
UPDATE SCRIPT  QMNT "cast((a.DRIVE_NAME)as char(16)) as DRIVE_NAME, -"
UPDATE SCRIPT  QMNT "cast((a.drive_state)as char(10)) as DRIVE_STATE, -"
UPDATE SCRIPT  QMNT "cast((a.volume_name)as char(8)) as VOL_NAME, -"
UPDATE SCRIPT  QMNT "varchar(b.device,12) as device, cast((a.online)as char(10)) as ONLINE, -"
UPDATE SCRIPT  QMNT "cast((a.ALLOCATED_TO)as char(20)) as DRV_OWNER from drives a, paths b -"
UPDATE SCRIPT  QMNT "where a.library_name=b.library_name and a.drive_name=b.destination_name -"
UPDATE SCRIPT  QMNT "and b.source_name=a.ALLOCATED_TO order by a.drive_name"

Thursday, June 23, 2011

What Problem? It's Working As Designed!

When upgrading from TSM 5.x to 6.x you have probably found that your select queries don't return in table format but in list format. You ask yourself, "WTH is going on here?" First off don't complain to IBM, it's "working as designed." You see with the change of the TSM DB to DB2 many of table column widths have changed. To have your select statements return in table format IBM states that you should use the CAST function on certain (if not all) columns. Otherwise, the best alternative is to save the results in commadelimited format and open the data in Excel. Here's the APAR??? that states it's not a problem. To quote Lady Gaga, TSM 6.x was "Born This Way!"

NOTE: Is it me or does IBM's last example leave one scratching their head wondering how using cast helped???

Tuesday, June 14, 2011

Drive Matching

While working with a VTL I realized how much I hated matching drive definitions on a LAN-Free client or remote library client and decided to do something about it. So after searching the web and finding a helpful script to pull rmt and serial numbers from the tape drives discovered on the LAN-Free or Lib-Client I worked it into an AIX shell script that will match the drives rmt with the correct drive definition on the library manager. The key to this working is to have the library manager listed in the lib-clients dsm.sys and to define the following TSM script on the library manager.


-=-=-=-=-=-=-TSM Server Script-=-=-=-=-=-=-=-


def script drive_match desc="This script is used by a shell script to match drives to rmts to help create DEFINE PATH statements"
upd script drive_match "select 'define path $1 ' || drive_name || ' srct=server destt=drive libr=' || library_name || ' device=/dev/$2 -"
upd script drive_match " online=yes' from drives where DRIVE_SERIAL='$3' "


-=-=-=-=-=-=-UNIX Shell Script-=-=-=-=-=-=-=-


#!/bin/ksh
ID=`cat /home/tsmadmin/VARS/ADSMID`
PA=`cat /home/tsmadmin/VARS/ADSMPA`
touch ./drv_match.mac
cat /dev/null > ./drv_match.mac
clear
echo "This script will build the DEFINE PATH statements for a server"
echo ""
echo "Enter the Library Manager Name: \c"
read SERV
echo ""
echo "What is the TSM server name these paths are going to be generated for: \c"
read TSMSRV
echo ""
lsdev |grep fscsi | while read FSCS rest
 do
   TAPES=$(lsdev -p $FSCS | grep rmt | grep -v ALT |cut -f1 -d" ")
     for TAPE in $TAPES
       do
         SERIAL=$(lscfg -vl $TAPE | grep Serial | awk -F"." '{printf "%d", $NF}')
         FCS=$(echo $FSCS | sed 's/fscsi/fcs/')
         dsmadmc -id=$ID -pa=$PA -dataonly=yes -commadelimited -servern=$SERV run drive_match $TSMSRV $TAPE $SERIAL | grep -v ANR >> ./drv_match.mac
        done
 done
cat ./drv_match.mac


-=-=-=-=-End Script-=-=-=-=-=-

You'll notice I save the output as a macro so it can be reviewed before executed. If you'd like to run the macro automatically then just add a dsmadmc line at the end.

The following is some sample output:


define path tsm8 VTL3_00332 srct=server destt=drive libr=VTL3 device=/dev/rmt88 online=yes
define path tsm8 VTL3_00336 srct=server destt=drive libr=VTL3 device=/dev/rmt89 online=yes
define path tsm8 VTL3_00340 srct=server destt=drive libr=VTL3 device=/dev/rmt90 online=yes
define path tsm8 VTL4_00444 srct=server destt=drive libr=VTL4 device=/dev/rmt91 online=yes

Thursday, May 26, 2011

Get Device Info From AIX

I needed to gather the serial numbers by device (rmt) in AIX for our VTL, and the grep command in AIX is not as functional as my Linux box at home, so the -A and -B options are not available. Those two flags allow you to grab X lines before and after the grep'ed expression which is really handy when running lscfg -vp. Here's a grep command to gather just the rmt(s) with their serial and WWN. If you need to change the number of lines just change the a (after) and b (before) value, and s is what is "grep'ed".

lscfg -vp | awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=1 a=5 s="rmt"

Wednesday, May 18, 2011

Getting TSM Script Info

So you want to query a script and see what it executes but don't like the standard Q SCRIPT results? Don't forget about the FORMAT= options available. Most people know FORMAT=DETAIL but with the Q SCRIPT command there are two additional formats. FORMAT=LINE and FORMAT=RAW. I like RAW but LINE is decent if you want to see the script by sequence.

UPDATE: As reader Erwann reminded me (I had long forgotten), there is also a F=MACRO option which will display the script in a form that can be run as a macro to define the script to another TSM server. If you issue Help Q SCRIPT it does not list the MACRO option, but it is valid and does work. So you could dump all your scripts to macro format and send it to an outfile. Then you could define them to an alternate TSM server (Q SCRIPT * OUTFILE=SCRIPTS.MAC F=Macro).


tsm: TSMLIBM>q script LIBR_INFO f=macro
DEFINE SCRIPT  LIBR_INFO DESC="Library path information"
UPDATE SCRIPT  LIBR_INFO "q libr $1"
UPDATE SCRIPT  LIBR_INFO "q libr $1 f=d"
UPDATE SCRIPT  LIBR_INFO "q path $1 srct=serv destt=libr f=d"
UPDATE SCRIPT  LIBR_INFO "q path * srct=serv destt=dr libr=$1 f=d"
UPDATE SCRIPT  LIBR_INFO "select library_name,library_type,library_serial from libraries where library_name ='$1'"
UPDATE SCRIPT  LIBR_INFO "select source_name,destination_name,library_name,device serial from paths where library_name='$1'"
UPDATE SCRIPT  LIBR_INFO "select drive_name,drive_serial,element,library_name from drives where library_name='$1'"


Here are the examples:

tsm: TSMLIBM>q script LIBR_INFO f=line   


Name           Line       Command                                                     
               Number     
----------     ------     ------------------------------------------------------------
LIBR_INFO      5          q libr $1                                                   
               10         q libr $1 f=d                                               
               15         q path $1 srct=serv destt=libr f=d                          
               20         q path * srct=serv destt=dr libr=$1 f=d                     
               25         select library_name,library_type,library_serial from        
                           libraries where library_name ='$1'                         
               30         select source_name,destination_name,library_name,device     
                           serial from paths where library_name='$1'                  
               35         select drive_name,drive_serial,element,library_name from    
                           drives where library_name='$1'             




tsm: TSMLIBM>q script LIBR_INFO f=raw
q libr $1
q libr $1 f=d
q path $1 srct=serv destt=libr f=d
q path * srct=serv destt=dr libr=$1 f=d
select library_name,library_type,library_serial from libraries where library_name ='$1'
select source_name,destination_name,library_name,device serial from paths where library_name='$1'
select drive_name,drive_serial,element,library_name from drives where library_name='$1'

Friday, April 29, 2011

Delete Old Filespaces

Been looking to do some cleanup and I wanted an easy way to do it. So...I wrote this script. I can take the list returned and either make it a macro or an internal TSM script. Sure I could build a shell script that processed a list with the TSM server_name, the node_name, and FSID but I thought I'd show how you can create a command out of SQL returned data.

select 'del filespace ' || node_name || ' ' || cast(FILESPACE_ID as char(3)) || ' type=backup nametype=fsid wait=yes' AS COMMAND from filespaces where cast((current_timestamp-backup_end)days as decimal)>90


Here is an example of the results from the script:



COMMAND
------------------------------------------------------------
del filespace NODE1 37  type=backup nametype=fsid wait=yes
del filespace NODE1 9   type=backup nametype=fsid wait=yes
del filespace NODE1 36  type=backup nametype=fsid wait=yes
del filespace NEO_1 32  type=backup nametype=fsid wait=yes
del filespace NEO_1 31  type=backup nametype=fsid wait=yes
del filespace NEO_1 23  type=backup nametype=fsid wait=yes
del filespace NEO_1 29  type=backup nametype=fsid wait=yes

Tuesday, January 11, 2011

Select X Days Back

As you all know I have been writing and rewriting scripts for my 6.x servers and have been experiencing interesting results when I use the timestampdiff option when determining how far back a script should look. So when running my summary report query I was getting inaccurate results when using the following script:

example 1:
select schedule_name, entity, start_time, end_time, timestampdiff(16, char(end_time-start_time)) || ' ' || timestampdiff(8, char(end_time-start_time)) || ':' || timestampdiff(8, char(end_time-start_time)) || ':' || substr(cast((end_time-start_time) as char(22)),13,2) AS ELAPSED_TIME, affected from summary where activity='STGPOOL BACKUP' and timestampdiff(8, char(current_timestamp-start_time))<=24


This script would not return all the STGPOOL BACKUP jobs from the summary table. Not sure why, but I have a couple ideas. So, I found that the following is easier to use and returned the correct results.


example 2:
select schedule_name, entity, start_time, end_time, timestampdiff(16, char(end_time-start_time)) || ' ' || timestampdiff(8, char(end_time-start_time)) || ':' || timestampdiff(8, char(end_time-start_time)) || ':' || substr(cast((end_time-start_time) as char(22)),13,2) AS ELAPSED_TIME, affected from summary where activity='STGPOOL BACKUP' and start_time>(CURRENT TIMESTAMP - 10 DAYS)


So whenever you would like to query X days back I suggest example 2 for ease of use.

Friday, November 26, 2010

Previously Unknown TSM SQL Feature

So while doing some script maintenance on a TSM server I came across this select statement and was shocked to see the CASE option in a select. I've used it in shell scripts but didn't think TSM allowed for it. Well it does and it works. Go figure!  (Runs on a TSM 5.3.5.2 server).


/* ---------------------------------------------*/
/* Script Name: eventx */
/* ---------------------------------------------*/
select -
schedule_name as "Schedule Name ", -
cast(substring(cast(scheduled_start as character(26)) from 12 for 8) as char(8)) as "Sched", -
node_name, -
cast(status as char(10)) as "Status", -
case -
when result=0 then ' 0-Succ' -
when result=4 then ' 4-SkFi' -
when result=8 then ' 8-Warn' -
when result=12 then '12-Errs' -
else cast(result as char(7)) -
end -
as "Result" -
from events -
where current_timestamp-scheduled_start<interval '24' hours -
and result<>0


I saw this and a whole new world opened up before my eyes! The possibilities!

Thursday, July 23, 2009

TSM Server Scripts Sleep Option

I have been frustrated with the lack of a sleep command with TSM scripts for a long time and just today a co-worker sent me this link which I think sums up how we've had to get around the it within TSM server scripts. The WAIT=YES option is only good for commands that allow it, and is not exactly what many of us need in certain situations. Since this document's modified date shows as 7-23-2009, I will take it that there is no respite from the issue with TSM 6.1. Basically IBM recommends you break the script in two and where you need the sleep you have the script schedule a onetime schedule of the secondary script for X number of minutes in the future. It does work. I've use this process on some scripts, but you'd think they would have added a sleep option by now. So I assume when it's absolutely needed many of you resort to a regular shell script to execute tasks, any alternate processes than that? I'd like to hear about it.

Thursday, February 07, 2008

REPOST: ACSLS Shared Library Checkout Script

For those with a shared ACSLS TSM library looking for a checkout script, I thought I would repost this so it would be easier to find.

Here is a basic rundown of what the script does.


  • On each library client DRM checks the tapes out with a REMOVE=NO option and creates a file with a list of the tapes.
  • On the library manager the tapes are checked back into the library.
  • The Library manager then checks every library clients DRM tapes out.
I know it sounds complex but it's not. It also is not perfect so you will need to keep on top of it, but don't worry it is not so bad that it's a headache. Some explaination is required also; In my environment I have 7 TSM instances and the firsts is just a library controller. This is why the following script starts at TSMSERV2 and stops the loop after TSMSERV7. Also note that the pipe sysmbol will not show up for some reason so you need to add it before the grep statements. Before you use the script you will also notice that it uses a TSM macro. Create the file by putting the following command into a macro called move_drmedia.mac.

move drm * so=dbb wherestate=mo tostate=vault remove=no CMD=&VOL CMDFILE=/usr/tivoli/tsm/client/ba/bin/Vol_List APPEND=YES WAIT=YES
move drm * so=dbb wherestate=vaultr tostate=onsiter


=-=-=-=-= Below Starts Checkout Script =-=-=-=-=

#!/bin/ksh

cd /usr/tivoli/tsm/client/ba/bin

OFFSITE=/usr/tivoli/tsm/client/ba/bin/OFFSITE/offsite.txt
RETRIEVE=/usr/tivoli/tsm/client/ba/bin/OFFSITE/retrieve.txt
ADSMID=`cat /usr/local/scripts/ADSMID`
ADSMPASS=`cat /usr/local/scripts/ADSMPASS`
I=2

cp $OFFSITE "$OFFSITE.BAK"
cp $RETRIEVE "$RETRIEVE.BAK"
cp /usr/tivoli/tsm/client/ba/bin/Vol_List /usr/tivoli/tsm/client/ba/bin/Vol_List.bak

cat /dev/null > /usr/tivoli/tsm/client/ba/bin/Vol_List

printf "Use this list to determine tapes that are to go offsite report any discrepancies to the Recovery Services Team.\n\n" > $OFFSITE
printf " \n\n" >> $OFFSITE
printf "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n" >> $OFFSITE
printf " Tapes to be sent offsite\n\n" >> $OFFSITE
printf " Current as of: `date`\n\n" >> $OFFSITE
printf "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n" >> $OFFSITE

printf "Use this list to determine tapes that are to come back onsite from Iron Mountain for reuse. Report any discrepancies to the Recovery Service Team.\n\n" > $RETRIEVE
printf " \n\n" >> $RETRIEVE
printf "********************************************************\n\n" >> $RETRIEVE
printf " Tapes to be brought back onsite from Iron Mountain\n" >> $RETRIEVE
printf " and placed back into TSM library for scratch.\n\n" >> $RETRIEVE
printf " Current as of: `date`\n\n" >> $RETRIEVE
printf "********************************************************\n\n" >> $RETRIEVE

while [ $I -lt 8 ]
do
S=TSMSERV-$I

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=$S -dataonly=yes "select volume_name from drmedia where state='MOUNTABLE' " grep L[0-3] >> $OFFSITE

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=$S -dataonly=yes "select volume_name from drmedia where state='VAULTRETRIEVE' " grep L[0-3] >> $RETRIEVE

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=$S 'macro move_drmedia.mac'

sleep 120

I=$(( $I + 1 ))
done

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=TSMSERV-1 'CHECKIN LIBVOL TSMLIB search=yes stat=private checklabel=no vollist=FILE:/usr/tivoli/tsm/client/ba/bin/Vol_List'

sleep 180

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=TSMSERV-1 'CHECKOUT LIBVOL TSMLIB vollist=FILE:/usr/tivoli/tsm/client/ba/bin/Vol_List'

mail -s "TDC Daily Tape Checkout" $HN tape_rpt < $OFFSITE

mail -s "TDC Daily Tape Return" $HN tape_rpt < $RETRIEVE

Saturday, October 27, 2007

ACSLS Shared Library DRM Checkout

I was recently asked by a reader if I would show them how I do the checkout of my DRM tapes in an shared ACSLS library. If you are not aware, ACSLS does not really support true DRM checkout within a shared library environment. Unfortunately, what occurs when you run the checkout is that ACSLS tries to check the tapes out one at a time; prompting for a request response before checking out the next tape. I found this out when we implemented our STK L5510 library and the checkout process was broken. So I went searching for some kind of answer to the situation and found APAR IC45537 which states the problem has been known since March of 2005. IBM has not resolved the issue within TSM but has relied on a local fix to resolve this issue. So I decided to post the script I created here to help those people out who have an ACSLS library and are looking to share it between multiple TSM instances and don't want to have to deal with Gresham's software.

Here is a basic rundown of what the script does.



  • On each library client DRM checks the tapes out with a REMOVE=NO option and creates a file with a list of the tapes.
  • On the library manager the tapes are checked back into the library.
  • The Library manager then checks every library clients DRM tapes out.
I know it sounds complex but it's not. It also is not perfect so you will need to keep on top of it, but don't worry it is not so bad that it's a headache. Some explaination is required also; In my environment I have 7 TSM instances and the firsts is just a library controller. This is why the following script starts at TSMSERV2 and stops the loop after TSMSERV7. Also note that the pipe sysmbol will not show up for some reason so you need to add it before the grep statements. Before you use the script you will also notice that it uses a TSM macro. Create the file by putting the following command into a macro called move_drmedia.mac.

move drm * so=dbb wherestate=mo tostate=vault remove=no CMD=&VOL CMDFILE=/usr/tivoli/tsm/client/ba/bin/Vol_List APPEND=YES WAIT=YES
move drm * so=dbb wherestate=vaultr tostate=onsiter


=-=-=-=-= Below Starts Checkout Script =-=-=-=-=

#!/bin/ksh

cd /usr/tivoli/tsm/client/ba/bin

OFFSITE=/usr/tivoli/tsm/client/ba/bin/OFFSITE/offsite.txt
RETRIEVE=/usr/tivoli/tsm/client/ba/bin/OFFSITE/retrieve.txt
ADSMID=`cat /usr/local/scripts/ADSMID`
ADSMPASS=`cat /usr/local/scripts/ADSMPASS`
I=2

cp $OFFSITE "$OFFSITE.BAK"
cp $RETRIEVE "$RETRIEVE.BAK"
cp /usr/tivoli/tsm/client/ba/bin/Vol_List /usr/tivoli/tsm/client/ba/bin/Vol_List.bak

cat /dev/null > /usr/tivoli/tsm/client/ba/bin/Vol_List

printf "Use this list to determine tapes that are to go offsite report any discrepancies to the Recovery Services Team.\n\n" > $OFFSITE
printf " \n\n" >> $OFFSITE
printf "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n" >> $OFFSITE
printf " Tapes to be sent offsite\n\n" >> $OFFSITE
printf " Current as of: `date`\n\n" >> $OFFSITE
printf "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n" >> $OFFSITE

printf "Use this list to determine tapes that are to come back onsite from Iron Mountain for reuse. Report any discrepancies to the Recovery Service Team.\n\n" > $RETRIEVE
printf " \n\n" >> $RETRIEVE
printf "********************************************************\n\n" >> $RETRIEVE
printf " Tapes to be brought back onsite from Iron Mountain\n" >> $RETRIEVE
printf " and placed back into TSM library for scratch.\n\n" >> $RETRIEVE
printf " Current as of: `date`\n\n" >> $RETRIEVE
printf "********************************************************\n\n" >> $RETRIEVE

while [ $I -lt 8 ]
do
S=TSMSERV-$I

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=$S -dataonly=yes "select volume_name from drmedia where state='MOUNTABLE' " grep L[0-3] >> $OFFSITE

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=$S -dataonly=yes "select volume_name from drmedia where state='VAULTRETRIEVE' " grep L[0-3] >> $RETRIEVE

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=$S 'macro move_drmedia.mac'

sleep 120

I=$(( $I + 1 ))
done

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=TSMSERV-1 'CHECKIN LIBVOL TSMLIB search=yes stat=private checklabel=no vollist=FILE:/usr/tivoli/tsm/client/ba/bin/Vol_List'

sleep 180

dsmadmc -id=$ADSMID -password=$ADSMPASS -servername=TSMSERV-1 'CHECKOUT LIBVOL TSMLIB vollist=FILE:/usr/tivoli/tsm/client/ba/bin/Vol_List'

mail -s "TDC Daily Tape Checkout" $HN tape_rpt < $OFFSITE

mail -s "TDC Daily Tape Return" $HN tape_rpt < $RETRIEVE