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

Experimental floppy drive detection. Please test.



 Will anyone interested please try the following patch against today's
 CVS?  You can start a system with the standard dboostrap, change to
 vt2, rm /sbin/dbootstrap, then transfer this one from a floppy with
 cp /floppy/dbootstrap /sbin, then kill the dboostrap to make it get
 restarted.

 This makes it detect whether there is a floppy fd1 installed or not.
 It works, but there is a long pause, one time, when dbootstrap is
 first started.  Do yous think the pause is too long, or should I
 commit this to CVS?  I tried to use alarm to only allow 2 seconds for
 the open to succeed, but apparently it's blocked in kernel code, so
 the alarm signal isn't handled until after the long pause anyway.

 The other thing to check on is whether the same method will work for
 attempting to detect the SCSI floppy on whatever architecture it is
 that has one.  (powerpc?)

 This is the best way I can find of doing floppy detection, other than
 grepping / sedding the `dmesg' output. (which might really be better
 since that won't hang for 20-30 seconds trying to open /dev/fd1.)
 This method is pretty much the same one used by libdetect.  It will
 also hang for a time on attempting to open /dev/fd1 when it does not
 exist.  If we decided to grep the `dmesg' output, then a line should
 be added to the rcS that will dump it to a file at boot, so the part
 we need won't scroll away after a while.

 It's weird, because when I open /dev/fd0, which exists, and there is
 no floppy in the drive, I get an error return from open(), and thus
 -1 for a file descriptor (and errno is ENXIO).  But when I open
 /dev/fd1, which does NOT exist, it hangs out for about 20-30 seconds,
 then returns a file descriptor.  I then have to run an ioctl on that
 descriptor, and check for an ENODEV.  Weird.  I wish the floppy
 drives had a listing in the /proc filesystem, like the cdrom's do.
 That would make this much simpler and there would not be a long pause
 during the initial detection.


Index: utilities/dbootstrap/main_menu.c
===================================================================
RCS file: /cvs/debian-boot/boot-floppies/utilities/dbootstrap/main_menu.c,v
retrieving revision 1.30
diff -u -r1.30 main_menu.c
--- utilities/dbootstrap/main_menu.c	2000/03/27 01:40:35	1.30
+++ utilities/dbootstrap/main_menu.c	2000/03/28 12:14:13
@@ -91,6 +91,8 @@
 
 #endif //_TESTING_
 
+void check_existance_of_floppy_devices (void); /* in choose_medium.c */
+
 int
 main_menu (void)
 {
@@ -175,6 +177,8 @@
 	if (Root) {
 	    found_root = strdup (Root->name);
 	}
+
+	check_existance_of_floppy_devices();
 
 	fdisk_reread();
 	if (fdisk_disks == NULL) {
Index: utilities/dbootstrap/choose_medium.c
===================================================================
RCS file: /cvs/debian-boot/boot-floppies/utilities/dbootstrap/choose_medium.c,v
retrieving revision 1.70
diff -u -r1.70 choose_medium.c
--- utilities/dbootstrap/choose_medium.c	2000/03/24 08:27:52	1.70
+++ utilities/dbootstrap/choose_medium.c	2000/03/28 12:13:25
@@ -1,12 +1,24 @@
-#include <assert.h>
+
 #include <stdio.h>
-#include <glob.h>
 #include <sys/mount.h>
+#include <syslog.h>
+
+#include <string.h>
+#include <dirent.h>
+
+#include <errno.h>
+#include <linux/hdreg.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+
+#include "../libfdisk/fdisk.h"	/* for fdisk_partitions #### Move this code to another file??? */
 #include "dbootstrap.h"
 #include "lang.h"
-#include <syslog.h>
 #include "util.h"
-#include "../libfdisk/fdisk.h"	/* for fdisk_partitions #### Move this code to another file??? */
+
+#if (KERNEL_VERSION_CODE < KERNEL_VERSION(2,2)) /* archane (sic) codes for old kernel. */
+# include <glob.h>
+#endif
 
 #define CM_MOUNTPOINT_DIR "/instmnt"
 #ifdef _TESTING_
@@ -23,11 +35,19 @@
 char **dirv;
 char *pattern;
 
-/* #### This and several other globals probably belong in a header also once more of this is librified. */
+/*
+ * #### This and several other globals probably belong in a header
+ *      also once more of this is librified. 
+ */
 char *cdrom_device = NULL;
 
-#include <string.h>
-#include <dirent.h>
+/*
+ * For fd0 and fd1.
+ *
+ * #### If the same technique will work for the SCSI
+ *      floppy, that should be added and tested.
+ */
+int floppy_exists[2] = {-1,-1};
 
 /* ED: floppy filesystem type is not the same for all architectures */
 #if #cpu(sparc) || #cpu(powerpc)
@@ -36,6 +56,85 @@
 static char *fs_type_tab[] = { "msdos", "ext2", NULL };
 #endif
 
+static int
+floppy_device_exists (const char *dev);
+
+/*
+ * To be called from the top of main_menu, after the "examining your
+ * system" dialog is displayed.  The first time it's run, it may pause
+ * for around 20 seconds trying to open a nonexistant floppy device.
+ * After that, it will return immediately.
+ *
+ */
+void
+check_existance_of_floppy_devices (void)
+{
+    if (floppy_exists[0] < 0 || floppy_exists[1] < 0) {
+	int i;
+	char *devices[] = {"/dev/fd0", "/dev/fd1"};
+	
+	for (i = 0; i <= 1; i++) {
+	    if ((floppy_exists[i] = floppy_device_exists (devices[i]))) {
+		DEBUGMSG ("Floppy %s exists.\n", devices[i]);
+	    }
+	    else {
+		DEBUGMSG ("Floppy %s does NOT exist.\n", devices[i]);
+	    }
+	}
+    }
+    return;
+}
+
+/*
+ * Return 1 if the device exists, 0 if it does not.  In the case where
+ * it does not exist, there will be an uninterruptable pause of about
+ * 20 seconds.  Calling an alarm does no good since it's blocked
+ * inside the kernel.
+ *
+ */
+static int
+floppy_device_exists (const char *dev)
+{
+#if 0
+    struct sigaction new_action, old_action;
+#endif
+
+    struct hd_geometry geom;
+    int fd = -1, ret = 0;
+
+#if 0
+    new_action.sa_handler = alarm_handler;
+    sigemptyset (&new_action.sa_mask);
+    new_action.sa_flags = 0 & ~SA_RESTART;
+    
+    if (sigaction (SIGALRM, &new_action, &old_action) < 0) {
+	perror ("sigaction");
+	exit (1);
+    }
+    
+    alarm (2);
+#endif
+
+    if ((fd = open (dev, O_RDONLY)) < 0 && (errno == ENXIO)) {
+	ret = 1;
+    }
+
+#if 0
+    alarm (0);
+    
+    if (sigaction (SIGALRM, &old_action, NULL) < 0) {
+	perror ("sigaction");
+	exit (1);			/* Throw an exception? */
+    }
+#endif
+
+    if (! ((ioctl (fd, HDIO_GETGEO, &geom) < 0) && (errno == ENODEV))) {
+	ret = 1;
+    }
+
+    return (ret);
+}
+
 int mount_and_check_floppy(char *device, const char *type,
 			   const char *text)
 {
@@ -61,14 +160,14 @@
 	    int rs, items;
 
 	    items = 0;
-	    if (strcmp(InstallationRootDevice, "/dev/fd0")) {
+	    if (floppy_exists[0] && strcmp(InstallationRootDevice, "/dev/fd0")) {
 		choices[items].string = _("/dev/fd0  : First floppy drive");
 		choices[items].tag = NULL;
 		choices[items].state = 0;
 		dlist[items] = "/dev/fd0";
 		items++;
 	    }
-	    if (strcmp(InstallationRootDevice, "/dev/fd1")) {
+	    if (floppy_exists[1] && strcmp(InstallationRootDevice, "/dev/fd1")) {
 		choices[items].string = _("/dev/fd1  : Second floppy drive");
 		choices[items].tag = NULL;
 		choices[items].state = 0;
@@ -943,58 +1042,6 @@
     return ret;
 }
 
-#if 0				/* Test program for the record. */
-/* My attempt at floppy drive detection.
- * gcc -o check_for_floppy check_for_floppy.c
- * time sudo ./check_for_floppy
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <linux/hdreg.h>
-#include <errno.h>
-
-void try_dev (const char *dev)
-{
-  struct hd_geometry geom;
-  int fd, status;
-
-  printf ("Trying %s ...\n", dev);
-  if ((fd = open (dev, O_RDONLY)) < 0) {
-    printf ("Error: open %s: %d, %s\n", dev, errno, strerror(errno));
-  }
-  printf ("Open returned, fd=%i\n", fd);
-  if (fd >= 0) {
-    printf ("Trying ioctl ...\n");
-    if ((status = ioctl (fd, HDIO_GETGEO, &geom)) < 0) {
-      printf ("Error: ioctl %s: %d, %s\n", dev, errno, strerror(errno));
-    }
-    else {
-      printf ("heads=%i, sectors=%i, cylinders=%i\n",
-	      (int) geom.heads, (int) geom.sectors, geom.cylinders);
-    }
-    close(fd);
-  }
-}
-
-int
-main (int argc, char **argv)
-{
-  try_dev("/dev/fd0");
-  try_dev("/dev/fd1");
-}
-#endif
-
-#if 0
-int
-has_floppy (dev_t dev)
-{
-    STUB!!
-}
-#endif
-
 int choose_medium(void)
 {
     struct stat statbuf;
@@ -1057,12 +1104,12 @@
 	ilist[items] = MED_cdrom;
 	items++;
     }
-    if (strcmp(InstallationRootDevice, "/dev/fd0")) {
+    if (floppy_exists[0] && strcmp(InstallationRootDevice, "/dev/fd0")) {
 	choices[items].string = _("/dev/fd0  : First floppy drive");
 	ilist[items] = MED_fd0;
 	items++;
     }
-    if (strcmp(InstallationRootDevice, "/dev/fd1")) {
+    if (floppy_exists[1] && strcmp(InstallationRootDevice, "/dev/fd1")) {
 	choices[items].string = _("/dev/fd1  : Second floppy drive");
 	ilist[items] = MED_fd1;
 	items++;


Reply to: