Subject: port-i386/31503: feature/bug in fdisk on i386
To: None <port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Wolfgang Stukenbrock <wgstuken@s012.nagler-company.com>
List: netbsd-bugs
Date: 10/07/2005 12:24:00
>Number:         31503
>Category:       port-i386
>Synopsis:       fdisk on i386 will fail to setup new empty disks
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Oct 07 12:24:00 +0000 2005
>Originator:     Wolfgang Stukenbrock
>Release:        NetBSD 2.0.2
>Organization:
Dr. Nagler & Comapny GmbH
>Environment:
	
	
System: NetBSD s012 2.0_RC5 NetBSD 2.0_RC5 (S012) #6: Tue Nov 30 11:38:39 CET 2004 wgstuken@s012:/export/netbsd-2.0rc4/src/sys/arch/i386/compile/S012 i386
Architecture: i386
Machine: i386
>Description:
	If multiple new disks of different size are added to a system, fdisk will
	fail to setup theese disks.
	The problem is, that theese new disk have no valid sector 0 and are placed
	in the same "match-group" by the kernel when the diskinformation is retrieved
	by fdisk.
	fdisk will determine the correct number of disksectors from the NetBSD-disklabel,
	but will use always the first entry in the "match-group" of disks.
	If disks of different size are added, the first entry may have a wrong number of
	disksectors and so the dos-disksector variable will be wrong.
	If the retrieved entry is smaller than the selected disk, only a part of the disk
	may be setup by fdisk and the wrong number of disksectors will be stored in sector 0.
	The reamining space of the disk is lost forever ...

	This problem may be fixed be searching for an entry in the "match-group" with the
	same number of disksectors as retrieved from the NetBSD-disklabel.
	The BIOS-Information for the disk retrieved from the selected "match-entry" is only
	used to setup the number of heads etc. and this information is fictivious for all
	kind of acual disks on i386 platforms.

	The fix below added code to /usr/src/sbin/fdisk/fdisk.c to search for a disk with
	the same number of disksectors and gets the head, cyl and sector information from
	that disk.
	If none is found, a warning is printed and the first entry is slected as before.
	(perhaps fdisk should terminate if no match is found ...)

	Ths fix only affects a routine that belongs to the i386 and x86 port.
>How-To-Repeat:
	add several new emtpy disk to a i386 system, run fdisk and look ath the reported
	number of disksectors for NetBSD and BIOS label.
>Fix:
===================================================================
RCS file: RCS/fdisk.c,v
retrieving revision 1.1
diff -c -r1.1 fdisk.c
*** fdisk.c	2005/10/07 08:55:35	1.1
--- fdisk.c	2005/10/07 09:11:37
***************
*** 1034,1040 ****
  		 * just use them, we don't need to know which disk is which.
  		 */
  		if (nip->ni_nmatches != 0) {
! 			bip = &dl->dl_biosdisks[nip->ni_biosmatches[0]];
  			dos_cylinders = bip->bi_cyl;
  			dos_heads = bip->bi_head;
  			dos_sectors = bip->bi_sec;
--- 1034,1054 ----
  		 * just use them, we don't need to know which disk is which.
  		 */
  		if (nip->ni_nmatches != 0) {
! /* need to determine the correct index to use.
!  * there is a feature if we have empty disks, that all empty disk are placed in the same
!  * biosmatches group by the kernel.
!  * As a workaround we search for the correct number of blocks in the list an take that entry
!  */
! 			for (i = 0; i < nip->ni_nmatches; i++)
! 			  {
! 			    bip = &dl->dl_biosdisks[nip->ni_biosmatches[i]];
! 			    if (disksectors == bip->bi_lbasecs) break;
! 			  }
! 			if (i == nip->ni_nmatches)
! 			  {
! 			    bip = &dl->dl_biosdisks[nip->ni_biosmatches[0]];
! 			    printf("WARNING: no matching number of disksectors (%llu) found\n         reverting to old style and take first entry (%llu sectors)\n", disksectors, bip->bi_lbasecs);
! 			  }
  			dos_cylinders = bip->bi_cyl;
  			dos_heads = bip->bi_head;
  			dos_sectors = bip->bi_sec;