From: "Dan Langille" To: bacula-users@lists.sourceforge.net Subject: [Bacula-users] FreeBSD - large backups to tape Date: Mon, 20 Oct 2003 15:29:18 -0400 Kern and I have been working on a FreeBSD/Bacula problem. He's asked me to post this to the list. The problem was within the FreeBSD pthreads library. A solution has been found. PROBLEM DESCRIPTION: The FreeBSD pthreads library does not properly handle End Of Tape. This problem will be fixed in FreeBSD 4.9. The bug results in more data being written to the tape than could be read. Any backup which involved more than one tape would be incomplete. DEMONSTRATION: To demonstrate the problem, tapetest.c can be obtained from http://www.freebsd.org/cgi/query-pr.cgi?pr=56274 This tests without pthreads: * If you build this program with: * * c++ -g -O2 -Wall -c tapetest.c * c++ -g -O2 -Wall tapetest.o -o tapetest * * Procedure for testing tape * ./tapetest /dev/your-tape-device * rewind * rawfill * rewind * scan * * The output will be something like: * * ======== * Rewound /dev/nsa0 * *Begin writing blocks of 64512 bytes. * ++++++++++++++++++++ ... * Write failed. Last block written=17294. stat=0 ERR=Unknown error: 0 * weof_dev * Wrote EOF to /dev/nsa0 * *Rewound /dev/nsa0 * *Starting scan at file 0 * 17294 blocks of 64512 bytes in file 0 * End of File mark. * End of File mark. * End of tape * Total files=1, blocks=17294, bytes = 1115670528 * ======== * * which is correct. Notice that the return status is * 0, while in the example below, which fails, the return * status is -1. This tests with pthreads: * If you build this program with: * * c++ -g -O2 -Wall -pthread -c tapetest.c * c++ -g -O2 -Wall -pthread tapetest.o -o tapetest * Note, we simply added -pthread compared to the * previous example. * * Procedure for testing tape * ./tapetest /dev/your-tape-device * rewind * rawfill * rewind * scan * * The output will be something like: * * ======== * Rewound /dev/nsa0 * *Begin writing blocks of 64512 bytes. * +++++++++++++++++++++++++++++ ... * Write failed. Last block written=17926. stat=-1 ERR=No space left on device * weof_dev * Wrote EOF to /dev/nsa0 * *Rewound /dev/nsa0 * *Starting scan at file 0 * 17913 blocks of 64512 bytes in file 0 * End of File mark. * End of File mark. * End of tape * Total files=1, blocks=17913, bytes = 1155603456 * ======== * * which is incroorect because it wrote 17,926 blocks but read * back only 17,913 blocks If you get the same number of blocks written and read WHEN using pthreads, then you've been correctly patched. SOLUTION: For FreeBSD prior to and including 4.9, you have two choices to ensure proper backups. These instructions assume you are familiar with patching FreeBSD and already have the FreeBSD source code installed on your machine. Do one of the following: - cvsup and build your system to FreeBSD 4.x-STABLE after the date Mon Dec 29 15:18:01 2003 UTC - Apply this patch. http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc_r/uthread/uthread_write.c.diff?r1=1.16.2.6&r2=1.16.2.8 To apply the patch, follow these instructions as root. fetch -o pthread.diff http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc_r/uthread/uthread_write.c.diff?r1=1.16.2.6\&r2=1.16.2.8 cd /usr/src/lib/libc_r/uthread/ patch < /path/to/pthread.diff cd .. make all install I recommend restarting Bacula. TESTING: I suggest running tapetest on your patched system and then conducting a backup which spans two tapes. Restore the data and compare to the original. If not identical, please let us know.