On 06/04/2010 08:38 AM, Daniel P. Berrange wrote:
> In that case, it may be better to have two constants - the
preferred
> transfer size (1M), and the XML padding block size (512 as before, or
> perhaps 4k given newer disk architectures that prefer 4k), along with
> code that allows the final transfer to be shorter than the preferred
> size so long as it is still a multiple of the block size.
That doesn't work because dd can't seek into the file a size less than
its transfer size. ie the seek=NN parameter is specifying a multiple
of the bs=XX value, not an absolute seek position in bytes.
One invocation of dd can't. But two invocations can! Thanks to the
fact that fd offsets are one of the few things that a child process
propagates back to the parent, when an fd is shared among processes.
The trick is to use the first dd to position the fd, then the second dd
to write larger blocks that are unaligned per the block size, but still
aligned based on the fundamental block size.
For an example:
$ perl -e 'print "1"x20' > sample1
$ { dd bs=5 seek=1 if=/dev/null;
dd bs=10 count=1 if=sample1; } > sample2
0+0 records in
0+0 records out
0 bytes (0 B) copied, 2.2349e-05 s, 0.0 kB/s
1+0 records in
1+0 records out
10 bytes (10 B) copied, 6.4604e-05 s, 155 kB/s
$ tr '\0' 0 < sample2
000001111111111
See - I produced sample2 by skipping past a smaller header (in this
case, bs=5), then writing a single larger block (bs=10, a multiple of
the smaller size, but not aligned to the smaller offset).
Would you like me to try and write this up into a followup patch?
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org