[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

/proc, autodetection and a new PATCH



On Mon, Dec 20, 1999 at 12:42:29AM -0500, Adam Di Carlo wrote:
> Chris Lawrence <cnlawren@olemiss.edu> writes:
> 
> > I'll take a look around and see where else we can benefit from looking
> > in /proc.  I'm pretty sure we can use /proc/partitions to bypass a lot
> > of logic, especially if we're commited to using a 2.2 kernel in potato.
> 
> Yeah... see utilities/fdisk/ -- Also, check out the included patch
> from Mark van Walraven.

That patch is now in CVS, revision 1.30 of fdisk.c.

I have the next patch (to filter out some non-disk devices) ready, but I
will be very busy the next few days and don't want to check in anything
further under those circumstances.  I'll attach it here - anyone able
to test it and report back, I'd be grateful.  Seems to be ok for IDE,
but I don't have any SMART2 systems available for test anymore, and also
lack a DAC960.  Does anyone have a system with ESDI or ACSI drives?

I've been studying /proc/partitions and it looks like a good way to
gather potential install targets for fdisk_reread() also.  The IDE,
DAC960 and SMART2 drivers all put their device numbers and (recommended)
names in /proc/partitions.  This looks much better than keeping a hitlist
of device names to search for in /dev.  There are a couple of problems:

Problem:  No guarantee that devices really are named the same in /dev.

Solution: Ignore device if /dev/<whatever> doesn't exist and have the
	  same major and minor device numbers.

Problem:  Nothing to indicate whether a line in /proc/partitions is a
	  drive or a partition.

Solution: Know about the device names for each device driver (yuck) or
	  about the device numbers for each device driver (slightly less
	  yuck).

I'm not happy about the second solution - it would be best to not have to
know any more about devices than what the kernel tells us.  Ideas, anyone?

I'm mostly inclined to play it safe and stick with the current approach,
since freeze is bearing down ...

Regards,

Mark.
Index: libfdisk/fdisk.c
===================================================================
RCS file: /cvs/debian-boot/boot-floppies/utilities/libfdisk/fdisk.c,v
retrieving revision 1.30
diff -u -r1.30 fdisk.c
--- libfdisk/fdisk.c	1999/12/28 01:56:37	1.30
+++ libfdisk/fdisk.c	1999/12/28 11:10:44
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <linux/unistd.h>
 #include <fcntl.h>
@@ -12,6 +13,7 @@
 #include <mntent.h>
 #include <assert.h>
 #include <linux/cdrom.h>
+#include <linux/major.h>
 
 #include "fdisk.h"
 
@@ -883,18 +885,65 @@
 static void alarmed(int signo) { timed_out = 1; }
 
 
-/* is_disk: return true is device is a disk drive */
+/* ide_is_disk: return true if IDE device is a disk drive */
+static int ide_is_disk(char *device, int fd)
+{
+    char pname[32];
+    int n;
+    FILE *f;
+    int result = 0;
+
+    /* /dev/hd? => /proc/ide/hd?/media */
+    device = strrchr(device, '/');
+    assert(device);
+    n = snprintf(pname, sizeof pname, "/proc/ide/%s/media", device + 1);
+    assert(n > 0);
+
+    /* open /proc/ide/hd?/media and look for ide_disk text */
+    f = fopen(pname, "r");
+    if (f) {
+	char line[8];
+	result = fgets(line, sizeof line, f) && strcmp(line, "disk\n") == 0;
+	fclose(f);
+    }
+    return result;
+}
+
+
+/* is_disk: return true if device is a disk drive */
 static int is_disk(char *device, int fd)
 {
+    struct stat stat_buf;
     struct cdrom_volctrl cdvol;
+
+    /* reject anything un-stat-able, or not a block device */
+    if (fstat(fd, &stat_buf) || ! S_ISBLK(stat_buf.st_mode))
+	return 0;
 
-    /** TODO *****************************************************************/
-    /* Erik thinks the CD-ROM test is inadequate.  I'm inclined to agree.    */
-    /* We could instead consult /proc/ide and /proc/scsi, which will allow   */
-    /* us to eliminate IDE CD-ROMs (and CD-Rs) and non-random-access SCSI    */
-    /* devices.  See debian-boot list for discussion.                        */
-    /* I'm not sure how to check for such devices on dac960 or smart2.       */
-    /* ***********************************************************************/
+    /* IDE devices */
+    switch (major(stat_buf.st_rdev)) {
+    case IDE0_MAJOR: case IDE1_MAJOR: case IDE2_MAJOR:
+    case IDE3_MAJOR: case IDE4_MAJOR: case IDE5_MAJOR:
+	return ide_is_disk(device, fd);
+    }
+
+    /* SCSI disk driver will only accept disks and mag-opt drives */
+    if (SCSI_DISK_MAJOR(major(stat_buf.st_rdev)))
+	return 1;
+
+#if #cpu (i386)
+    /* ESDI devices assumed to all be disks */
+    if (major(stat_buf.st_rdev) == PS2ESDI_MAJOR)
+	return 1;
+#elif #cpu (m68k)
+    /* ACSI devices assumed to all be disks */
+    if (major(stat_buf.st_rdev) == ACSI_MAJOR)
+	return 1;
+#endif
+
+    /** TODO ***************************************************************/
+    /* I'm not sure how to check for non-disk devices on dac960 or smart2. */
+    /* *********************************************************************/
 
     /* supposedly anything failing CDROMVOLREAD for the right reasons is ok */
     return ioctl(fd, CDROMVOLREAD, &cdvol) && (errno == EINVAL ||

Reply to: