Bug 167979 - [ufs] DIOCGDINFO ioctl does not work on 8.2 file systems
Summary: [ufs] DIOCGDINFO ioctl does not work on 8.2 file systems
Status: Closed Overcome By Events
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-16 21:00 UTC by Spencer Minear
Modified: 2022-01-22 16:07 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Spencer Minear 2012-05-16 21:00:12 UTC
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);
}

Fix: 

None Known
How-To-Repeat: Run the test program
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2012-05-17 08:12:38 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-fs

Over to maintainer(s).
Comment 2 ahmedatnet 2014-01-13 14:55:37 UTC
Bug 167979 states that ioctl(fd, DIOCGDINFO, &dl) fails with error: =
'Inappropriate ioctl for device'. The reason for failure of ioctl call =
with DIOCGDINFO option is that Makefile used to build kernel image does =
not have /usr/src/sys/geom/geom_bsd.c and =
/usr/src/sys/geom/geom_bsd_enc.c files included in it. When these two =
files are included in the Makefile and information is added for how to =
make object files of these files and how to link them with kernel image, =
DIOCGDINFO option works fine when used with ioctl.



To add these files in Makefile automatically, "/usr/src/sys/conf/files" =
has to be changed as follows:


# diff -u /usr/src/sys/conf/files_org /usr/src/sys/conf/files
--- /usr/src/sys/conf/files_org 2012-09-20 23:47:07.000000000 -0700
+++ /usr/src/sys/conf/files     2012-09-20 23:48:04.000000000 -0700
@@ -2011,8 +2011,8 @@
 geom/eli/pkcs5v2.c             optional geom_eli
 geom/gate/g_gate.c             optional geom_gate
 geom/geom_aes.c                optional geom_aes
-geom/geom_bsd.c                optional geom_bsd
-geom/geom_bsd_enc.c            optional geom_bsd
+geom/geom_bsd.c                standard
+geom/geom_bsd_enc.c            standard
 geom/geom_ccd.c                optional ccd | geom_ccd
 geom/geom_ctl.c                standard
 geom/geom_dev.c                standard



After these changes, automatically generated Makefile will have =
inclusion of  "/usr/src/sys/geom/geom_bsd.c" and =
"/usr/src/sys/geom/geom_bsd_enc.c" files.
=20


Difference in Makefile generated by making above changes in =
"/usr/src/sys/conf/files":

# diff -u Makefile ../BUG_FIX/Makefile | grep geom
-       pseudofs_fileno.o pseudofs_vncache.o pseudofs_vnops.o geom_ctl.o =
\
-       geom_dev.o geom_disk.o geom_dump.o geom_event.o geom_io.o \
-       geom_kern.o geom_slice.o geom_subr.o geom_vfs.o g_label.o \
+       pseudofs_fileno.o pseudofs_vncache.o pseudofs_vnops.o geom_bsd.o =
\
+       geom_bsd_enc.o geom_ctl.o geom_dev.o geom_disk.o geom_dump.o \
+       geom_event.o geom_io.o geom_kern.o geom_slice.o geom_subr.o \
+       geom_vfs.o g_label.o g_label_ext2fs.o g_label_iso9660.o \
-       $S/fs/pseudofs/pseudofs_vnops.c $S/geom/geom_ctl.c \
-       $S/geom/geom_dev.c $S/geom/geom_disk.c $S/geom/geom_dump.c \
-       $S/geom/geom_event.c $S/geom/geom_io.c $S/geom/geom_kern.c \
-       $S/geom/geom_slice.c $S/geom/geom_subr.c $S/geom/geom_vfs.c \
-       $S/geom/label/g_label.c $S/geom/label/g_label_ext2fs.c \
-       $S/geom/label/g_label_iso9660.c $S/geom/label/g_label_msdosfs.c =
\
-       $S/geom/label/g_label_ntfs.c $S/geom/label/g_label_reiserfs.c \
-       $S/geom/label/g_label_ufs.c $S/geom/label/g_label_gpt.c \
-       $S/geom/part/g_part.c $S/geom/part/g_part_bsd.c \
-       $S/geom/part/g_part_ebr.c $S/geom/part/g_part_gpt.c \
-       $S/geom/part/g_part_mbr.c $S/isa/isa_common.c $S/isa/isahint.c \
+       $S/fs/pseudofs/pseudofs_vnops.c $S/geom/geom_bsd.c \
+       $S/geom/geom_bsd_enc.c $S/geom/geom_ctl.c $S/geom/geom_dev.c \
+       $S/geom/geom_disk.c $S/geom/geom_dump.c $S/geom/geom_event.c \
+       $S/geom/geom_io.c $S/geom/geom_kern.c $S/geom/geom_slice.c \
+       $S/geom/geom_subr.c $S/geom/geom_vfs.c $S/geom/label/g_label.c \
+       $S/geom/label/g_label_ext2fs.c $S/geom/label/g_label_iso9660.c \
+       $S/geom/label/g_label_msdosfs.c $S/geom/label/g_label_ntfs.c \
+       $S/geom/label/g_label_reiserfs.c $S/geom/label/g_label_ufs.c \
+       $S/geom/label/g_label_gpt.c $S/geom/part/g_part.c \
+       $S/geom/part/g_part_bsd.c $S/geom/part/g_part_ebr.c \
+       $S/geom/part/g_part_gpt.c $S/geom/part/g_part_mbr.c \
+geom_bsd.ln: $S/geom/geom_bsd.c
+geom_bsd.o: $S/geom/geom_bsd.c
+geom_bsd_enc.ln: $S/geom/geom_bsd_enc.c
+geom_bsd_enc.o: $S/geom/geom_bsd_enc.c
 geom_ctl.ln: $S/geom/geom_ctl.c


=20
Fix was tested on FreeBSD 8.3, with the test program provided with the =
bug. Following are the results:

Before Fix:

# ./bug ad0s1a
bug: DIOCGDIFNO failed on 'ad0s1a': Inappropriate ioctl for device


# ./bug ad0s1b
bug: DIOCGDIFNO failed on 'ad0s1b': Inappropriate ioctl for device


After Fix:

# ./bug ad0s1a
Filesystem type 4.2BSD

# ./bug ad0s1b
Filesystem type swap


Fahad Ahmed, Engineer
Dorr H. Clark, advisor
COEN 284, Operating Systems Case Study
Santa Clara University
Comment 3 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:00:50 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped