*BSD News Article 58519


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.mel.connect.com.au!munnari.OZ.AU!news.ecn.uoknor.edu!paladin.american.edu!europa.chnt.gtegsc.com!gatech!newsfeed.internetmci.com!in1.uu.net!news.new-york.net!wlbr!sms
From: sms@wlv.iipo.gtegsc.com (Steven M. Schultz)
Subject: RL&XP iostats wrong, llib-lc update, opening mounted disks (#291)
Sender: news@wlbr.iipo.gtegsc.com (System Administrator)
Organization: GTE Government Systems, Thousand Oaks CA USA
Message-ID: <DKwF3x.CLr@wlbr.iipo.gtegsc.com>
X-Nntp-Posting-Host: wlv.iipo.gtegsc.com
Date: Tue, 9 Jan 1996 05:26:21 GMT
Lines: 439

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 <sys/time.h>
  
  #include <sys/dir.h>
+ #include <sys/mount.h>
  #include <sys/resource.h>
  #include <sys/socket.h>
  #include <sys/stat.h>
***************
*** 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<<dkn;
  		dk_xfer[dkn]++;
--- 519,525 ----
  	rladdr->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<<dkn;
  		dk_xfer[dkn]++;
*** /usr/src/sys/pdpuba/xp.c.old	Tue Nov 21 19:55:21 1995
--- /usr/src/sys/pdpuba/xp.c	Mon Jan  8 20:13:52 1996
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	2.3 (2.11BSD GTE) 1995/11/20
   */
  
  /*
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)xp.c	2.4 (2.11BSD GTE) 1996/1/8
   */
  
  /*
***************
*** 143,150 ****
  	static int last_attached = -1;
  
  #ifdef UCB_METER
! 	if (xp_dkn < 0)
! 		dk_alloc(&xp_dkn, NXPD+NXPC, "xp", 0L);
  #endif
  
  	if ((unsigned)unit >= 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<<dkn;
  		dk_seek[dkn]++;
  		dk_wds[dkn] += bp->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<<dkn;
+ 		dk_xfer[dkn]++;
  		dk_seek[dkn]++;
  		dk_wds[dkn] += bp->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
  ============