Differences between Solaris/Linux and FreeBSD

Kern Sibbald kern at sibbald.com
Mon Jun 2 03:45:38 PDT 2003


On Sun, 2003-06-01 at 22:08, Justin T. Gibbs wrote:
> > Hello,
> > 
> > I'm the author of a GPL'ed network backup program called
> > Bacula (www.bacula.org). For the last three years, it
> > has been working flawlessly on Solaris and Linux systems.
> > When users attempted to use it recently on FreeBSD,
> > it did not work. I subsequently modified Bacula so that
> > it would work on FreeBSD -- basically, I had to program
> > around some important differences in the way FreeBSD 
> > handles EOFs compared to Solaris and Linux.  At some point
> > in the future, I would like to discuss the problems
> > I had in detail, if that interests you.
> 
> I would be interested as I'm sure would other readers of this
> list.

...

As promised, in this email, I will try my best to describe
the differences I found between Solaris/Linux and FreeBSD
concerning tape handling. There were five separate areas
where I noticed differences:

1. On Solaris/Linux, the default behavior for ioctl(MTEOM)
   is to run in what they call slow mode. In this mode, the
   tape is positioned to the end of the data, and the driver
   returns the correct file number in the MTIOCGET packet.
   It is possible to enable fast-EOM, but no one uses it to
   my knowledge.

   On FreeBSD, you apparently always use the fast-EOM so that
   the tape position is unknown after the ioctl().

   Bacula always knows how many files are on a tape, and when
   appending to a tape that is already written and newly opened,
   it MUST know where it is on the tape. As a consequence, on
   FreeBSD, I must explicitly use MTFSF with read()s in between
   to position to the end of the tape -- a fairly slow affair.

   Note, on FreeBSD, the user must explicitly tell Bacula not
   to use the MTEOM function with a special configuration
   statement.

2. Your handling of EOM differs from Solaris/Linux.  On both of
   those systems, when the Bacula reads the first EOF, the driver
   returns 0 bytes read. On reading the second EOF, the driver
   returns 0 bytes read, but before returning backspaces over
   the EOF, leaving you positioned correctly for appending to the
   tape and having told you you are at the end of the tape by
   giving two consecutive 0 byte read.  Any further read() 
   request return an I/O error.

   On FreeBSD, reading the first EOF returns 0 bytes, reading
   the second EOF also returns 0 bytes (sometimes, I apparently
   get "Illegal operation"). However, the tape is left positioned
   after the second EOF, so appending from that point effectively
   "loses" the data. 

   To handle this correctly the FreeBSD user must add a configuration
   statement to Bacula telling him to backspace file at EOM. 

3. I have previously described this but will do so again for
   completeness here. On Solaris/Linux when Bacula does:

    write();
    ioctl(MTEOF);
    ioctl(MTEOF)
    ioctl(MTBSF);
    ioctl(MTBSF);
    ioctl(MTBSR);
    read();

   the read() re-reads the last write.  On FreeBSD, the read returns
   0 bytes (there is also a problem of freezing the tape wrapped into
   this example if I am not mistaken). Apparently the 0 bytes read is
   because FreeBSD adds an additional EOF mark (not necessary) and
   leaves the drive positioned *after* the mark thus re-reading the
   last record fails when it logically should not.

4. Tape freezing: On Solaris/Linux, the tape never "freezes". On 
   FreeBSD it does freeze. As best I can determine, you freeze the
   drive when you lose track of where you are. Typically, this 
   occurs when I do a MTBSR to re-read the last record. On Solaris/Linux
   the tape is never frozen, but when they don't know the position,
   they simply return -s in the MTIOCGET packet, which is fine with
   me because Bacula only uses that info when initially reading a
   tape to append to it.

   Freezing the tape causes all sorts of problems because it generates
   a flood of unexpected errors. Within a large complicated program like
   Bacula, when a low level routine re-reads a record during writing and
   the tape freezes, it cannot simply rewind the drive as this could
   cause chaos and possible overwriting of the beginning of the drive.

   I've attempted to overcome tape freezing by providing the user a
   means to turn off MTBSR (but they don't always do so), and by issuing
   ioctl(MTIOCERRSTAT) after every return of -1 from any I/O request.

   I recommend that you do away with freezing the drive -- it seems to
   me that it only causes more problems.  In saying that I have to 
   that I really do not understand tape freezing or why you do it since
   I found no documentation on it, and everything I write above I have
   deduced from what Dan has reported back to me.

5. I am quite fuzzy on this point because I forget exactly what happened
   and what I did about it. 

   It seems to me that on Linux, if I read a block but specify a number
   of bytes less than the number actually in the block on the tape, the
   driver returns the data anyway.  I then check if the block is 
   internally complete and if not, increase my record size to the size
   indicated in the data received, backspace one record, and re-read it.

   If I am not mistaken, on FreeBSD, the first read returns an error,
   and Bacula just immediately gives up.  Your documentation specifies
   that one can never read a partial record from a tape, but it does not
   specify what error code is generated. As a consequence, rather than
   recovering and re-reading the record, Bacula has to assume it was
   a fatal error.  

I hope these points are clear. If not please don't hesitate to ask.

Best regards,

Kern

   



More information about the freebsd-scsi mailing list