>/usr/local/bin/tar -cvf - /home | rsh linux-host dd of=/dev/nst0
>
>(you may want to specify '-b blocksize' to the tar command... and
>  'bs=blocksize' to the dd)

The only problem with using dd like this is that dd does not do output
reblocking.  It takes whatever record size comes in (i.e. the size of
the read()) and that's what it writes.

With networking in between, those read's can be all sorts of interesting
sizes, which in turn will write all sorts of interesting record sizes to
the tape, which in turn will be hard to read back later.  Like at 2AM.
When you really, really don't need yet another problem :-).

Adding "-b blocksize" to the tar or "bs=blocksize" to the dd will have
no effect on this whatsoever.

I think some versions of dd have options to deal with this, but it's not
broadly supported, which has always been one of the major mysteries of
Unix to me.

You might be better using "cat", which will (hopefully) use stdio and
thus all the output write's will be the same size (BUFSIZ from stdio.h).
Maybe not a size you want, or one you can control, but at least all
the same.

I wrote a little perl script years ago to deal with this (appended --
I call it "reblock").  As I look at it, it could use some better error
handling, and I'm certain could be coded better, but it's never failed me
(and dd certainly has).  Your example would then go like this:

  rsh linux-host mt -f /dev/nst0 rewind
  /usr/local/bin/tar -cvf - /home | rsh linux-host "reblock > /dev/nst0"

John R. Jackson, Technical Software Specialist, [EMAIL PROTECTED]

#!/usr/local/bin/perl

# Perform I/O reblocking to force all output records (except the last)
# to be of the same size.

if ($#ARGV >= 0) {
        $BlockSize = shift (@ARGV);
        $BlockSize = $BlockSize*1024 if ( $BlockSize =~ m/[kK]$/ );
        $BlockSize = $BlockSize*512 if ( $BlockSize =~ m/[bB]$/ );
        $BlockSize = $BlockSize*2 if ( $BlockSize =~ m/[wW]$/ );
} else {
        $BlockSize = 10 * 1024;                 # normal tar blocking size
}

$buf = '';
$b = 0;                                         # data in the buffer

while (($r = sysread (STDIN, $buf, $BlockSize, $b)) > 0) {
        $b += $r;
        if ($b >= $BlockSize) {
                syswrite (STDOUT, $buf, $BlockSize, 0);
                $b -= $BlockSize;
                if ($b > 0) {
                        $buf = substr ($buf, $BlockSize, $b);
                }
        }
}

if ($b > 0) {
        syswrite (STDOUT, $buf, $b, 0);
}

exit (0);

Reply via email to