[comp.unix.xenix] Possible bug in SCO tape driver

fnf@estinc.UUCP (Fred Fish) (12/22/89)

Enclosed is a small test program that tickles a bug on our system.  I'd
be curious to know if the same bug appears on other systems running SCO
Xenix 2.3.1, and if so, their configuration.  Thanks!

======================================================================

/*
 *	This little program demonstrates a bug in the SCO tape driver for
 *	the following configuration.  I don't know if it affects other
 *	configurations.
 *
 *	Machine:	Bell Technologies MPE with Bell supplied 60Mb tape
 *	SCO Release:	2.3.1
 *	Tape Config:	Base addr = 0x300, Interrupt = 5, DMA = 1, Type = W
 *
 *	Note that the Bell Tech supplied tape driver IS NOT used.  The SCO
 *	driver is faster anyway...
 *
 *	The bug is that if the tape is kept streaming, when it reaches the
 *	end of the tape, the first attempted write that fails returns with
 *	errno set to ENOSPC and subsequent tries fail and return with errno
 *	set to EIO.  A close of the device then succeeds.
 *
 *	However, if the tape is not kept streaming, the first failing write
 *	at the end of the tape returns with errno set to EIO, as do all
 *	subsequent writes.  When the device is closed, the driver hangs
 *	(the drive light stays on and the system call never returns) until
 *	the tape is removed.  The tape drive remains unusable until the
 *	system is rebooted.  To demonstrate the bug, change the value of
 *	SLEEPTIME below to a large enough value to cause streaming to stop.
 *
 *	This problem was discovered because unlike tar or cpio which give
 *	up and go home at the slightest hint of trouble, BRU wants to
 *	retry every failing archive I/O operation at least several times
 *	before attempting some other form of error recovery, such as deciding
 *	that the end of the tape has been reached and asking for the next one.
 *
 *	- Fred Fish  ><>
 *
 */

#include <stdio.h>
#include <fcntl.h>

#define DEVICE		"/dev/rct0"	/* Device to test */
#define MAXERRORS	10		/* Maximum number of errors */
#define SLEEPTIME	5		/* 0 to stream, approx 5 for bug */

main ()
{
    int fd;
    int size = 0;
    int errcount = 0;
    char buf[1024 * 200];
    
    if ((fd = open (DEVICE, O_WRONLY, 0666)) == -1) {
	fprintf (stderr, "%s: can't open for write", DEVICE);
	perror ("");
    } else {
	fprintf (stderr, "Writing device '%s', descriptor %d\n", DEVICE, fd);
	fprintf (stderr, "Writing %d sized blocks\n", sizeof (buf));
	fflush (stderr);
	while (errcount < MAXERRORS) {
	    if (write (fd, buf, sizeof (buf)) == sizeof (buf)) {
		size += sizeof (buf);
		fprintf (stderr, "Wrote %dKb\n", size / 1024);
	    } else {
		errcount++;
		fprintf (stderr, "error %d (limit %d) ", errcount, MAXERRORS);
		perror ("write failed");
	    }
	    fflush (stderr);
	    sleep (SLEEPTIME);
	}
	fprintf (stderr, "Close descriptor %d\n", fd);
	if (close (fd) == -1) {
		perror ("Close failed");
	}
    }
}
-- 
# Fred Fish, 1835 E. Belmont Drive, Tempe, AZ 85284,  USA
# 1-602-491-0048           asuvax!{nud,mcdphx}!estinc!fnf

fnf@estinc.UUCP (Fred Fish) (12/23/89)

In article <250@estinc.UUCP> fnf@estinc.UUCP (Fred Fish) writes:
> *	...............  When the device is closed, the driver hangs
> *	(the drive light stays on and the system call never returns) until
> *	the tape is removed.  The tape drive remains unusable until the
> *	system is rebooted.  .......

Further investigation indicates that what I wrote here isn't totally
true.  The tape can be returned to service with the command "tape reset".

-Fred
-- 
# Fred Fish, 1835 E. Belmont Drive, Tempe, AZ 85284,  USA
# 1-602-491-0048           asuvax!{nud,mcdphx}!estinc!fnf