From owner-freebsd-current Sun Jan 12 23:51:38 2003 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CE61337B401 for ; Sun, 12 Jan 2003 23:51:35 -0800 (PST) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by mx1.FreeBSD.org (Postfix) with ESMTP id AD70843ED8 for ; Sun, 12 Jan 2003 23:51:34 -0800 (PST) (envelope-from bde@zeta.org.au) Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id SAA04274; Mon, 13 Jan 2003 18:51:09 +1100 Date: Mon, 13 Jan 2003 18:51:44 +1100 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Nate Lawson Cc: Sean Kelly , Subject: Re: fdisk issues? In-Reply-To: Message-ID: <20030113181713.O11356-100000@gamplex.bde.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Sun, 12 Jan 2003, Nate Lawson wrote: > On Sun, 12 Jan 2003, Sean Kelly wrote: > > edgemaster# fdisk ad1 > > Floating exception (core dumped) > > > > In get_params, we have: > > ... > > 780 error = ioctl(fd, DIOCGFWSECTORS, &u); > > 781 if (error == 0) > > 782 sectors = dos_sectors = u; > > 783 error = ioctl(fd, DIOCGFWHEADS, &u); > > 784 if (error == 0) > > 785 heads = dos_heads = u; > > 786 > > 787 dos_cylsecs = cylsecs = heads * sectors; > > 788 disksecs = cyls * heads * sectors; > > ... > > 794 error = ioctl(fd, DIOCGMEDIASIZE, &o); > > 795 if (error == 0) { > > 796 disksecs = o / u; > > 797 cyls = dos_cyls = o / (u * dos_heads * dos_sectors); > > 798 } > > ... > > Any disk which returns 0 for these params is broken. I put in a > workaround for the GEOM case: > > sys/geom/geom_dev.c revision 1.26 > date: 2002/10/15 21:28:50; author: njl; state: Exp; lines: +8 -0 > Return an error if the drive reports heads/sectors that do not make sense. > This fixes a divide by zero in fdisk(8) This doesn't unbreak the non-GEOM case. That case was broken in rev.1.65 of fdisk.c by removing the fallback to using the geometry read from the label. Previous commits messed up the logic of the fallbacks so that the first level of fallback (previously the non-fallback level) was run even when it was not needed or used, except it was used in the sense that it printed a warning if it failed. Rev.1.65 axed this messenger and also axed the next (final) level of fallback to a geometry of 1/1/1. > There should probably be an appropriate error check in fdisk to catch > problems like this instead of dumping core. fdisk should just have active code to set usable defaults like it used to. Note that fdisk is perfectly usable with a geometry of 1/1/1. You just have to type in the C and H values after it starts up if you want to change geometry-related things. The only difficulty in implementing the fallbacks is reporting the results of errors. Users probably don't need to be told about all the failing ioctls tried. > The more important question > is "who in the kernel is setting these to 0?" as that part needs work too. Well, fdisk itself sets these to 0. The ioctls to get the number of heads and sectors may fail because they are unimplemented, and then the sloppy error handling in the code quoted above bites. It divides if the DIOCGMEDIASIZE ioctl succeeded, but a divisor is 0 if the earlier head or sector ioctl failed. The head and/or sector counts are only statically initialized to 0 in this case, since the fallback which set them to 1 was axed. The ioctls can also fail when fdisk is run on a regular file. Strangely enough, this case works perfectly since the DIOCGMEDIASIZE ioctl fails so the division is not attempted: Script started on Mon Jan 13 18:45:31 2003 ttyv2:bde@gamplex:/tmp> dd if=/dev/ad0 of=mbr count=1 1+0 records in 1+0 records out 512 bytes transferred in 0.024743 secs (20693 bytes/sec) ttyv2:bde@gamplex:/tmp> fdisk mbr fdisk: device mbr is not character special ******* Working on device mbr ******* parameters extracted from in-core disklabel are: cylinders=0 heads=0 sectors/track=0 (0 blks/cyl) parameters to be used for BIOS calculations are: cylinders=0 heads=0 sectors/track=0 (0 blks/cyl) Media sector size is 512 Warning: BIOS sector numbering starts with sector 1 Information from DOS bootblock is: The data for partition 1 is: sysid 11 (0x0b),(DOS or Windows 95 with 32 bit FAT) start 63, size 2104452 (1027 Meg), flag 0 beg: cyl 0/ head 1/ sector 1; end: cyl 130/ head 254/ sector 63 ... Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message