Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Oct 2002 23:11:14 -0400 (EDT)
From:      Robert Watson <rwatson@FreeBSD.ORG>
To:        Ian Dowse <iedowse@maths.tcd.ie>
Cc:        n0go013 <ttz@blahdeblah.demon.co.uk>, "Greg 'groggy' Lehey" <grog@FreeBSD.ORG>, current <freebsd-current@FreeBSD.ORG>
Subject:   Re: [ GEOM tests ] disklabel warnings and vinum drives lost 
Message-ID:  <Pine.NEB.3.96L.1021004231016.64999S-100000@fledge.watson.org>
In-Reply-To: <200210050408.aa61102@salmon.maths.tcd.ie>

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

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
robert@fledge.watson.org      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 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.1021004231016.64999S-100000>