Amanda-Users

Re: amrestore problem, headers ok but no data

2005-01-07 15:27:39
Subject: Re: amrestore problem, headers ok but no data
From: Jon LaBadie <jon AT jgcomp DOT com>
To: amanda-users AT amanda DOT org
Date: Fri, 7 Jan 2005 15:11:41 -0500
On Fri, Jan 07, 2005 at 02:01:26PM -0500, Eric Siegerman wrote:
> On Fri, Jan 07, 2005 at 11:17:21AM -0500, Brian Cuttler wrote:
>
>samar 170# dd of=/dev/sdlt2 obs=32k if=./scratch
>64+0 records in
>1+0 records out
>
>"bs" block size, "obs" outpub BS, (there is an IBS also, which I
>am afraid of developing should this not resolve soon)
>

"bs" is just a short cut to saying "obs" and "ibs".
So the following are the same:

   obs=32k ibs=32k
    bs=32k

It is only necessary to use obs and ibs if they are different
(including an unspecified one of the default 512 bytes).

> > 
> > Oddly trying to dd if=/dev/rmt/tps... read no data
> > 
> > samar 85# mt -f /dev/rmt/tps1d4nrns rewind
> > samar 86# dd if=/dev/rmt/tps1d4nrns of=scratch
> > Read error: Invalid argument
> > 0+0 records in
> > 0+0 records out
> 
> These two things might well be related.  That dd command, without
> a "bs=" argument, is trying to read 512-byte blocks.  But the
> physical blocks on the tape are 32 KB -- your adjustments have
> seen to that.  It would be appropriate for the read() call to
> fail in that situation, as indeed it did.  On Solaris (whose man
> pages I have access to at the moment), the error status would be
> ENOMEM; perhaps on your system it's EINVAL == "Invalid argument"
> instead.  (The place to look that up would likely be in the man
> page for the tape driver -- st(7) is where I found the Solaris
> version.)

That ENOMEM, reported as "insufficient memory" sometimes used to
throw me for a loop.  Here is the situation as I understand it.

To enhance performance dd tries to do unbuffered I/O, meaning the
data goes directly to memory in dd rather than through buffers
in the OS and then to dd.  An upshot of this is that the buffer
dd reads into must be at least as big as a block on the device.
As there is no OS buffering, dd must get the entire block from
the device in one shot, no taking little chunks at a time.  The
devices do not send bytes on request, they send blocks.

So if dd is left with a default 512 byte "ibs", input block size,
but the device is using a larger block size, like an amanda tape
of 32k, dd has allocated a 512 byte piece of memory to hold the
input data.  But when dd requests the first block it unexectedly
gets 32k of data and has "insufficient memory" (ENOMEM).

The reverse is not really a problem.  Suppose you said "ibs=128k".
dd would simply read sufficient device blocks until the buffer
was filled, four blocks in the above example.  The problems arise
when the device wants to feed dd more data per read than dd is
prepared to receive.

On output dd can make its own adjustments.  If the obs is larger,
it can move multiple input buffers to the output buffer before
doing the write.  If the reverse is true, input block size larger
than output, it can copy part of the input block to the output
buffer and do multiple outputs from a single input buffer.

HTH
jon
-- 
Jon H. LaBadie                  jon AT jgcomp DOT com
 JG Computing
 4455 Province Line Road        (609) 252-0159
 Princeton, NJ  08540-4322      (609) 683-7220 (fax)