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>