[comp.unix.questions] Mag Tape Duplication Problems

russ@wpg.UUCP (russ) (02/15/88)

After hearing me brag about how great unix "tools" are for doing just 
about everything, a friend of mine asked me to duplicate a reel of 
nine-track tape that was estimated to contain app. 60 megs of data.  

Although I only have one nine track drive, I do have a cartridge streamer 
(20 megs) so I naively assumed that I could read and write the contents of 
the nine-track in 20 meg segments to three separate cartridge tapes and 
then concatenate the three cartridge tapes back onto a new reel of 
nine-track tape.  I had figured that if 'dd' couldn't handle it, a 
simple-minded program (on the order of while getchar (putchar) would be 
able to do the job.  

Apart from my profound ignorance of whatever it is that passes for 
sentinel-like characters on tape devices, one of the things I didn't plan 
on was that the tape turned out to contain, not one big file, but rather a 
zillion or so small files that appear to range from two to seven blocks in 
length.  

I suppose I could repetitiously invoke 'dd' while keeping track of the 
total number of blocks, but I keep wondering what will happen if we get 
down to the end of a cartridge tape and then come across a five meg file.  

Any suggestions about how this thing could be handled "elegantly"?

-- 
Russell Lawrence, WP Group, POB 306, Metairie, LA 70004
AT&T:   +1 504 456 0001          COMPUSERVE: 72337,3261
UUCP:   {philabs,hpda,nbires,amdahl,...}!uunet!wpg!russ

gwc@root.co.uk (Geoff Clare) (02/26/88)

In article <351@wpg.UUCP> russ@wpg.UUCP (russ) writes:
>
>After hearing me brag about how great unix "tools" are for doing just 
>about everything, a friend of mine asked me to duplicate a reel of 
>nine-track tape that was estimated to contain app. 60 megs of data.  
>
>Although I only have one nine track drive, I do have a cartridge streamer 
>(20 megs) so I naively assumed that I could read and write the contents of 
>the nine-track in 20 meg segments to three separate cartridge tapes and 
>then concatenate the three cartridge tapes back onto a new reel of 
>nine-track tape.  I had figured that if 'dd' couldn't handle it, a 
>simple-minded program (on the order of while getchar (putchar) would be 
>able to do the job.  
>
>I suppose I could repetitiously invoke 'dd' while keeping track of the 
>total number of blocks, but I keep wondering what will happen if we get 
>down to the end of a cartridge tape and then come across a five meg file.  
>

I thought I would knock up a shell script to do the job and mail it to
Russ, but it took longer than I expected and when I was finished I
thought "Hey, this is good stuff", so I'm going to post it in the hope
that more people may find a use for it, or at least for some of the
ideas in it.

I should first issue a warning that this is totally untested, so
apologies for any bugs in it, but I think the method should work.

So here it is:


----------------------------- cut here -------------------------------

# shell script to copy mag tape to multiple cartridge volumes and back

BLOCKSIZE=10k		# mag tape block size required
MAGTAPE=/dev/rmt8	# name of mag tape device
CARTRIDGE=/dev/rct	# name of cartridge device
BLOCKSPERVOL=40000	# no. of 512 byte blocks to fill cartridge tape

IFS="+$IFS"	# add '+' to field seperator list to ease splitting of
		# dd block counts

# write cartridges until fewer then requested no. of blocks are transferred

blocks="$BLOCKSPERVOL"
vol=1
dd if="$MAGTAPE" ibs="$BLOCKSIZE" | while test "$blocks" -eq "$BLOCKSPERVOL"
do
	echo "insert cartridge $vol and press RETURN"
	read a </dev/tty
	a=`dd count="$BLOCKSPERVOL" of="$CARTRIDGE" 2>&1`
	echo $a
	set -- $a
	blocks=`expr $1 \+ $2`
	eval b"$vol"="$blocks"
	vol=`expr $vol \+ 1`
done

echo "insert blank mag tape to receive copy and press RETURN"
read a

# write back cartridges - no of blocks on each volume is in b$vol

outvol=1
while test "$outvol" -lt "$vol"
do
	echo >&2 "insert cartridge $outvol and press RETURN"
	read a
	eval blocks=\$b"$vol"
	echo >&2 "block count should be $blocks"
	dd count="$blocks" if="$CARTRIDGE"
	outvol=`expr $outvol \+ 1`
done | dd obs="$BLOCKSIZE" of="$MAGTAPE"

----------------------------- cut here -------------------------------

-- 

Geoff Clare    UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH
gwc@root.co.uk   ...!mcvax!ukc!root44!gwc   +44-1-606-7799  FAX: +44-1-726-2750

gwc@root.co.uk (Geoff Clare) (02/29/88)

When I actually got round to trying out the script I posted, there
were a few problems with it I had not forseen (OK, I know I should
have tried it *before* I posted it, but I was short of time, sorry).

The main problem was that because the first loop was on the end of a pipe
it was executed in a subshell, so all those carefully stored block
counts were not available to the second loop.  This has been
cured by having the entire script from that point down executed as
a subshell receiving the data from the pipe.

Here is the updated version:

----------------------------- cut here ----------------------------

:
# shell script to copy mag tape to multiple cartridge volumes and back

BLOCKSIZE=10k		# mag tape block size required
MAGTAPE=/dev/rmt8	# name of mag tape device
CARTRIDGE=/dev/rct	# name of cartridge device
BLOCKSPERVOL=40000	# no. of 512 byte blocks to fill cartridge tape

IFS="+$IFS"	# add '+' to field seperator list to ease splitting of
		# dd block counts

# direct dd output into remainder of script as single subshell, instead of
# just the first loop, to allow $b1 $b2 etc. to be accessed in the second loop

dd if="$MAGTAPE" ibs="$BLOCKSIZE" | (

	# write cartridges until < requested no. of blocks are transferred

	blocks="$BLOCKSPERVOL"
	vol=1
	while test "$blocks" -eq "$BLOCKSPERVOL"
	do
		echo "insert cartridge $vol and press RETURN"
		read a </dev/tty
		a=`dd count="$BLOCKSPERVOL" of="$CARTRIDGE" 2>&1`
		echo "$a"
		set -- $a
		blocks=`expr $1 \+ $2`
		eval b"$vol"="$blocks"
		vol=`expr $vol \+ 1`
	done

	echo "insert blank mag tape to receive copy and press RETURN"
	read a </dev/tty

	# write back cartridges - no of blocks on each volume is in b$vol

	outvol=1
	while test "$outvol" -lt "$vol"
	do
		echo >&2 "insert cartridge $outvol and press RETURN"
		read a </dev/tty
		eval blocks=\$b"$outvol"
		echo >&2 "block count should be $blocks"
		dd count="$blocks" if="$CARTRIDGE"
		outvol=`expr $outvol \+ 1`
	done | dd obs="$BLOCKSIZE" of="$MAGTAPE"
)

----------------------------- cut here ----------------------------

-- 

Geoff Clare    UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH
gwc@root.co.uk   ...!mcvax!ukc!root44!gwc   +44-1-606-7799  FAX: +44-1-726-2750