Subject: RL&XP iostats wrong, llib-lc update, opening mounted disks (#291) Index: pdpuba/rl.c,xp.c,sys/sys_inode.c,lib/lint/llib-lc 2.11BSD Description: The UCB_METER code in the RL and XP drivers was wrong. The drive statistics were not being totaled where 'iostat' expected them and in the case of the XP driver the words/second field was not initialized correctly. When statfs(2), fstatfs(2), getfsstat(2) and getmntinfo(3) were added to the system the lint library for libc was not updated. When the system is in secure or very secure mode opens should be denied for block disk devices on which filesystems are mounted. Repeat-By: Have RL or XP drives present in the system and start 'iostat' running. Note that the statistics are always 0. Run lint over a program containing references to the 'statfs' family of system calls. Note the lack of checking for proper use of the functions. As root (or a user with group id of operator) open the block (non-raw) device of / when the system is in secure (securelevel=1) or very secure (securelevel=2) mode. Note that the open will succeed. Fix: Thanks to Tim Shoppa (shoppa@krl.caltech.edu) for spotting and fixing the problems in the RL+XP drivers as well as the off by a factor of 1000 in iostat's calulation of transfer times. The check in sys_inode.c for opening the block device of a mounted filesystem was already present but ifdef'd out pending the implem- tation of the 'statfs' system calls. Since those system calls are now present the security check can be enabled. To install this update cut where indicated, saving to a file (/tmp/291) and then: patch -p0 < /tmp/291 cd /usr/src/usr.bin make iostat install -s -m 2755 -g kmem iostat /usr/bin cd /usr/src/usr.bin/lint ./libs Then, if you have RL or XP drives present in the system you may wish (especially if you have UCB_METER enabled) recompile your kernel to incorporate the changes to those drivers. This and previous updates to 2.11BSD are available via anonymous FTP to the system FTP.IIPO.GTEGSC.COM in the directory /pub/2.11BSD. ------------------------------cut here--------------------------- *** /usr/lib/lint/llib-lc.old Sun Sep 10 17:27:40 1995 --- /usr/lib/lint/llib-lc Mon Jan 1 14:35:45 1996 *************** *** 1,4 **** ! /* @(#)llib-lc 1.40 (2.11BSD GTE) 1995/09/10 */ /* LINTLIBRARY */ --- 1,4 ---- ! /* @(#)llib-lc 1.41 (2.11BSD GTE) 1996/1/1 */ /* LINTLIBRARY */ *************** *** 6,11 **** --- 6,12 ---- #include #include + #include #include #include #include *************** *** 66,71 **** --- 67,73 ---- int fperr(f) struct fperr *f; { return(0); } int fsync( f ) { return 0; } int fstat(f, b) struct stat *b; { return(0); } + int fstatfs(f, b) int f; struct statfs *b; { return(0); } int ftruncate( d, l) off_t l; { return 0;} int getdtablesize() { return 20 ; } gid_t getegid() { return((gid_t)1); } *************** *** 76,81 **** --- 78,84 ---- int gethostname( n, l ) char *n; int l; { return 0 ;} int getitimer( w, v ) struct itimerval *v; { return 0; } int getloadavg( d, n) double d[]; int n; { return 0; } + int getmntinfo(b, f) struct statfs **b; int f; { return (0); } int getpagesize() { return 1; } int getpeername(s, n, l) struct sockaddr *n; int *l; { return (0); } int getpgrp(p) { return 1; } *************** *** 86,91 **** --- 89,95 ---- int getrusage( res, rip) struct rusage *rip; { return 0;} int getsockname(s, name, namelen) char *name; int *namelen; { return(0); } int getsockopt( s, level, opt, buf, len ) char *buf; int *len; { return 0;} + int getstatfs(b, s, f) struct statfs *b; int s, f; { return(0); } int gettimeofday( t, z ) struct timeval *t; struct timezone *z; { return 0;} uid_t getuid() { return((uid_t)1); } int ioctl( d, r, p) u_long r; char *p; { return 0;} *************** *** 157,162 **** --- 161,167 ---- int socket( a, t, p) {return 1;} int socketpair( d, t, p, s ) int s[2]; { return 0; } int stat(s, b) char *s; struct stat *b; { return(0); } + int statfs(s, b) char *s; struct statfs *b; { return(0); } #ifdef notdef char * stk( a ) char * a; { return a; } char * sstk( a ) int a; { return (char *)0; } *** /usr/src/sys/pdpuba/rl.c.old Mon Nov 27 20:40:01 1995 --- /usr/src/sys/pdpuba/rl.c Mon Jan 8 20:15:34 1996 *************** *** 3,14 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)rl.c 1.7 (2.11BSD GTE) 1995/11/27 */ /* * RL01/RL02 disk driver * * Date: November 27, 1995 * Add support for using the software unibus/qbus map. This allows 3rd * party 18bit RL controllers (DSD-880) to be used in a 22bit Qbus system. --- 3,17 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)rl.c 1.8 (2.11BSD GTE) 1996/1/8 */ /* * RL01/RL02 disk driver * + * Date: January 7, 1996 + * Fix broken UCB_METER statistics gathering. + * * Date: November 27, 1995 * Add support for using the software unibus/qbus map. This allows 3rd * party 18bit RL controllers (DSD-880) to be used in a 22bit Qbus system. *************** *** 103,111 **** { #ifdef UCB_METER if (rl_dkn < 0) { ! dk_alloc(&rl_dkn, NRL+1, "rl", 20L * 10L * 512L); ! if (rl_dkn >= 0) ! dk_wps[rl_dkn+NRL] = 0L; } #endif --- 106,112 ---- { #ifdef UCB_METER if (rl_dkn < 0) { ! dk_alloc(&rl_dkn, NRL, "rl", 20L * 10L * 512L); } #endif *************** *** 442,448 **** bp = rltab.b_actf; #ifdef UCB_METER if (rl_dkn >= 0) ! dk_busy &= ~((1 << (rl_dkn + rl.dn)) | (1 << (rl_dkn + NRL))); #endif if (rladdr->rlcs & RL_CERR) { if (rladdr->rlcs & RL_HARDERR && rltab.b_errcnt > 2) { --- 443,449 ---- bp = rltab.b_actf; #ifdef UCB_METER if (rl_dkn >= 0) ! dk_busy &= ~(1 << (rl_dkn + rl.dn)); #endif if (rladdr->rlcs & RL_CERR) { if (rladdr->rlcs & RL_HARDERR && rltab.b_errcnt > 2) { *************** *** 518,524 **** rladdr->rlcs = rl.com | (rl.rl_un.w[0] & 03) << 4; #ifdef UCB_METER if (rl_dkn >= 0) { ! int dkn = rl_dkn + NRL; dk_busy |= 1<rlcs = rl.com | (rl.rl_un.w[0] & 03) << 4; #ifdef UCB_METER if (rl_dkn >= 0) { ! int dkn = rl_dkn + rl.dn; dk_busy |= 1<= NXPC) --- 143,151 ---- static int last_attached = -1; #ifdef UCB_METER ! if (xp_dkn < 0) { ! dk_alloc(&xp_dkn, NXPD, "xp", 0L); ! } #endif if ((unsigned)unit >= NXPC) *************** *** 249,256 **** if (part >= i) return(ENXIO); #ifdef UCB_METER ! if (xp_dkn >= 0) ! dk_wps[xd - xp_drive] = (long) xd->xp_nsect * (rpm / 60) * 256L; #endif mask = 1 << part; dkoverlapchk(xd->xp_open, dev, xd->xp_label, "xp"); --- 250,258 ---- if (part >= i) return(ENXIO); #ifdef UCB_METER ! if (xp_dkn >= 0) { ! dk_wps[xp_dkn+unit] = (long) xd->xp_nsect * (rpm / 60) * 256L; ! } #endif mask = 1 << part; dkoverlapchk(xd->xp_open, dev, xd->xp_label, "xp"); *************** *** 474,481 **** xpaddr->hpcs1.c[0] = HP_IE; xpaddr->hpas = 1 << xd->xp_unit; #ifdef UCB_METER ! if (xp_dkn >= 0) dk_busy &= ~(1 << (xp_dkn + unit)); #endif dp = &xputab[unit]; if ((bp=dp->b_actf) == NULL) --- 476,484 ---- xpaddr->hpcs1.c[0] = HP_IE; xpaddr->hpas = 1 << xd->xp_unit; #ifdef UCB_METER ! if (xp_dkn >= 0) { dk_busy &= ~(1 << (xp_dkn + unit)); + } #endif dp = &xputab[unit]; if ((bp=dp->b_actf) == NULL) *************** *** 675,683 **** xpaddr->hpcs1.w = unit; #ifdef UCB_METER if (xp_dkn >= 0) { ! int dkn = xp_dkn + NXPD + (xc - &xp_controller[0]); dk_busy |= 1<b_bcount>>6; } --- 678,687 ---- xpaddr->hpcs1.w = unit; #ifdef UCB_METER if (xp_dkn >= 0) { ! int dkn = xp_dkn + XPUNIT(bp->b_dev); dk_busy |= 1<b_bcount>>6; } *************** *** 702,711 **** xpaddr = xc->xp_addr; as = xpaddr->hpas & 0377; if (xc->xp_active) { - #ifdef UCB_METER - if (xp_dkn >= 0) - dk_busy &= ~(1 << (xp_dkn + NXPD + dev)); - #endif /* * Get device and block structures. Select the drive. */ --- 706,711 ---- *************** *** 717,722 **** --- 717,727 ---- return; #endif unit = XPUNIT(bp->b_dev); + #ifdef UCB_METER + if (xp_dkn >= 0) { + dk_busy &= ~(1 << (xp_dkn + unit)); + } + #endif xd = &xp_drive[unit]; xpaddr->hpcs2.c[0] = xd->xp_unit; /* *** /usr/src/sys/sys/sys_inode.c.old Sun May 21 17:04:37 1995 --- /usr/src/sys/sys/sys_inode.c Fri Dec 29 23:10:37 1995 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)sys_inode.c 1.5 (2.11BSD GTE) 1995/05/21 */ #include "param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)sys_inode.c 1.6 (2.11BSD GTE) 1995/12/29 */ #include "param.h" *************** *** 651,657 **** */ if (securelevel >= 2 && (mode & FWRITE) && isdisk(dev, IFBLK)) return(EPERM); - #ifdef notyet /* * Do not allow opens of block devices that are * currently mounted. --- 651,656 ---- *************** *** 659,672 **** * 2.11BSD must relax this restriction to allow 'fsck' to * open the root filesystem (which is always mounted) during * a reboot. Once in secure or very secure mode the ! * above restriction is fully effective. ! * ! * Also, 'df' on 2.11BSD opens the device - this check can ! * not be enabled until the 'statfs' capability is present. */ if (securelevel > 0 && (error = ufs_mountedon(dev))) return(error); - #endif return ((*bdevsw[maj].d_open)(dev, mode, S_IFBLK)); } return (0); --- 658,668 ---- * 2.11BSD must relax this restriction to allow 'fsck' to * open the root filesystem (which is always mounted) during * a reboot. Once in secure or very secure mode the ! * above restriction is fully effective. On the otherhand ! * fsck should 1) use the raw device, 2) not do sync calls... */ if (securelevel > 0 && (error = ufs_mountedon(dev))) return(error); return ((*bdevsw[maj].d_open)(dev, mode, S_IFBLK)); } return (0); *** /usr/src/usr.bin/iostat.c.old Tue Jan 12 05:58:57 1988 --- /usr/src/usr.bin/iostat.c Mon Jan 8 20:19:17 1996 *************** *** 1,5 **** ! #ifndef lint ! static char *sccsid = "@(#)iostat.c 4.15 (Berkeley) 87/01/12"; #endif /* --- 1,5 ---- ! #if !defined(lint) && defined(DOSCCS) ! static char *sccsid = "@(#)iostat.c 4.16 (2.11BSD) 1996/1/8"; #endif /* *************** *** 248,257 **** return; } atime = s.dk_time[dn]; ! atime /= (float) hz; words = (double)s.dk_wds[dn]*32.0; /* number of words transferred */ ! xtime = (double)dk_mspw[dn]*words; /* transfer time */ ! itime = atime - xtime; /* time not transferring */ if (xtime < 0) itime += xtime, xtime = 0; if (itime < 0) --- 248,257 ---- return; } atime = s.dk_time[dn]; ! atime /= (float) hz; /* time controller busy, seconds */ words = (double)s.dk_wds[dn]*32.0; /* number of words transferred */ ! xtime = (double)dk_mspw[dn]*words/1000.;/* transfer time , seconds */ ! itime = atime - xtime; /* time busy but not transferring , seconds */ if (xtime < 0) itime += xtime, xtime = 0; if (itime < 0) *** /VERSION.old Fri Jan 5 21:32:28 1996 --- /VERSION Mon Jan 8 20:25:27 1996 *************** *** 1,4 **** ! Current Patch Level: 290 2.11 BSD ============ --- 1,4 ---- ! Current Patch Level: 291 2.11 BSD ============