*BSD News Article 53914


Return to BSD News archive

Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!simtel!chi-news.cic.net!news.wctc.net!spcuna!wlbr!sms
From: sms@wlv.iipo.gtegsc.com (Steven M. Schultz)
Subject: disklabels broke multi MSCP controller support (#277)
Sender: news@wlbr.iipo.gtegsc.com (System Administrator)
Organization: GTE Government Systems, Thousand Oaks CA USA
Message-ID: <DHAu1q.B2A@wlbr.iipo.gtegsc.com>
X-Nntp-Posting-Host: wlv.iipo.gtegsc.com
Date: Tue, 31 Oct 1995 06:01:02 GMT
Lines: 283

Subject: disklabels broke multi MSCP controller support (#277)
Index:	pdpuba/ra.c,sys/kern_sysctl.c 2.11BSD

Description:
	1) When disklabels were implemented the support for multiple
	MSCP controllers was broken.

	2) The network sysctl function was not #ifdef'd on INET.

Repeat-By:
	1) Have two MSCP controllers in the system.  Copy files from the
	first drive on the first controller to the first drive on the
	second controller.  Notice the filesystem corruption on both
	drives.

	2) Attempt to build a GENERIC kernel after installing update #276.
	   Note that two undefined symbols (KScall and net_sysctl) appear.
Fix:
	Apply the following patch, recompile and install the kernel.  If,
	as is a good idea, you have a copy of the GENERIC kernel present 
	(as /genunix) you should also recompile that kernel and install it.

	The MSCP bug was a stupid mistake - I must have  been hallucinating
	at the time.  The 'buffer header' for each drive must be present
	in the 'drive info structure' and not in a parallel array.  This
	is because the first drive on all controllers is "unit 0".  The
	unit number is not unique within the driver.   NOTE: the combination
	of controller number _and_ unit number is unique and this is what
	should have been used in the first place.

	In the case of the sysctl system call I simply overlooked the 
	fact that not all kernels are configured for networking.

	Cut where indicated, saving to a file (/tmp/277) and then:

		patch -p0 < /tmp/277

		cd /sys/YOUR_KERNEL_NAME
		make clean
		make
		make install
		reboot

		cd /sys/GENERIC
		make clean
		make
		mv unix /genunix

=========================cut here========================
*** /sys/pdpuba/ra.c.old	Tue Aug  1 22:21:45 1995
--- /sys/pdpuba/ra.c	Mon Oct 30 19:48:46 1995
***************
*** 3,9 ****
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	3.0 (2.11BSD GTE) 1995/08/01
   */
  
   /***********************************************************************
--- 3,9 ----
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)ra.c	3.1 (2.11BSD GTE) 1995/10/28
   */
  
   /***********************************************************************
***************
*** 14,19 ****
--- 14,25 ----
  
  /* 
   * ra.c - MSCP Driver
+  * Date:	October 28, 1995
+  * Fix multicontroller support (which was badly broken when disklabels were 
+  * added).  Accessing drives on the second controller would cause serious 
+  * filesystem corruption on the the corresponding drives on the first 
+  * controller.
+  *
   * Date:	August 1, 1995
   * Fix a bug which prohibited labeling previously disks which were unlabeled 
   * or had a corrupted label.  The default ('a' partition spanning the volume)
***************
*** 127,132 ****
--- 133,142 ----
  #include "file.h"
  #include "stat.h"
  
+ #ifndef	offsetof
+ #define	offsetof(type,member) ((size_t)(&((type *)0)->member))
+ #endif
+ 
  #define	RACON(x)			((minor(x) >> 6) & 03)
  #define	RAUNIT(x)			((minor(x) >> 3) & 07)
  
***************
*** 168,173 ****
--- 178,184 ----
  	struct  dkdevice   ra_dk;	/* General disk info structure */
  	daddr_t		ra_nblks;	/* Volume size from online pkt */
  	short		ra_unit;	/* controller unit # */
+ 	struct	buf	ra_utab;	/* buffer header for drive */
  } ra_infoT;
  
  #define	ra_bopen	ra_dk.dk_bopenmask
***************
*** 195,201 ****
  ra_softcT	ra_sc[NRAC];	/* Controller table */
  memaddr		ra_com[NRAC];	/* Communications area table */
  ra_infoT	ra_disks[NRAD];	/* Disk table */
- struct	buf	rautab[NRAD];	/* per drive transfer queue */
  
  #define	MAPSEGDESC	(((btoc(sizeof (ra_comT))-1)<<8)|RW)
  
--- 206,211 ----
***************
*** 496,503 ****
  		{
  		disk->ra_flags |= DKF_CLOSING;
  		s = splbio();
! 		while	(rautab[unit].b_actf)
! 			sleep(&rautab[unit], PRIBIO);
  		splx(s);
  		disk->ra_flags &= ~DKF_CLOSING;
  		wakeup(disk);
--- 506,513 ----
  		{
  		disk->ra_flags |= DKF_CLOSING;
  		s = splbio();
! 		while	(disk->ra_utab.b_actf)
! 			sleep(&disk->ra_utab, PRIBIO);
  		splx(s);
  		disk->ra_flags &= ~DKF_CLOSING;
  		wakeup(disk);
***************
*** 679,685 ****
  	 * Link the buffer onto the drive queue
  	 */
  	s = splbio();
! 	dp = &rautab[unit];
  	if (dp->b_actf == 0)
  		dp->b_actf = bp;
  	else
--- 689,695 ----
  	 * Link the buffer onto the drive queue
  	 */
  	s = splbio();
! 	dp = &disk->ra_utab;
  	if (dp->b_actf == 0)
  		dp->b_actf = bp;
  	else
***************
*** 757,763 ****
  		 */
  		dp->b_active = 0;
  		sc->sc_ctab.b_actf = dp->b_forw;
! 		disk = sc->sc_drives[dp - rautab];
  		if	(disk->ra_open == 0)
  			wakeup(dp);	/* finish close protocol */
  		goto loop;
--- 767,774 ----
  		 */
  		dp->b_active = 0;
  		sc->sc_ctab.b_actf = dp->b_forw;
! 		i = offsetof(ra_infoT, ra_utab);
! 		disk = (ra_infoT *)((int)dp - i);
  		if	(disk->ra_open == 0)
  			wakeup(dp);	/* finish close protocol */
  		goto loop;
***************
*** 1101,1107 ****
  				mp->m_unit);
  			break;
  		}
! 		dp = &rautab[mp->m_unit];
  
  		if (st == M_S_SUCC) {
  			/* Link the drive onto the controller queue */
--- 1112,1118 ----
  				mp->m_unit);
  			break;
  		}
! 		dp = &disk->ra_utab;
  
  		if (st == M_S_SUCC) {
  			/* Link the drive onto the controller queue */
***************
*** 1154,1160 ****
  		 */
  		bp->av_back->av_forw = bp->av_forw;
  		bp->av_forw->av_back = bp->av_back;
! 		dp = &rautab[mp->m_unit];
  
  #ifdef UCB_METER
  		if (ra_dkn >= 0) {
--- 1165,1171 ----
  		 */
  		bp->av_back->av_forw = bp->av_forw;
  		bp->av_forw->av_back = bp->av_back;
! 		dp = &disk->ra_utab;
  
  #ifdef UCB_METER
  		if (ra_dkn >= 0) {
*** /sys/sys/kern_sysctl.c.old	Mon Oct  9 21:44:28 1995
--- /sys/sys/kern_sysctl.c	Sun Oct 29 00:08:01 1995
***************
*** 33,39 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)kern_sysctl.c	8.4.2 (2.11BSD GTE) 1995/10/09
   */
  
  /*
--- 33,39 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *	@(#)kern_sysctl.c	8.4.3 (2.11BSD GTE) 1995/10/29
   */
  
  /*
***************
*** 64,71 ****
--- 64,73 ----
  #endif
  sysctlfn vm_sysctl;
  sysctlfn fs_sysctl;
+ #ifdef	INET
  sysctlfn NET_SYSCTL;
  extern	int	net_sysctl();	/* In supervisor space */
+ #endif
  sysctlfn cpu_sysctl;
  
  /*
***************
*** 115,123 ****
--- 117,127 ----
  	case CTL_VM:
  		fn = vm_sysctl;
  		break;
+ #ifdef	INET
  	case CTL_NET:
  		fn = NET_SYSCTL;
  		break;
+ #endif
  #ifdef notyet
  	case CTL_FS:
  		fn = fs_sysctl;
***************
*** 360,365 ****
--- 364,370 ----
  }
  #endif /* DEBUG */
  
+ #ifdef	INET
  /*
   * In 4.4BSD-Lite these functions were scattered amoungst the various
   * subsystems they dealt with.
***************
*** 387,392 ****
--- 392,398 ----
  	return(KScall(net_sysctl, 6 * sizeof (int),
  			name, namelen, oldp, oldlenp, newp, newlen));
  }
+ #endif
  
  /*
   * Rather useless - but it's not very big so let's do it.
*** /VERSION.old	Sat Oct 21 18:12:06 1995
--- /VERSION	Sat Oct 28 20:38:28 1995
***************
*** 1,4 ****
! Current Patch Level: 276
  
  2.11 BSD
  ============
--- 1,4 ----
! Current Patch Level: 277
  
  2.11 BSD
  ============