kern/167979: DIOCGDINFO ioctl does not work on 8.2 file systems

Spencer Minear spencer_minear at mcafee.com
Wed May 16 20:00:14 UTC 2012


>Number:         167979
>Category:       kern
>Synopsis:       DIOCGDINFO ioctl does not work on 8.2 file systems
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 16 20:00:12 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Spencer Minear
>Release:        FreeBSD 8.2
>Organization:
McAfee
>Environment:
FreeBSD freebe1.scur.com 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Fri Feb 18 02:24:46 UTC 2011     root at almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
Use of ioctl(fd, DIOCGDINFO, &dl) fails with a 'Inappropriate ioctl for device' message when run on a file system like ad0s1a.  On a similar 7.2 system one receives the expected "Filesystem type 4.2BSD" type of information.

My analysis suggests that the problem is related to changes in the GEOM layer, specifically the introduction of the PART class.  In 7.2 the ioctl ends up getting to the underlying BSD geom layer and obtains the required information.  In 8.3 the ioctl appears to get to a PART entry that has the name of the device, but does not know how to get to the underlying BSD layer to find out the file type.

In addition I've noted that if you have a slice that contains a number of BSD file systems, that are not being used, the device information shows many devices with completely bogus names like /dev/ad0s3aa, /dev/ad0s3ac, etc.  In most cases these names get repeated.  If the file system ad0s3a is mounted then all off the bogus names disappear.  It appears that the mount action will initiate geom spoil processing that cleans up these entries.

The following simple test program was used to show that the ioctl behavior changes between FreeBSD 7.2 and 8.2.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <err.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define FSTYPENAMES
#include <sys/disklabel.h>

int
main(int argc, char** argv)
{

    struct disklabel dl;
    int fd;
    char *dev;
    char *dev_path;
    char p;
    struct stat sb;
    u_char t;
    const char *vfstype;

    if (argc != 2) {
	printf("Usage: tstdioginfo device\n");
	exit(1);
    }

    dev = argv[1];

    asprintf(&dev_path, "/dev/%s", dev);

    if (stat(dev_path, &sb) != 0) {
	err(1, "Failed to stat dev %s\n", dev);
	exit(1);
    }
	
    p = dev[strlen(dev) - 1];

    /* deduce the file system type from the disk label */
    if ((fd = open(dev_path, O_RDONLY)) == -1)
	err(1, "cannot open '%s'", dev_path);

    if (ioctl(fd, DIOCGDINFO, &dl) == -1) {
	(void) close(fd);
	err(1, "DIOCGDIFNO failed on '%s'", dev);
    }
    
    
    if ((p - 'a') >= dl.d_npartitions)
	errx(1, "partition `%s' is not defined on disk", dev);
    
    if ((t = dl.d_partitions[p - 'a'].p_fstype) >= FSMAXTYPES) 
	errx(1, "partition `%s' is not of a legal vfstype",
	     dev);

    if ((vfstype = fstypenames[t]) == NULL)
	errx(1, "vfstype `%s' on partition `%s' is not supported",
	     fstypenames[t], dev);

    printf("Filesystem type %s\n", vfstype);
    return(0);
}




>How-To-Repeat:
Run the test program 
>Fix:
None Known

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list