Bugfix for Gnu Tar Concerning Multiple Volumes and Reading From Pipes
Please note: The info following below is out of date now.
I had contact with the maintainer of Gnu Tar in the mean time.
Unfortunately, my bug fix does not fix the problems completely. I
hope to find some spare time in the next time to look into the
problem again. - If you like, you can take my patch as a starting
point four your own fix, of course.
I have discovered and fixed two bugs in tar-1.13.17 (from the
SuSE 7.0 Linux edition). In this version, multiple volumes
do not work when used together with reading from a pipe, even when
using the option --read-full-records to handle short reads from a
pipe.
While fixing this bug, I found another one in the source code. It
occurs when using multiple volumes together with a block size of one
or two.
I posted a fix on January 17, 2001 to bug-tar@gnu.org. I never got a
reply, nor found the fix in a new version of tar. Therefore, I now
provide it here. Maybe you find it through a search engine.
I wrote a (GNU)
makefile that demonstrates both problems. The
makefile creates the appropriate test data and then runs tar,
printing comments on what it is currently doing. See also the
comments at the beginning of the makefile.
Both bugs are in the source file src/buffer.c. The first bug is in
the function flush_read(). There is a handling for multi-volume, and
there is a handling for short reads due to reading from a pipe
(obeying the option --read-full-records). The latter handling jumps
to label short_read. But then the multi-volume handling is skipped,
so both features cannot be used together.
I have written a fix for the file src/buffer.c and provide a
patch
for it. The fix introduces the function rmtread_full() and replaces
most, but not all, calls to rmtread() in buffer.c by rmtread_full().
This new function retries to read until it gets sufficient data,
when read_full_records_option is set, except at EOF.
While fixing this bug, I found that the function flush_read() does
not consider that a full record might be shorter than three blocks
(i.e., --blocking-factor=1 or 2). It therefore just reads one record
and then increments the block cursor up to two times, still
expecting data to be left. I fixed this by checking for the amount
of data left, when incrementing, and by performing more reads when
necessary. The makefile demonstrates this bug, too. With an unpatched
version of tar, the tar command crashes already when writing, since
the write code does not consider the above case, too. My patch fixes
both reading and writing.
Note: the reason to use pipes with multi-volume in the first place
was that tar does not stop reading immediately when the specified
length of the tape is exhausted. This lead to some ugly device
errors with my CD drive. Therefore I used dd to read the right
amount of data, and fed it into tar through a pipe.
I found also a third, minor problem with tar:
when running ./configure, the file lib/fnmatch.h is not created for
my platform, SuSE Linux (presumably correct, since the system
provides it). But in the makefile in the src directory, this file is
a prerequisite for several targets, nevertheless. Therefore I had to
create a symbolic link from the file lib/fnmatch.hno to
lib/fnmatch.h to let "make" run smoothly.
|