dcorliss
asked on
Writing large file (2.4 GB) to a multi-tape file.
I have inherited a UNIX script that writes a file to a single tape. The file has become so large (2.4 GB) that it will not fit on a single tape. I need to alter the script to accomodate the use of multi-tape. I am looking for examples of UNIX scripts that allow for the writing of a large file to a multi-tape file.
Just a reminder:
cpio, GUN tar, Solaris ufsdump can handle multi volumes.
The native unix tar is OS depandent.
cpio, GUN tar, Solaris ufsdump can handle multi volumes.
The native unix tar is OS depandent.
What kind of Unix do you have?
If AIX, the backup utiliy supports multi volume tapes.
If AIX, the backup utiliy supports multi volume tapes.
ASKER
I thank you for your comments but I have a specially written script (running on Solaris 2.8) that does data manipulation. How can I get a copy of the script to you for study?
ASKER
There's a section (exit) written to blow up if the tape count is greater then 1. It is here I need to handle going to another tape. I assume I have to close the current tape volume and open another but this I do not know how to do.
ASKER
Script:
#!/usr/bin/ksh
#
# set DEBUG=echo to run in DEBUG mode, which will not access the tape drive
#
DEBUG=
#DEBUG=echo
VALID_NUM_PARMS=8
VALID_NUM_PARMS_OPT=9
USAGE="write_tape.sh source_dir vol_ser_alpha first_vol_ser_num file_name_base lrecl blksize rewind|norewind|eject 3480|3490|3490E [vb_data_write.pl ]"
if [ $# -ne $VALID_NUM_PARMS ]
then
if [ $# -ne $VALID_NUM_PARMS_OPT ]
then
echo "Invalid number of parameters ($#) - Expecting $VALID_NUM_PARMS or $VALID_NUM_PARMS_OPT"
echo $USAGE
exit -1
fi
fi
# Accept parameters
SRC_DIR=$1;shift
VOL_SER_ALPHA=$1;shift
VOL_SER_NUM_FIRST=$1;shift
FILE_NAME_BASE=$1;shift
LRECL=$1;shift
BLKSIZE=$1;shift
EOF_OPTION=$1;shift
CART_TYPE=$1;shift
#!!TAPE_OPTIONS_DATA="conv =block,ebc dic obs=$BLKSIZE cbs=$LRECL "
#!!TAPE_OPTIONS_DATA="$TAP E_OPTIONS_ CONVERT obs=$BLKSIZE cbs=$LRECL "
#Default record format: F (Fixed Block)
RECFM=F
# Optional Data Conversion parameter
if [ $# -ge 1 ]
then
DATA_FILTER_PARM=$1
if [ "noconvert" = "$DATA_FILTER_PARM" ]
then
: # OK
shift
NO_CONVERT_CHAR_SET=1
FILTER_DATA=0
TAPE_OPTIONS_CONVERT=" "
else
# See if DATA_FILTER_PARM is vb_data_write.pl
if [ "vb_data_write.pl" = "$DATA_FILTER_PARM" ]
then
shift
NO_CONVERT_CHAR_SET=1
#record format: V (Variable Block)
RECFM=V
FILTER_DATA=1
TAPE_OPTIONS_CONVERT=" "
DATA_OPTIONS_CONVERT=$*
if [ -n "$DATA_OPTIONS_CONVERT" ]
then
echo "Data filter options found ==>$DATA_OPTIONS_CONVERT<= =. Ignring."
fi
else
echo "Invalid noconvert option ==>$NO_CONVERT_CHAR_SET<== . Valid: noconvert or vb_data_write.pl"
echo $USAGE
exit -1
fi
fi
else
NO_CONVERT_CHAR_SET=0
FILTER_DATA=0
TAPE_OPTIONS_CONVERT="conv =block,ebc dic "
fi
# Validate Destination Directory
if [ -d $SRC_DIR ]
then
if [ -w $SRC_DIR ]
then
: # Cool. Can write to directory.
else
echo $LOGNAME does not have write authority to directory $SRC_DIR
echo exiting
exit -1
fi
else
echo Input Directory $SRC_DIR is not a directory
echo exiting
exit -1
fi
# Validate Destination Directory
if [ -f ${SRC_DIR}/${FILE_NAME_BAS E} ]
then
: # Cool. File exisits
else
echo Input File ${SRC_DIR}/${FILE_NAME_BAS E} not found
echo exiting
exit -1
fi
if [ "rewind" = "$EOF_OPTION" -o "eject" = "$EOF_OPTION" -o "norewind" = "$EOF_OPTION" ]
then
: # OK
else
echo "Invalid end of tape option ==>$EOF_OPTION<==. Valid: rewind|norewind|eject"
echo $USAGE
exit -1
fi
if [ "3480" = "$CART_TYPE" -o "3490" = "$CART_TYPE" -o "3490E" = "$CART_TYPE" ]
then
: # OK
if [ "3480" = "$CART_TYPE" ]
then
CART_CAPACITY=419429996
else
if [ "3490" = "$CART_TYPE" ]
then
CART_CAPACITY=838860396
else
# !! CART_CAPACITY=2576979974
# !! Future: Use info from ../log/tape_size_hist.txt
CART_CAPACITY=2722230600
fi
fi
else
echo "Invalid tape cartridge option ==>$CART_TYPE<==. \
Valid: 3480|3490|3490E"
echo $USAGE
exit -1
fi
# Validate numeric parms
let TEST_NUM=$VOL_SER_NUM_FIRS T+1
if [ $? -ne 0 ]
then
echo "Non-numeric Vol Ser Numeric portion ==>$VOL_SER_NUM_FIRST<==."
echo $USAGE
exit -1
fi
let TEST_NUM=$LRECL+1
if [ $? -ne 0 ]
then
echo "Logical Record Length is non-numeric ==>$LRECL<==."
echo $USAGE
exit -1
fi
let TEST_NUM=$BLKSIZE+1
if [ $? -ne 0 ]
then
echo "Block size is non-numeric ==>$BLKSIZE<==."
echo $USAGE
exit -1
fi
set -x # !! DEBUG - comment out this line when all is cool.
# Calc various info
# Determine # of tapes
FILE_SIZE=`stat --dereference --format='%s' ${SRC_DIR}/${FILE_NAME_BAS E}`
LF_COUNT_ALL=`wc -l ${SRC_DIR}/${FILE_NAME_BAS E}`
LF_COUNT=`echo $LF_COUNT_ALL | tr -s ' ' | cut -d' ' -f1 | tr -d ' '`
if [ -z "$LF_COUNT" ]
then
LF_COUNT=`echo $LF_COUNT_ALL | tr -s ' ' | cut -d' ' -f2 | tr -d ' '`
fi
# The following ugly code attempts to round up the TTL_BLOCKS to the next
# integer, since the korn shell uses integer arithmetic.
let MULT_FACTOR=100000
let TTL_BLOCKS_MULT=\(\($FILE_ SIZE-$LF_C OUNT\)*$MU LT_FACTOR\ )/$BLKSIZE
# Use mod operator to see if need to round
let REMAINDER=$TTL_BLOCKS_MULT %$MULT_FAC TOR
if [ $REMAINDER -ne 0 ]
then
let TTL_BLOCKS=\(\($FILE_SIZE- $LF_COUNT\ )/$BLKSIZE \)+1
else
let TTL_BLOCKS=\($FILE_SIZE-$L F_COUNT\)/ $BLKSIZE
fi
# This does not take into account header/trailer files on each tape,
# nor blksize%cart_capacity
let NUM_TAPES=$FILE_SIZE/$CART _CAPACITY+ 1
echo FILE_SIZE=$FILE_SIZE, TTL_BLOCKS=$TTL_BLOCKS, NUM_TAPES=$NUM_TAPES
echo LF_COUNT=$LF_COUNT
let VOL_SER_NUM_LAST=$VOL_SER_ NUM_FIRST+ $NUM_TAPES -1
# pad with zeros if needed
LEN_NUM_FIRST=`echo $VOL_SER_NUM_FIRST | wc -c | tr -d ' '`
LEN_NUM_LAST=`echo $VOL_SER_NUM_LAST | wc -c | tr -d ' '`
echo HEY LEN_NUM_FIRST=$LEN_NUM_FIR ST, LEN_NUM_LAST=$LEN_NUM_LAST
let LEN_DIFF=$LEN_NUM_FIRST-$L EN_NUM_LAS T
if [ $LEN_DIFF -gt 0 ]
then
VOL_SER_NUM_LAST=`echo "0000000" | cut -c1-$LEN_DIFF`$VOL_SER_NUM _LAST
fi
if [ $NUM_TAPES -eq 1 ]
then
TAPE_INFO=tape
TAPE_INFO2="tape is"
TAPE_INFO3="it"
else
TAPE_INFO=tapes
TAPE_INFO2="tapes are"
TAPE_INFO3="the first tape"
fi
if [ $NUM_TAPES -gt 10 ]
then
echo $0 cannot currently handle writing more than 10 tapes. Sorry.
echo Modify loop in $0 so that it pauses every 10 tapes for unmounting
echo written tapes, and mounting x \(up to 10\) blank tapes before going on.
exit -1
else
if [ $NUM_TAPES -gt 1 ]
then
echo $0 cannot currently handle writing more than 1 tape. Sorry.
echo Modify loop in $0 to figure out blocks per tape, and use
echo dd parms iseek=n and count=n to bust apart file.
exit -1
fi
echo Ensure $NUM_TAPES blank $TAPE_INFO2 in the tape library
echo and $TAPE_INFO3 is loaded
fi
echo Hit Enter to write $NUM_TAPES $TAPE_INFO from ${SRC_DIR}/${FILE_NAME_BAS E}
echo Vol Ser ${VOL_SER_ALPHA}${VOL_SER_ NUM_FIRST} to \
${VOL_SER_ALPHA}${VOL_SER_ NUM_LAST} blksize=$BLKSIZE \
and $EOF_OPTION last tape
read stuff
# Clobber log files
echo about to "> $SRC_DIR/${FILE_NAME_BASE} .out 2> $SRC_DIR/${FILE_NAME_BASE} .err"
> $SRC_DIR/${FILE_NAME_BASE} .out 2> $SRC_DIR/${FILE_NAME_BASE} .err
if [ -w $SRC_DIR/${FILE_NAME_BASE} .out -a -w $SRC_DIR/${FILE_NAME_BASE} .err ]
then
: # OK to write in this dir
else
echo Unable to write files in `pwd`
exit -1
fi
echo `date '+%D %T'` write_tape.sh going to write $NUM_TAPES $TAPE_INFO \
starting with VOL_SER=${VOL_SER_ALPHA}${ VOL_SER_NU M_FIRST}, \
last=${VOL_SER_ALPHA}${VOL _SER_NUM_L AST} \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out
echo `date '+%D %T'` Base File Name=$FILE_NAME_BASE, LRECL=$LRECL, \
Blocksize=$BLKSIZE \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out
CURR_TAPE=$VOL_SER_NUM_FIR ST
# 2: TAPE_OPTIONS="conv=ascii,u nblock ibs=$BLKSIZE cbs=$LRECL "
# 3: TAPE_OPTIONS="conv=ascii,u nblock ibs=$BLKSIZE "
# 4: TAPE_OPTIONS="conv=ascii ibs=$BLKSIZE cbs=$LRECL "
#!TAPE_OPTIONS_LABEL="conv =ebcdic,bl ock obs=$BLKSIZE cbs=80 "
TAPE_OPTIONS_LABEL="conv=b lock,ebcdi c cbs=80 "
#!TAPE_OPTIONS_DATA="conv= ebcdic,blo ck obs=$BLKSIZE cbs=$LRECL "
#!!TAPE_OPTIONS_DATA="conv =block,ebc dic obs=$BLKSIZE cbs=$LRECL "
TAPE_OPTIONS_DATA="$TAPE_O PTIONS_CON VERT obs=$BLKSIZE cbs=$LRECL "
time $DEBUG mt status >> ${FILE_NAME_BASE}.out 2>> ${FILE_NAME_BASE}.err
TAPES_WRITTEN=1
while [ $CURR_TAPE -le $VOL_SER_NUM_LAST ]
do
echo `date '+%D %T'` "working on Tape Vol Ser: ${VOL_SER_ALPHA}${CURR_TAP E}" \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out $SRC_DIR/${FILE_NAME_BASE} .err
##
# perl script to generate header file
# !! To do: Handle files spanning tapes
##
echo `date '+%D %T'` "Creating vol ser header for ${VOL_SER_ALPHA}${CURR_TAP E}" \
>> $SRC_DIR/${FILE_NAME_BASE} .out
$DEBUG write_vol_ser.pl ${VOL_SER_ALPHA}${VOL_SER_ NUM_FIRST} \
${VOL_SER_ALPHA}${CURR_TAP E} $FILE_NAME_BASE \
$LRECL $BLKSIZE $TAPES_WRITTEN $NUM_TAPES $RECFM > \
$SRC_DIR/${FILE_NAME_BASE} _${VOL_SER _ALPHA}${C URR_TAPE}_ 0
echo `date '+%D %T'` "Writing vol ser header for ${VOL_SER_ALPHA}${CURR_TAP E}" \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out $SRC_DIR/${FILE_NAME_BASE} .err
time $DEBUG /usr/bin/dd of=/dev/rmt/0n \
if=$SRC_DIR/${FILE_NAME_BA SE}_${VOL_ SER_ALPHA} ${CURR_TAP E}_0 \
$TAPE_OPTIONS_LABEL \
>> $SRC_DIR/${FILE_NAME_BASE} .out 2>> $SRC_DIR/${FILE_NAME_BASE} .err
time $DEBUG mt status \
>> $SRC_DIR/${FILE_NAME_BASE} .out 2>> $SRC_DIR/${FILE_NAME_BASE} .err
##
# Write data file
# !! To do: Handle files spanning tapes
##
echo `date '+%D %T'` "Writing data for ${VOL_SER_ALPHA}${CURR_TAP E}" \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out $SRC_DIR/${FILE_NAME_BASE} .err
echo `date '+%D %T'` "Options: $TAPE_OPTIONS_DATA " \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out $SRC_DIR/${FILE_NAME_BASE} .err
set -x # !! TEMP DEBUG
if [ $FILTER_DATA -eq 1 ]
then
# Use dd with no "if" parm, pipe from DATA_FILTER_PARM
time $DEBUG $DATA_FILTER_PARM blksize=$BLKSIZE \
$SRC_DIR/${FILE_NAME_BASE} \
2>> $SRC_DIR/${FILE_NAME_BASE} .err | \
/usr/bin/dd of=/dev/rmt/0n \
$TAPE_OPTIONS_DATA \
>> $SRC_DIR/${FILE_NAME_BASE} .out 2>> $SRC_DIR/${FILE_NAME_BASE} .err
RC_WRITE_DATA=$?
# Need to grep $SRC_DIR/${FILE_NAME_BASE} .err to see if
# $DATA_FILTER_PARM script had a
# error, since the dd program might have masked a
# bad RC
grep '^Error:' $SRC_DIR/${FILE_NAME_BASE} .err
if [ $? -eq 0 ]
then
# Found string - there was an error
RC_WRITE_DATA=123
fi
# Need to obtain blocks written if $DATA_FILTER_PARM is vb_data_write.pl
# since writing VB data means that we can't determine the number of
# blocks written by simply dividing file size by block size,
# since each record can be varying in length.
if [ "vb_data_write.pl" = "$DATA_FILTER_PARM" ]
then
if [ $NUM_TAPES -gt 1 ]
then
# Blow up for now
echo "write_tape.sh: I don't know how you got here 2, but you shouldn't have!"
exit -1
else
TTL_BLOCKS=`grep 'vb_data_write finished.* blocks written' $SRC_DIR/${FILE_NAME_BASE} .err | cut -f 9 -d'|'`
#echo "HEY: Just set TTL_BLOCKS to $TTL_BLOCKS "
#echo "HEY: TTL_BLOCKS=grep 'vb_data_write finished.* blocks written' $SRC_DIR/${FILE_NAME_BASE} .err | cut -f 9 -d'|'"
fi
fi
else
# Write directly to file
time $DEBUG /usr/bin/dd of=/dev/rmt/0n \
if=$SRC_DIR/${FILE_NAME_BA SE} \
$TAPE_OPTIONS_DATA \
>> $SRC_DIR/${FILE_NAME_BASE} .out 2>> $SRC_DIR/${FILE_NAME_BASE} .err
RC_WRITE_DATA=$?
fi
if [ $RC_WRITE_DATA -ne 0 ]
then
echo `date '+%D %T'` "Error $RC_WRITE_DATA Writing data " \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out $SRC_DIR/${FILE_NAME_BASE} .err
echo You may need to mt rewind this tape
exit -1
fi
set +x # !! TEMP DEBUG
time $DEBUG mt status \
>> $SRC_DIR/${FILE_NAME_BASE} .out 2>> $SRC_DIR/${FILE_NAME_BASE} .err
##
#
# perl script to generate trailer file
# !! To do: Handle files spanning tapes
#
##
if [ $NUM_TAPES -gt 1 ]
then
# Blow up for now
echo "write_tape.sh: I don't know how you got here, but you shouldn't have!"
exit -1
else
#let TTL_BLOCKS=$FILE_SIZE/$BLK SIZE
let CURR_BLOCKS=$TTL_BLOCKS
fi
echo `date '+%D %T'` "Creating vol ser trailer for ${VOL_SER_ALPHA}${CURR_TAP E}" \
>> $SRC_DIR/${FILE_NAME_BASE} .out
echo `date '+%D %T'` "HEY! CURR_TAPE==>$CURR_TAPE<==, NUM_TAPES==>$NUM_TAPES<==, TAPES_WRITTEN==>$TAPES_WRI TTEN<==" \
echo `date '+%D %T'` "HEY! CURR_BLOCKS==>$CURR_BLOCKS <==, TTL_BLOCKS==>$TTL_BLOCKS<= =, TAPES_WRITTEN==>$TAPES_WRI TTEN<==" \
>> $SRC_DIR/${FILE_NAME_BASE} .out
$DEBUG write_vol_ser.pl ${VOL_SER_ALPHA}${VOL_SER_ NUM_FIRST} \
${VOL_SER_ALPHA}${CURR_TAP E} $FILE_NAME_BASE \
$LRECL $BLKSIZE $TAPES_WRITTEN $NUM_TAPES $RECFM $CURR_BLOCKS > \
$SRC_DIR/${FILE_NAME_BASE} _${VOL_SER _ALPHA}${C URR_TAPE}_ 2
echo `date '+%D %T'` "Writing vol ser trailer for ${VOL_SER_ALPHA}${CURR_TAP E}" \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out $SRC_DIR/${FILE_NAME_BASE} .err
time $DEBUG /usr/bin/dd of=/dev/rmt/0n \
if=$SRC_DIR/${FILE_NAME_BA SE}_${VOL_ SER_ALPHA} ${CURR_TAP E}_2 \
$TAPE_OPTIONS_LABEL \
>> $SRC_DIR/${FILE_NAME_BASE} .out 2>> $SRC_DIR/${FILE_NAME_BASE} .err
time $DEBUG mt status \
>> $SRC_DIR/${FILE_NAME_BASE} .out 2>> $SRC_DIR/${FILE_NAME_BASE} .err
if [ $CURR_TAPE -eq $VOL_SER_NUM_LAST ]
then
# Last tape. Rewind or Eject to next tape
if [ "eject" = "$EOF_OPTION" ]
then
echo `date '+%D %T'` "Switching to next tape " \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out \
$SRC_DIR/${FILE_NAME_BASE} .err
time $DEBUG mt_swap_tape.sh swap \
>> $SRC_DIR/${FILE_NAME_BASE} .out \
2>> $SRC_DIR/${FILE_NAME_BASE} .err
else
if [ "rewind" = "$EOF_OPTION" ]
then
echo `date '+%D %T'` "Rewinding last tape " \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out \
$SRC_DIR/${FILE_NAME_BASE} .err
time $DEBUG mt rewind \
>> $SRC_DIR/${FILE_NAME_BASE} .out \
2>> $SRC_DIR/${FILE_NAME_BASE} .err
else
echo `date '+%D %T'` "Leaving last tape positioned at EOF" \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out \
$SRC_DIR/${FILE_NAME_BASE} .err
fi
fi
else
# !! To Do: Need to ensure not on last tape slot (10). If so,
# !! pause until tape magazine is reloaded with 10
# !! blank tapes.
# !! Look at /export/home/kabira/common /log/mt_sw ap_tape_in fo.txt
# !! to determine current tape slot in use.
echo `date '+%D %T'` "Switching to next tape " \
| tee -a $SRC_DIR/${FILE_NAME_BASE} .out \
$SRC_DIR/${FILE_NAME_BASE} .err
time $DEBUG mt_swap_tape.sh swap \
>> $SRC_DIR/${FILE_NAME_BASE} .out \
2>> $SRC_DIR/${FILE_NAME_BASE} .err
fi
echo `date '+%D %T'` " - End of Loop" \
>> $SRC_DIR/${FILE_NAME_BASE} .out
ps -f -p $$ \
>> $SRC_DIR/${FILE_NAME_BASE} .out
# Bump counters
let CURR_TAPE=$CURR_TAPE+1
let TAPES_WRITTEN=$TAPES_WRITT EN+1
# pad with zeros if needed
LEN_NUM_LAST=`echo $CURR_TAPE | wc -c | tr -d ' '`
echo HEY LEN_NUM_FIRST=$LEN_NUM_FIR ST, LEN_NUM_LAST=$LEN_NUM_LAST
let LEN_DIFF=$LEN_NUM_FIRST-$L EN_NUM_LAS T
if [ $LEN_DIFF -gt 0 ]
then
CURR_TAPE=`echo "0000000" | cut -c1-$LEN_DIFF`$CURR_TAPE
fi
echo HEY CURR_TAPE=$CURR_TAPE
done
exit 0
#!/usr/bin/ksh
#
# set DEBUG=echo to run in DEBUG mode, which will not access the tape drive
#
DEBUG=
#DEBUG=echo
VALID_NUM_PARMS=8
VALID_NUM_PARMS_OPT=9
USAGE="write_tape.sh source_dir vol_ser_alpha first_vol_ser_num file_name_base lrecl blksize rewind|norewind|eject 3480|3490|3490E [vb_data_write.pl ]"
if [ $# -ne $VALID_NUM_PARMS ]
then
if [ $# -ne $VALID_NUM_PARMS_OPT ]
then
echo "Invalid number of parameters ($#) - Expecting $VALID_NUM_PARMS or $VALID_NUM_PARMS_OPT"
echo $USAGE
exit -1
fi
fi
# Accept parameters
SRC_DIR=$1;shift
VOL_SER_ALPHA=$1;shift
VOL_SER_NUM_FIRST=$1;shift
FILE_NAME_BASE=$1;shift
LRECL=$1;shift
BLKSIZE=$1;shift
EOF_OPTION=$1;shift
CART_TYPE=$1;shift
#!!TAPE_OPTIONS_DATA="conv
#!!TAPE_OPTIONS_DATA="$TAP
#Default record format: F (Fixed Block)
RECFM=F
# Optional Data Conversion parameter
if [ $# -ge 1 ]
then
DATA_FILTER_PARM=$1
if [ "noconvert" = "$DATA_FILTER_PARM" ]
then
: # OK
shift
NO_CONVERT_CHAR_SET=1
FILTER_DATA=0
TAPE_OPTIONS_CONVERT=" "
else
# See if DATA_FILTER_PARM is vb_data_write.pl
if [ "vb_data_write.pl" = "$DATA_FILTER_PARM" ]
then
shift
NO_CONVERT_CHAR_SET=1
#record format: V (Variable Block)
RECFM=V
FILTER_DATA=1
TAPE_OPTIONS_CONVERT=" "
DATA_OPTIONS_CONVERT=$*
if [ -n "$DATA_OPTIONS_CONVERT" ]
then
echo "Data filter options found ==>$DATA_OPTIONS_CONVERT<=
fi
else
echo "Invalid noconvert option ==>$NO_CONVERT_CHAR_SET<==
echo $USAGE
exit -1
fi
fi
else
NO_CONVERT_CHAR_SET=0
FILTER_DATA=0
TAPE_OPTIONS_CONVERT="conv
fi
# Validate Destination Directory
if [ -d $SRC_DIR ]
then
if [ -w $SRC_DIR ]
then
: # Cool. Can write to directory.
else
echo $LOGNAME does not have write authority to directory $SRC_DIR
echo exiting
exit -1
fi
else
echo Input Directory $SRC_DIR is not a directory
echo exiting
exit -1
fi
# Validate Destination Directory
if [ -f ${SRC_DIR}/${FILE_NAME_BAS
then
: # Cool. File exisits
else
echo Input File ${SRC_DIR}/${FILE_NAME_BAS
echo exiting
exit -1
fi
if [ "rewind" = "$EOF_OPTION" -o "eject" = "$EOF_OPTION" -o "norewind" = "$EOF_OPTION" ]
then
: # OK
else
echo "Invalid end of tape option ==>$EOF_OPTION<==. Valid: rewind|norewind|eject"
echo $USAGE
exit -1
fi
if [ "3480" = "$CART_TYPE" -o "3490" = "$CART_TYPE" -o "3490E" = "$CART_TYPE" ]
then
: # OK
if [ "3480" = "$CART_TYPE" ]
then
CART_CAPACITY=419429996
else
if [ "3490" = "$CART_TYPE" ]
then
CART_CAPACITY=838860396
else
# !! CART_CAPACITY=2576979974
# !! Future: Use info from ../log/tape_size_hist.txt
CART_CAPACITY=2722230600
fi
fi
else
echo "Invalid tape cartridge option ==>$CART_TYPE<==. \
Valid: 3480|3490|3490E"
echo $USAGE
exit -1
fi
# Validate numeric parms
let TEST_NUM=$VOL_SER_NUM_FIRS
if [ $? -ne 0 ]
then
echo "Non-numeric Vol Ser Numeric portion ==>$VOL_SER_NUM_FIRST<==."
echo $USAGE
exit -1
fi
let TEST_NUM=$LRECL+1
if [ $? -ne 0 ]
then
echo "Logical Record Length is non-numeric ==>$LRECL<==."
echo $USAGE
exit -1
fi
let TEST_NUM=$BLKSIZE+1
if [ $? -ne 0 ]
then
echo "Block size is non-numeric ==>$BLKSIZE<==."
echo $USAGE
exit -1
fi
set -x # !! DEBUG - comment out this line when all is cool.
# Calc various info
# Determine # of tapes
FILE_SIZE=`stat --dereference --format='%s' ${SRC_DIR}/${FILE_NAME_BAS
LF_COUNT_ALL=`wc -l ${SRC_DIR}/${FILE_NAME_BAS
LF_COUNT=`echo $LF_COUNT_ALL | tr -s ' ' | cut -d' ' -f1 | tr -d ' '`
if [ -z "$LF_COUNT" ]
then
LF_COUNT=`echo $LF_COUNT_ALL | tr -s ' ' | cut -d' ' -f2 | tr -d ' '`
fi
# The following ugly code attempts to round up the TTL_BLOCKS to the next
# integer, since the korn shell uses integer arithmetic.
let MULT_FACTOR=100000
let TTL_BLOCKS_MULT=\(\($FILE_
# Use mod operator to see if need to round
let REMAINDER=$TTL_BLOCKS_MULT
if [ $REMAINDER -ne 0 ]
then
let TTL_BLOCKS=\(\($FILE_SIZE-
else
let TTL_BLOCKS=\($FILE_SIZE-$L
fi
# This does not take into account header/trailer files on each tape,
# nor blksize%cart_capacity
let NUM_TAPES=$FILE_SIZE/$CART
echo FILE_SIZE=$FILE_SIZE, TTL_BLOCKS=$TTL_BLOCKS, NUM_TAPES=$NUM_TAPES
echo LF_COUNT=$LF_COUNT
let VOL_SER_NUM_LAST=$VOL_SER_
# pad with zeros if needed
LEN_NUM_FIRST=`echo $VOL_SER_NUM_FIRST | wc -c | tr -d ' '`
LEN_NUM_LAST=`echo $VOL_SER_NUM_LAST | wc -c | tr -d ' '`
echo HEY LEN_NUM_FIRST=$LEN_NUM_FIR
let LEN_DIFF=$LEN_NUM_FIRST-$L
if [ $LEN_DIFF -gt 0 ]
then
VOL_SER_NUM_LAST=`echo "0000000" | cut -c1-$LEN_DIFF`$VOL_SER_NUM
fi
if [ $NUM_TAPES -eq 1 ]
then
TAPE_INFO=tape
TAPE_INFO2="tape is"
TAPE_INFO3="it"
else
TAPE_INFO=tapes
TAPE_INFO2="tapes are"
TAPE_INFO3="the first tape"
fi
if [ $NUM_TAPES -gt 10 ]
then
echo $0 cannot currently handle writing more than 10 tapes. Sorry.
echo Modify loop in $0 so that it pauses every 10 tapes for unmounting
echo written tapes, and mounting x \(up to 10\) blank tapes before going on.
exit -1
else
if [ $NUM_TAPES -gt 1 ]
then
echo $0 cannot currently handle writing more than 1 tape. Sorry.
echo Modify loop in $0 to figure out blocks per tape, and use
echo dd parms iseek=n and count=n to bust apart file.
exit -1
fi
echo Ensure $NUM_TAPES blank $TAPE_INFO2 in the tape library
echo and $TAPE_INFO3 is loaded
fi
echo Hit Enter to write $NUM_TAPES $TAPE_INFO from ${SRC_DIR}/${FILE_NAME_BAS
echo Vol Ser ${VOL_SER_ALPHA}${VOL_SER_
${VOL_SER_ALPHA}${VOL_SER_
and $EOF_OPTION last tape
read stuff
# Clobber log files
echo about to "> $SRC_DIR/${FILE_NAME_BASE}
> $SRC_DIR/${FILE_NAME_BASE}
if [ -w $SRC_DIR/${FILE_NAME_BASE}
then
: # OK to write in this dir
else
echo Unable to write files in `pwd`
exit -1
fi
echo `date '+%D %T'` write_tape.sh going to write $NUM_TAPES $TAPE_INFO \
starting with VOL_SER=${VOL_SER_ALPHA}${
last=${VOL_SER_ALPHA}${VOL
| tee -a $SRC_DIR/${FILE_NAME_BASE}
echo `date '+%D %T'` Base File Name=$FILE_NAME_BASE, LRECL=$LRECL, \
Blocksize=$BLKSIZE \
| tee -a $SRC_DIR/${FILE_NAME_BASE}
CURR_TAPE=$VOL_SER_NUM_FIR
# 2: TAPE_OPTIONS="conv=ascii,u
# 3: TAPE_OPTIONS="conv=ascii,u
# 4: TAPE_OPTIONS="conv=ascii ibs=$BLKSIZE cbs=$LRECL "
#!TAPE_OPTIONS_LABEL="conv
TAPE_OPTIONS_LABEL="conv=b
#!TAPE_OPTIONS_DATA="conv=
#!!TAPE_OPTIONS_DATA="conv
TAPE_OPTIONS_DATA="$TAPE_O
time $DEBUG mt status >> ${FILE_NAME_BASE}.out 2>> ${FILE_NAME_BASE}.err
TAPES_WRITTEN=1
while [ $CURR_TAPE -le $VOL_SER_NUM_LAST ]
do
echo `date '+%D %T'` "working on Tape Vol Ser: ${VOL_SER_ALPHA}${CURR_TAP
| tee -a $SRC_DIR/${FILE_NAME_BASE}
##
# perl script to generate header file
# !! To do: Handle files spanning tapes
##
echo `date '+%D %T'` "Creating vol ser header for ${VOL_SER_ALPHA}${CURR_TAP
>> $SRC_DIR/${FILE_NAME_BASE}
$DEBUG write_vol_ser.pl ${VOL_SER_ALPHA}${VOL_SER_
${VOL_SER_ALPHA}${CURR_TAP
$LRECL $BLKSIZE $TAPES_WRITTEN $NUM_TAPES $RECFM > \
$SRC_DIR/${FILE_NAME_BASE}
echo `date '+%D %T'` "Writing vol ser header for ${VOL_SER_ALPHA}${CURR_TAP
| tee -a $SRC_DIR/${FILE_NAME_BASE}
time $DEBUG /usr/bin/dd of=/dev/rmt/0n \
if=$SRC_DIR/${FILE_NAME_BA
$TAPE_OPTIONS_LABEL \
>> $SRC_DIR/${FILE_NAME_BASE}
time $DEBUG mt status \
>> $SRC_DIR/${FILE_NAME_BASE}
##
# Write data file
# !! To do: Handle files spanning tapes
##
echo `date '+%D %T'` "Writing data for ${VOL_SER_ALPHA}${CURR_TAP
| tee -a $SRC_DIR/${FILE_NAME_BASE}
echo `date '+%D %T'` "Options: $TAPE_OPTIONS_DATA " \
| tee -a $SRC_DIR/${FILE_NAME_BASE}
set -x # !! TEMP DEBUG
if [ $FILTER_DATA -eq 1 ]
then
# Use dd with no "if" parm, pipe from DATA_FILTER_PARM
time $DEBUG $DATA_FILTER_PARM blksize=$BLKSIZE \
$SRC_DIR/${FILE_NAME_BASE}
2>> $SRC_DIR/${FILE_NAME_BASE}
/usr/bin/dd of=/dev/rmt/0n \
$TAPE_OPTIONS_DATA \
>> $SRC_DIR/${FILE_NAME_BASE}
RC_WRITE_DATA=$?
# Need to grep $SRC_DIR/${FILE_NAME_BASE}
# $DATA_FILTER_PARM script had a
# error, since the dd program might have masked a
# bad RC
grep '^Error:' $SRC_DIR/${FILE_NAME_BASE}
if [ $? -eq 0 ]
then
# Found string - there was an error
RC_WRITE_DATA=123
fi
# Need to obtain blocks written if $DATA_FILTER_PARM is vb_data_write.pl
# since writing VB data means that we can't determine the number of
# blocks written by simply dividing file size by block size,
# since each record can be varying in length.
if [ "vb_data_write.pl" = "$DATA_FILTER_PARM" ]
then
if [ $NUM_TAPES -gt 1 ]
then
# Blow up for now
echo "write_tape.sh: I don't know how you got here 2, but you shouldn't have!"
exit -1
else
TTL_BLOCKS=`grep 'vb_data_write finished.* blocks written' $SRC_DIR/${FILE_NAME_BASE}
#echo "HEY: Just set TTL_BLOCKS to $TTL_BLOCKS "
#echo "HEY: TTL_BLOCKS=grep 'vb_data_write finished.* blocks written' $SRC_DIR/${FILE_NAME_BASE}
fi
fi
else
# Write directly to file
time $DEBUG /usr/bin/dd of=/dev/rmt/0n \
if=$SRC_DIR/${FILE_NAME_BA
$TAPE_OPTIONS_DATA \
>> $SRC_DIR/${FILE_NAME_BASE}
RC_WRITE_DATA=$?
fi
if [ $RC_WRITE_DATA -ne 0 ]
then
echo `date '+%D %T'` "Error $RC_WRITE_DATA Writing data " \
| tee -a $SRC_DIR/${FILE_NAME_BASE}
echo You may need to mt rewind this tape
exit -1
fi
set +x # !! TEMP DEBUG
time $DEBUG mt status \
>> $SRC_DIR/${FILE_NAME_BASE}
##
#
# perl script to generate trailer file
# !! To do: Handle files spanning tapes
#
##
if [ $NUM_TAPES -gt 1 ]
then
# Blow up for now
echo "write_tape.sh: I don't know how you got here, but you shouldn't have!"
exit -1
else
#let TTL_BLOCKS=$FILE_SIZE/$BLK
let CURR_BLOCKS=$TTL_BLOCKS
fi
echo `date '+%D %T'` "Creating vol ser trailer for ${VOL_SER_ALPHA}${CURR_TAP
>> $SRC_DIR/${FILE_NAME_BASE}
echo `date '+%D %T'` "HEY! CURR_TAPE==>$CURR_TAPE<==,
echo `date '+%D %T'` "HEY! CURR_BLOCKS==>$CURR_BLOCKS
>> $SRC_DIR/${FILE_NAME_BASE}
$DEBUG write_vol_ser.pl ${VOL_SER_ALPHA}${VOL_SER_
${VOL_SER_ALPHA}${CURR_TAP
$LRECL $BLKSIZE $TAPES_WRITTEN $NUM_TAPES $RECFM $CURR_BLOCKS > \
$SRC_DIR/${FILE_NAME_BASE}
echo `date '+%D %T'` "Writing vol ser trailer for ${VOL_SER_ALPHA}${CURR_TAP
| tee -a $SRC_DIR/${FILE_NAME_BASE}
time $DEBUG /usr/bin/dd of=/dev/rmt/0n \
if=$SRC_DIR/${FILE_NAME_BA
$TAPE_OPTIONS_LABEL \
>> $SRC_DIR/${FILE_NAME_BASE}
time $DEBUG mt status \
>> $SRC_DIR/${FILE_NAME_BASE}
if [ $CURR_TAPE -eq $VOL_SER_NUM_LAST ]
then
# Last tape. Rewind or Eject to next tape
if [ "eject" = "$EOF_OPTION" ]
then
echo `date '+%D %T'` "Switching to next tape " \
| tee -a $SRC_DIR/${FILE_NAME_BASE}
$SRC_DIR/${FILE_NAME_BASE}
time $DEBUG mt_swap_tape.sh swap \
>> $SRC_DIR/${FILE_NAME_BASE}
2>> $SRC_DIR/${FILE_NAME_BASE}
else
if [ "rewind" = "$EOF_OPTION" ]
then
echo `date '+%D %T'` "Rewinding last tape " \
| tee -a $SRC_DIR/${FILE_NAME_BASE}
$SRC_DIR/${FILE_NAME_BASE}
time $DEBUG mt rewind \
>> $SRC_DIR/${FILE_NAME_BASE}
2>> $SRC_DIR/${FILE_NAME_BASE}
else
echo `date '+%D %T'` "Leaving last tape positioned at EOF" \
| tee -a $SRC_DIR/${FILE_NAME_BASE}
$SRC_DIR/${FILE_NAME_BASE}
fi
fi
else
# !! To Do: Need to ensure not on last tape slot (10). If so,
# !! pause until tape magazine is reloaded with 10
# !! blank tapes.
# !! Look at /export/home/kabira/common
# !! to determine current tape slot in use.
echo `date '+%D %T'` "Switching to next tape " \
| tee -a $SRC_DIR/${FILE_NAME_BASE}
$SRC_DIR/${FILE_NAME_BASE}
time $DEBUG mt_swap_tape.sh swap \
>> $SRC_DIR/${FILE_NAME_BASE}
2>> $SRC_DIR/${FILE_NAME_BASE}
fi
echo `date '+%D %T'` " - End of Loop" \
>> $SRC_DIR/${FILE_NAME_BASE}
ps -f -p $$ \
>> $SRC_DIR/${FILE_NAME_BASE}
# Bump counters
let CURR_TAPE=$CURR_TAPE+1
let TAPES_WRITTEN=$TAPES_WRITT
# pad with zeros if needed
LEN_NUM_LAST=`echo $CURR_TAPE | wc -c | tr -d ' '`
echo HEY LEN_NUM_FIRST=$LEN_NUM_FIR
let LEN_DIFF=$LEN_NUM_FIRST-$L
if [ $LEN_DIFF -gt 0 ]
then
CURR_TAPE=`echo "0000000" | cut -c1-$LEN_DIFF`$CURR_TAPE
fi
echo HEY CURR_TAPE=$CURR_TAPE
done
exit 0
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
http://oldlook.experts-exchange.com/questions/20668611/catenating-files-and-deleting-the-parts-as-I-go.html?query=tar+split&searchType=all