Return to BSD News archive
Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!news.rmit.EDU.AU!news.unimelb.EDU.AU!munnari.OZ.AU!news.hawaii.edu!news.uoregon.edu!vixen.cso.uiuc.edu!newsfeed.internetmci.com!salliemae!europa.chnt.gtegsc.com!wlbr!moe!sms
From: sms@moe.2bsd.com (Steven M. Schultz)
Subject: TMSCP bug, standalone xon/xoff, tcopy errors, fsck strings (#323)
Archive-Name: comp.bugs.2bsd
Organization: 2BSD, Simi Valley CA USA
Message-ID: <Dso2xr.EAF@moe.2bsd.com>
Date: Sat, 8 Jun 1996 05:51:26 GMT
Lines: 658
Subject: TMSCP bug, standalone xon/xoff, tcopy errors, fsck strings (#323)
Index: pdpuba/tmscp.c,pdpstand/prf.c,ucb/tcopy.c,etc/fsck/Makefile,dir.c 2.11BSD
Description:
1. Multiple TMSCP drives in a system were not being handled correctly.
2. The standalone disklabel program's output would become scrambled
if the console device needed to use XON/XOFF.
3. If tcopy(1) encountered any form of error it would simply print
"write error" or something equally informative. No indication was
giving as to the exact error returned from the kernel.
4. Fsck(8) had multiple repeated strings scattered thruout causing
almost 1kb of data space to be wasted.
Repeat-By:
1. mt -f /dev/rmt0 rew; mt -f /dev/rmt8 rew
An error ('busy') will be returned for the second command.
2. Have an LA120 or similar device as the system console and running
at 9600 baud. Run a standalone utility which produces copious
output and note that the printout becomes scrambled.
3. Copy a tape with 'tcopy /dev/rmt0 /dev/rmt88' and encounter a
error on the output tape. Note that 'write error, tcopy aborted'
is the only information printed out with no indication what error
occured.
4. Run strings on /etc/fsck ('strings /etc/fsck') and notice that
there are repeated instances of the various messages (such as
"DIRECTORY %s: LENGTH %ld NOT MULTIPLE of %d") present.
Fix:
1. It is likely that this bug was introduced during the rewrite of
the TMSCP driver to support the TU81+ cache. It is possible (but
somewhat less likely) this is a latent bug that just showed up a
couple days ago. Essentially the 'inuse' bit was being cleared
when the drive was close BUT the controller structure still had a
reference to the drive. The system would end up with the same
drive assigned to two different controllers. Ick.
2. Several of the screens/menus in the standalone disklabel program
produced sufficient output to overrun a hardcopy console device.
Thanks to Tim Shoppa for contributing a rudimentary xon/xoff
mechanism for the standalone I/O system. The only drawback
(unlikely to be a problem though) is that input from the keyboard
is ignored while waiting for the console device to issue the 'xon'.
3. In the process of trying to fix problem #1 I ran into tcopy's
overquiet nature - errors were obviously being encountered by tcopy
but the exact error code was not being reported. The err(3) and
strerror(3) routines were used to improve tcopy's error reporting.
Record sizes need to be printed using '%u' instead of '%d' in order
to handle 32kb records (32768 prints as -32768).
4. Fsck needs every bit of memory it can get for bitmaps, etc. No
sense wasting D space on repeated strings. Yes it would be nice
if the compiler could collapse shared strings but that still would
not obviate the need for xstr(1) because xstr collects shared strings
from an entire collection of modules. One minor change was needed
in dir.c for the initialization of a static structure (something
xstr can not handle). Other than that the only change was to the
Makefile.
To install this update: cut where indicated, saving to a file (/tmp/323)
and then:
patch -p0 < /tmp/323
cd /usr/src/ucb
make tcopy
install -m 755 -s tcopy /usr/ucb/tcopy
cd /usr/src/etc/fsck
make
install -m 755 -s fsck /etc/fsck
make clean
cd /sys/pdpstand
make
cp boot /boot
If you have boot tapes or other standalone boot media around you may
want to update them with the new standalone utilities at this time.
cd /sys/GENERIC
make
mv unix /genunix
If you have TMSCP devices present then you will want to recompile
the current kernel:
cd /sys/YOUR_KERNEL
make
make install
reboot
This and previous updates are available via anonymous FTP to either
FTP.IIPO.GTEGSC.COM or FTP.2BSD.COM in the directory /pub/2.11BSD.
=============================cut here=========================
*** /usr/src/sys/pdpuba/tmscp.c.old Fri May 17 22:36:05 1996
--- /usr/src/sys/pdpuba/tmscp.c Wed Jun 5 20:33:45 1996
***************
*** 1,6 ****
#define TMSDEBUG 1
! /* @(#)tmscp.c 1.7 (2.11BSD GTE) 1996/5/17 */
#if !defined(lint) && defined(DOSCCS)
static char *sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86";
--- 1,6 ----
#define TMSDEBUG 1
! /* @(#)tmscp.c 1.8 (2.11BSD GTE) 1996/6/5 */
#if !defined(lint) && defined(DOSCCS)
static char *sccsid = "@(#)tmscp.c 1.24 (ULTRIX) 1/21/86";
***************
*** 244,250 ****
memaddr tmscp[NTMSCP]; /* click addresses of ctrl comm area */
/*
! * Bit definitions for Tflags word above. These take the place of several
* individual structure members in tms_info.
*/
--- 244,250 ----
memaddr tmscp[NTMSCP]; /* click addresses of ctrl comm area */
/*
! * Tflags definitions. These take the place of several
* individual structure members in tms_info.
*/
***************
*** 356,372 ****
struct tms_info *
getdd()
! {
! register int i;
register struct tms_info *p;
! for (i = NTMS, p = tms_info; i--; p++) {
! if ((p->Tflags & _INUSE) == 0)
return(p);
! }
log(LOG_INFO, "tms: !drives\n");
return(NULL);
! }
static int
wait_step(mask, good, csr, sc)
--- 356,380 ----
struct tms_info *
getdd()
! {
register struct tms_info *p;
! for (p = tms_info; p < &tms_info[NTMS]; p++)
! {
! if (p->tms_type == 0)
! {
! /*
! * Set the type with a placeholder value - we may have to sleep waiting for
! * the drive to come on line and we don't want this slot to be grabbed again.
! * The online response will load the real drive type.
! */
! p->tms_type = 1; /* XXX */
return(p);
! }
! }
log(LOG_INFO, "tms: !drives\n");
return(NULL);
! }
static int
wait_step(mask, good, csr, sc)
***************
*** 578,587 ****
tms = getdd();
if (!tms)
return(ENXIO);
! tms->Tflags &= ~_ONLINE;
sc->sc_drives[unit] = tms;
}
! if (tms->Tflags & _INUSE)
return(EBUSY);
tms->Tflags |= _INUSE;
--- 586,595 ----
tms = getdd();
if (!tms)
return(ENXIO);
! tms->Tflags = 0;
sc->sc_drives[unit] = tms;
}
! else if (tms->Tflags & _INUSE)
return(EBUSY);
tms->Tflags |= _INUSE;
***************
*** 592,597 ****
--- 600,608 ----
if (!tkini(sc))
{
log(LOG_INFO, "tms%d init fail\n", ctlr);
+ sc->sc_drives[unit] = NULL;
+ tms->Tflags = 0;
+ tms->tms_type = 0;
(void) splx(s);
return(ENXIO);
}
***************
*** 603,609 ****
if (sc->sc_state != S_RUN)
{
sc->sc_drives[unit] = NULL;
! tms->Tflags &= ~(_INUSE | _ONLINE);
(void) splx(s);
return(EIO);
}
--- 614,621 ----
if (sc->sc_state != S_RUN)
{
sc->sc_drives[unit] = NULL;
! tms->Tflags = 0;
! tms->tms_type = 0;
(void) splx(s);
return(EIO);
}
***************
*** 647,652 ****
--- 659,665 ----
if (!(tms->Tflags & _ONLINE))
{
oops: tms->Tflags = 0;
+ tms->tms_type = 0;
sc->sc_drives[unit] = NULL;
return(ENXIO); /* Didn't go online */
}
***************
*** 717,723 ****
tms->tms_flags &= ~MTF_CSE;
if (tms->Tflags & _WRITTEN)
tms_wrteof(dev, tms);
! tms->Tflags &= ~(_WRITTEN | _BUFMARK |_INUSE);
if ((dev & T_NOREWIND) == 0)
{
tmscpcommand(dev, TMS_REW, 0);
--- 730,736 ----
tms->tms_flags &= ~MTF_CSE;
if (tms->Tflags & _WRITTEN)
tms_wrteof(dev, tms);
! tms->Tflags &= ~(_WRITTEN | _BUFMARK | _INUSE);
if ((dev & T_NOREWIND) == 0)
{
tmscpcommand(dev, TMS_REW, 0);
*** /usr/src/sys/pdpstand/prf.c.old Sun Jun 4 12:02:42 1995
--- /usr/src/sys/pdpstand/prf.c Tue Jun 4 22:32:48 1996
***************
*** 3,9 ****
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)prf.c 1.3 (2.11BSD) 1995/06/04
*/
#include "../machine/cons.h"
--- 3,9 ----
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
! * @(#)prf.c 1.4 (2.11BSD) 1996/06/04
*/
#include "../machine/cons.h"
***************
*** 80,90 ****
if ((KLADDR->dlrbuf & 0177) == 0)
return;
#endif
- timo = 60000;
/*
* Try waiting for the console tty to come ready,
* otherwise give up after a reasonable time.
*/
while ((KLADDR->dlxcsr & DLXCSR_TRDY) == 0)
if (--timo == 0)
break;
--- 80,97 ----
if ((KLADDR->dlrbuf & 0177) == 0)
return;
#endif
/*
+ * If we got a XOFF, wait for a XON
+ */
+ if ((KLADDR->dlrcsr & DL_RDONE) != 0)
+ if ((KLADDR->dlrbuf & 0177) == 19)
+ while ((KLADDR->dlrbuf & 0177) != 17)
+ continue;
+ /*
* Try waiting for the console tty to come ready,
* otherwise give up after a reasonable time.
*/
+ timo=60000;
while ((KLADDR->dlxcsr & DLXCSR_TRDY) == 0)
if (--timo == 0)
break;
*** /usr/src/etc/fsck/Makefile.old Fri Apr 20 09:33:41 1990
--- /usr/src/etc/fsck/Makefile Wed May 8 22:06:07 1996
***************
*** 3,13 ****
# All rights reserved. The Berkeley software License Agreement
# specifies the terms and conditions for redistribution.
#
! # @(#)Makefile 5.8 (Berkeley) 9/7/85
#
DESTDIR=
CFLAGS= -O
LFLAGS= -i
# The program itself
#
--- 3,14 ----
# All rights reserved. The Berkeley software License Agreement
# specifies the terms and conditions for redistribution.
#
! # @(#)Makefile 5.8.1 (2.11BSD) 1996/5/8
#
DESTDIR=
CFLAGS= -O
LFLAGS= -i
+ XSTR= /usr/ucb/xstr
# The program itself
#
***************
*** 28,44 ****
#
HDRS= fsck.h
! ${PROG}: ${OBJS} ${HDRS}
! cc ${LFLAGS} -o ${PROG} ${OBJS}
! ${LOCOBJS}:
! cc ${CFLAGS} -c $*.c
install: ${PROG}
install -s ${PROG} ${DESTDIR}/etc/${PROG}
clean:
! rm -f a.out core ${OBJS} ${PROG}
lint:
lint ${INCPATH} ${SRCS}
--- 29,54 ----
#
HDRS= fsck.h
! ${PROG}: ${OBJS} ${HDRS} strings.o
! cc ${LFLAGS} -o ${PROG} ${OBJS} strings.o
! .c.o:
! cc -E ${CFLAGS} $*.c | ${XSTR} -c -
! cc ${CFLAGS} -c x.c
! mv -f x.o $*.o
! rm -f x.c
+ strings.o: strings
+ ${XSTR}
+ cc -c xs.c
+ mv -f xs.o strings.o
+ rm -f xs.c
+
install: ${PROG}
install -s ${PROG} ${DESTDIR}/etc/${PROG}
clean:
! rm -f a.out core ${OBJS} ${PROG} strings.o x.c xs.c strings
lint:
lint ${INCPATH} ${SRCS}
*** /usr/src/etc/fsck/dir.c.old Sat Sep 15 20:16:11 1990
--- /usr/src/etc/fsck/dir.c Wed May 8 21:54:45 1996
***************
*** 5,11 ****
*/
#if !defined(lint) && defined(DOSCCS)
! static char sccsid[] = "@(#)dir.c 5.1 (Berkeley) 6/5/85";
#endif not lint
#include <sys/param.h>
--- 5,11 ----
*/
#if !defined(lint) && defined(DOSCCS)
! static char sccsid[] = "@(#)dir.c 5.1.1 (2.11BSD) 1996/5/8";
#endif not lint
#include <sys/param.h>
***************
*** 19,25 ****
char *endpathname = &pathname[MAXPATHLEN - 2];
char *lfname = "lost+found";
struct dirtemplate emptydir = { 0, DIRBLKSIZ };
! struct dirtemplate dirhead = { 0, 8, 1, ".", 0, DIRBLKSIZ - 8, 2, ".." };
DIRECT *fsck_readdir();
--- 19,32 ----
char *endpathname = &pathname[MAXPATHLEN - 2];
char *lfname = "lost+found";
struct dirtemplate emptydir = { 0, DIRBLKSIZ };
! /*
! * The strange initialization is due to quoted strings causing problems when
! * 'xstr' is used to preprocess the sources. The structure has two members
! * as 'char dot_name[2]' and 'char dotdot_name[6]' which is NOT the same as
! * 'char *'.
! */
! struct dirtemplate dirhead = { 0, 8, 1, {'.'}, 0, DIRBLKSIZ - 8, 2,
! {'.', '.' }};
DIRECT *fsck_readdir();
***************
*** 322,329 ****
}
}
if (lfdir == 0) {
! pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY");
! printf("\n\n");
return (0);
}
}
--- 329,335 ----
}
}
if (lfdir == 0) {
! pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n");
return (0);
}
}
*** /usr/src/ucb/tcopy.c.old Sat Jan 1 02:14:53 1994
--- /usr/src/ucb/tcopy.c Fri Jun 7 20:14:18 1996
***************
*** 9,15 ****
"@(#) Copyright (c) 1985 Regents of the University of California.\n\
All rights reserved.\n";
! static char sccsid[] = "@(#)tcopy.c 1.3 (2.11BSD GTE) 1/1/94";
#endif
#include <stdio.h>
--- 9,15 ----
"@(#) Copyright (c) 1985 Regents of the University of California.\n\
All rights reserved.\n";
! static char sccsid[] = "@(#)tcopy.c 1.4 (2.11BSD GTE) 1996/6/4";
#endif
#include <stdio.h>
***************
*** 18,40 ****
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
- #ifdef pdp11
#define SIZE ((unsigned)32 * 1024)
- #else
- #define SIZE (64 * 1024)
- #endif
char buff[SIZE];
int filen=1;
long count, lcount;
int RUBOUT();
- long itol();
int nfile;
long size, tsize;
int ln;
char *inf, *outf;
int copy;
main(argc, argv)
char **argv;
--- 18,39 ----
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
+ #include <string.h>
+ #include <errno.h>
#define SIZE ((unsigned)32 * 1024)
char buff[SIZE];
int filen=1;
long count, lcount;
int RUBOUT();
int nfile;
long size, tsize;
int ln;
char *inf, *outf;
int copy;
+ static char *msg1= "file %d: records %ld to %ld: size %u\n";
+ static char *msg2 = "file %d: record %ld: size %u\n";
main(argc, argv)
char **argv;
***************
*** 51,65 ****
outf = argv[2];
copy = 1;
}
! if ((inp=open(inf, O_RDONLY, 0666)) < 0) {
! fprintf(stderr,"Can't open %s\n", inf);
! exit(1);
! }
if (copy) {
! if ((outp=open(outf, O_WRONLY, 0666)) < 0) {
! fprintf(stderr,"Can't open %s\n", outf);
! exit(3);
! }
}
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
(void) signal(SIGINT, RUBOUT);
--- 50,61 ----
outf = argv[2];
copy = 1;
}
! if ((inp=open(inf, O_RDONLY, 0666)) < 0)
! err(1, "Can't open %s", inf);
!
if (copy) {
! if ((outp=open(outf, O_WRONLY, 0666)) < 0)
! err(3, "Can't open %s", outf);
}
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
(void) signal(SIGINT, RUBOUT);
***************
*** 71,79 ****
nw = write(outp, buff, n);
if (copy) {
if (nw != n) {
! fprintf(stderr, "write (%d) != read (%d)\n",
! nw, n);
! fprintf(stderr, "COPY Aborted\n");
exit(5);
}
}
--- 67,83 ----
nw = write(outp, buff, n);
if (copy) {
if (nw != n) {
! int error = errno;
! if (nw == -1)
! fprintf(stderr, "write error, file %d, record %ld: ",
! filen, lcount);
! if (nw == -1)
! fprintf(stderr, "%s",strerror(error));
! else
! fprintf(stderr,
! "write (%u) != read (%u)\n",
! nw, n);
! fprintf(stderr, "copy aborted\n");
exit(5);
}
}
***************
*** 81,91 ****
if (n != ln) {
if (ln > 0)
if (count - lcount > 1)
! printf("file %d: records %ld to %ld: size %d\n",
! filen, lcount, count-1, ln);
else
! printf("file %d: record %ld: size %d\n",
! filen, lcount, ln);
ln = n;
lcount = count;
}
--- 85,93 ----
if (n != ln) {
if (ln > 0)
if (count - lcount > 1)
! printf(msg1, filen, lcount, count-1, ln);
else
! printf(msg2, filen, lcount, ln);
ln = n;
lcount = count;
}
***************
*** 97,107 ****
}
if (ln > 0)
if (count - lcount > 1)
! printf("file %d: records %ld to %ld: size %d\n",
! filen, lcount, count-1, ln);
else
! printf("file %d: record %ld: size %d\n",
! filen, lcount, ln);
printf("file %d: eof after %ld records: %ld bytes\n",
filen, count-1, size);
if (copy) {
--- 99,107 ----
}
if (ln > 0)
if (count - lcount > 1)
! printf(msg1, filen, lcount, count-1, ln);
else
! printf(msg2, filen, lcount, ln);
printf("file %d: eof after %ld records: %ld bytes\n",
filen, count-1, size);
if (copy) {
***************
*** 133,145 ****
--count;
if (count)
if (count > lcount)
! printf("file %d: records %ld to %ld: size %d\n",
! filen, lcount, count, ln);
else
! printf("file %d: record %ld: size %d\n",
! filen, lcount, ln);
printf("rubout at file %d: record %ld\n", filen, count);
printf("total length: %ld bytes\n", tsize+size);
exit(1);
}
-
--- 133,142 ----
--count;
if (count)
if (count > lcount)
! printf(msg1, filen, lcount, count, ln);
else
! printf(msg2, filen, lcount, ln);
printf("rubout at file %d: record %ld\n", filen, count);
printf("total length: %ld bytes\n", tsize+size);
exit(1);
}
*** /VERSION.old Fri May 24 22:05:47 1996
--- /VERSION Fri Jun 7 19:57:45 1996
***************
*** 1,4 ****
! Current Patch Level: 322
2.11 BSD
============
--- 1,4 ----
! Current Patch Level: 323
2.11 BSD
============