Date: Sun, 7 Sep 1997 10:30:22 +0200 From: j@uriah.heep.sax.de (J Wunsch) To: hackers@FreeBSD.ORG Cc: handy@sag.space.lockheed.com (Brian N. Handy) Subject: Re: Tape question Message-ID: <19970907103022.YU02721@uriah.heep.sax.de> In-Reply-To: <Pine.OSF.3.96.970902141656.16187M-100000@sag.space.lockheed.com>; from Brian N. Handy on Sep 2, 1997 14:19:30 -0700 References: <Pine.OSF.3.96.970902141656.16187M-100000@sag.space.lockheed.com>
next in thread | previous in thread | raw e-mail | index | archive | help
As Brian N. Handy wrote: > The problem is easily described: > > - The Exabyte tapes to be read have a variable (logical) block size, > it typically is 8192 bytes, but often shorter. > > - My original c program always attempted to read a 8192 byte block: > > nn = read(unit,buffer,8192); > > - On the sun this worked, it would read one (logical) block, and > return the actual number of bytes read. > > - In FreeBSD this created unpredictable results, if the logical block > was shorter than 8192. This must be a problem with the Exabyte then. It works fine for me, with a Tandberg TDC4222, and a QIC-525 cartridge (QIC-150, of course, doesn't work since it's fixed-length blocking). Also, i know that restore(8) basically relies on this feature in order to determine the tape block size. ISTR that this once was broken, but that's been quite some time ago. Here's my test program: #include <sys/types.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { size_t table[] = {512, 1024, 2048, 4096, 8192, 20480, 10240, 15555, 33333, 0}; int i, fd, mode; ssize_t rv; char buf[65536], obuf[65536]; const char *op; ssize_t (*func)(int, void *, size_t); if (argc != 2) { fprintf(stderr, "usage: foo {read|write}\n"); return 1; } if (strcmp(argv[1], "write") == 0) { mode = O_WRONLY; func = (ssize_t (*)(int, void *, size_t))write; op = "write()"; } else { mode = O_RDONLY; func = read; op = "read()"; } if ((fd = open("/dev/rst0", mode)) == -1) { fprintf(stderr, "open() failed\n"); return 1; } for (i = 0; i < 65536; i++) obuf[i] = buf[i] = (char)random(); for (i = 0; table[i]; i++) { size_t amnt = func == read? 65536: table[i]; rv = func(fd, buf, amnt); if (rv == -1) { fprintf(stderr, "%s failed\n", op); return -1; } printf("%s returned %d out of %d\n", op, rv, amnt); if (func == read && memcmp(buf, obuf, rv)) fprintf(stderr, "buffer fails comparision\n"); } return 0; } And the results are: j@uriah 1010% ./foo write write() returned 512 out of 512 write() returned 1024 out of 1024 write() returned 2048 out of 2048 write() returned 4096 out of 4096 write() returned 8192 out of 8192 write() returned 20480 out of 20480 write() returned 10240 out of 10240 write() returned 15555 out of 15555 write() returned 33333 out of 33333 j@uriah 1011% ./foo read read() returned 512 out of 65536 read() returned 1024 out of 65536 read() returned 2048 out of 65536 read() returned 4096 out of 65536 read() returned 8192 out of 65536 read() returned 20480 out of 65536 read() returned 10240 out of 65536 read() returned 15555 out of 65536 read() returned 33333 out of 65536 -- cheers, J"org joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE Never trust an operating system you don't have sources for. ;-)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19970907103022.YU02721>