On Sat, 5 Oct 2002, Ian Dowse wrote:
> >The divide by zero problem seems to be caused by an interaction > >between two bugs: GEOM refuses to return the sector size because > ... > >The next failure I get is: > > > > Can't write config to /dev/da1s1d, error 45 (EOPNOTSUPP) > > This turns out to be vinum doing a DIOCWLABEL to make the label writable > before writing its configuration, but GEOM does not support that ioctl I > presume. It should be safe to ignore these DIOCWLABEL ioctl return > values as the actual writing of the vinum data should give a suitable > error if making the label writable fails and is important. The patch > below is Robert's patch with all 3 other issues fixed, and together, > this seems to be enough to make vinum work again. Wonderful. I just committed a fix so that vinum.ko can be unloaded without a panic when WITNESS is present. I'll give the combined patch a spin on my crashbox and see if it does the trick here. Thanks! Robert N M Watson FreeBSD Core Team, TrustedBSD Projects [EMAIL PROTECTED] Network Associates Laboratories > Index: vinumio.c > =================================================================== > RCS file: /dump/FreeBSD-CVS/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 02:40:18 -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++; > - } > - > - 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 */ > + 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 ((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; > > @@ -144,7 +77,7 @@ > if (dsw == NULL) > drive->lasterror = ENOENT; > else > - drive->lasterror = (dsw->d_open) (drive->dev, FWRITE, 0, NULL); > + drive->lasterror = (dsw->d_open) (drive->dev, FWRITE | FREAD, 0, NULL); > > if (drive->lasterror != 0) { /* failed */ > drive->state = drive_down; /* just force it down */ > @@ -278,13 +211,17 @@ > void > close_locked_drive(struct drive *drive) > { > + int error; > + > /* > * If we can't access the drive, we can't flush > * the queues, which spec_close() will try to > * do. Get rid of them here first. > */ > - drive->lasterror = (*devsw(drive->dev)->d_close) (drive->dev, 0, 0, NULL); > + error = (*devsw(drive->dev)->d_close) (drive->dev, 0, 0, NULL); > drive->flags &= ~VF_OPEN; /* no longer open >*/ > + if (drive->lasterror == 0) > + drive->lasterror = error; > } > > /* > @@ -678,20 +615,18 @@ > if ((drive->state != drive_unallocated) > && (drive->state != drive_referenced)) { /* and it's a real drive >*/ > wlabel_on = 1; /* enable writing the >label */ > - error = (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the >label writeable */ > + (void) (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the >label writeable */ > DIOCWLABEL, > (caddr_t) & wlabel_on, > FWRITE, > curthread); > - if (error == 0) > - error = write_drive(drive, (char *) vhdr, VINUMHEADERLEN, >VINUM_LABEL_OFFSET); > + error = write_drive(drive, (char *) vhdr, VINUMHEADERLEN, >VINUM_LABEL_OFFSET); > if (error == 0) > error = write_drive(drive, config, MAXCONFIG, >VINUM_CONFIG_OFFSET); /* first config copy */ > if (error == 0) > error = write_drive(drive, config, MAXCONFIG, >VINUM_CONFIG_OFFSET + MAXCONFIG); /* second copy */ > wlabel_on = 0; /* enable writing the >label */ > - if (error == 0) > - error = (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the >label non-writeable again */ > + (void) (*devsw(drive->dev)->d_ioctl) (drive->dev, /* make the >label non-writeable again */ > DIOCWLABEL, > (caddr_t) & wlabel_on, > FWRITE, > To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message