Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Oct 2002 20:07:11 -0400 (EDT)
From:      Robert Watson <rwatson@FreeBSD.ORG>
To:        Terry Lambert <tlambert2@mindspring.com>
Cc:        Emiel Kollof <coolvibe@hackerheaven.org>, Peter Wemm <peter@wemm.org>, Poul-Henning Kamp <phk@critter.freebsd.dk>, n0go013 <ttz@blahdeblah.demon.co.uk>, current <freebsd-current@FreeBSD.ORG>
Subject:   Re: [ GEOM tests ] disklabel warnings and vinum drives lost
Message-ID:  <Pine.NEB.3.96L.1021004200338.70577U-100000@fledge.watson.org>
In-Reply-To: <3D9E0DD8.1C9526DE@mindspring.com>

next in thread | previous in thread | raw e-mail | index | archive | help

On Fri, 4 Oct 2002, Terry Lambert wrote:

> The assumption here is that the devfs will be available to the system
> before the root is mounted transparently over it.  This is also doable
> with an unmounted instance of the backing devfs, not yet mounted on
> /dev, if a transparent mount of / over top of a preexiting / -> /dev is
> not supported (i.e. devfs is mounted on /dev on the root FS, rather than
> the root FS being mounted on a backing node on which defvfs is already
> mounted on /, and the devices showing through as if they were on /). 

Actually, no -- Vinum doesn't know how to do that--the device name used in
this code originates in a userland ioctl() configuration call for Vinum. 
However, here's a patch that makes Vinum use namei() to rely on devfs to
locate requested devices instead of parsing the device name and guessing
the device number (incorrectly with GEOM).  Unfortunately, I almost
immediately run into a divide by zero due to a zero sector size.  Jeff
Roberson mentioned to me he had a fix for this bug that he sent to Greg,
but that was never committed.

Index: vinumio.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/vinum/vinumio.c,v
retrieving revision 1.75
diff -u -r1.75 vinumio.c
--- vinumio.c	21 Aug 2002 23:39:51 -0000	1.75
+++ vinumio.c	5 Oct 2002 00:03:09 -0000
@@ -50,92 +50,25 @@
 int
 open_drive(struct drive *drive, struct thread *td, int verbose)
 {
-    int devmajor;					    /* major devs for disk device */
-    int devminor;					    /* minor devs for disk device */
-    int unit;
-    char *dname;
+    struct nameidata nd;
     struct cdevsw *dsw;					    /* pointer to cdevsw entry */
+    int error;
 
-    if (bcmp(drive->devicename, "/dev/", 5))		    /* device name doesn't start with /dev */
-	return ENOENT;					    /* give up */
     if (drive->flags & VF_OPEN)				    /* open already, */
 	return EBUSY;					    /* don't do it again */
 
-    /*
-     * Yes, Bruce, I know this is horrible, but we
-     * don't have a root filesystem when we first
-     * try to do this.  If you can come up with a
-     * better solution, I'd really like it.  I'm
-     * just putting it in now to add ammuntion to
-     * moving the system to devfs.
-     */
-    dname = &drive->devicename[5];
-    drive->dev = NULL;					    /* no device yet */
-
-    /* Find the device */
-    if (bcmp(dname, "ad", 2) == 0)			    /* IDE disk */
-	devmajor = 116;
-    else if (bcmp(dname, "wd", 2) == 0)			    /* IDE disk */
-	devmajor = 3;
-    else if (bcmp(dname, "da", 2) == 0)
-	devmajor = 13;
-    else if (bcmp(dname, "vn", 2) == 0)
-	devmajor = 43;
-    else if (bcmp(dname, "md", 2) == 0)
-	devmajor = 95;
-    else if (bcmp(dname, "ar", 2) == 0)
-        devmajor = 157;
-    else if (bcmp(dname, "amrd", 4) == 0) {
-	devmajor = 133;
-	dname += 2;
-    } else if (bcmp(dname, "mlxd", 4) == 0) {
-	devmajor = 131;
-	dname += 2;
-    } else if (bcmp(dname, "idad", 4) == 0) {
-	devmajor = 109;
-	dname += 2;
-    } else if (bcmp(dname, "twed", 4) == 0) {               /* 3ware raid */
-      devmajor = 147;
-      dname += 2;
-    } else
-      return ENODEV;
-    dname += 2;						    /* point past */
-
-    /*
-     * Found the device.  We can expect one of
-     * two formats for the rest: a unit number,
-     * then either a partition letter for the
-     * compatiblity partition (e.g. h) or a
-     * slice ID and partition (e.g. s2e).
-     * Create a minor number for each of them.
-     */
-    unit = 0;
-    while ((*dname >= '0')				    /* unit number */
-    &&(*dname <= '9')) {
-	unit = unit * 10 + *dname - '0';
-	dname++;
+    NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, drive->devicename,
+        curthread);
+    error = namei(&nd);
+    if (error)
+	return (error);
+    if (!vn_isdisk(nd.ni_vp, &error)) {
+	NDFREE(&nd, 0);
+	return (error);
     }
+    drive->dev = udev2dev(nd.ni_vp->v_rdev->si_udev, 0);
+    NDFREE(&nd, 0);
 
-    if (*dname == 's') {				    /* slice */
-	if (((dname[1] < '1') || (dname[1] > '4'))	    /* invalid slice */
-	||((dname[2] < 'a') || (dname[2] > 'h')))	    /* or invalid partition */
-	    return ENODEV;
-	devminor = ((unit & 31) << 3)			    /* unit */
-	+(dname[2] - 'a')				    /* partition */
-	+((dname[1] - '0' + 1) << 16)			    /* slice */
-	+((unit & ~31) << 16);				    /* high-order unit bits */
-    } else {						    /* compatibility partition */
-	if ((*dname < 'a') || (*dname > 'h'))		    /* or invalid partition */
-	    return ENODEV;
-	devminor = (*dname - 'a')			    /* partition */
-	+((unit & 31) << 3)				    /* unit */
-	+((unit & ~31) << 16);				    /* high-order unit bits */
-    }
-
-    if ((devminor & 7) == 2)				    /* partition c */
-	return ENOTTY;					    /* not buying that */
-
-    drive->dev = makedev(devmajor, devminor);		    /* find the device */
     if (drive->dev == NULL)				    /* didn't find anything */
 	return ENODEV;
 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1021004200338.70577U-100000>