bug-parted
[Top][All Lists]
Advanced

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

[PATCH] improve device probing heuristics


From: Andreas Dilger
Subject: [PATCH] improve device probing heuristics
Date: Fri, 1 Feb 2002 17:57:16 -0700
User-agent: Mutt/1.2.5.1i

Andrew,
this patch improves device probing heuristics (at least IMHO):
1) Add support for devices names in the form .../dN and .../cMdN to not
   be dropped by the partition elimination check (h/w RAID devices,
   which _appear_ to be handled by other parts of the code if they are
   specified, but are not if auto probed).
1) If /proc/ide/hdX/media is available, it will check to see if this is a
   disk drive before trying to probe it (to avoid cdrom or floppy problems
   and/or delays).  On ia64 machines, apparently /dev/hda is normally an
   LS-120 floppy or CDROM, and trying to probe it takes a long time.  I
   also heard reports on the LVM list that trying to probe CDROMs can
   cause problems for some users.
2) If the .../media file is found for one device, we consider it authoritative
   information that other devices which do not have this file do not exist.
   If no .../media file has ever been found, we continue to probe the device.
3) If we get valid devices back from /proc/partitions, we do not continue
   to probe all of the other devices.  This requires _ped_probe_device()
   to have a return value (included in this patch).  Not 100% sure about
   this, because it might have problems for devices attached to modular
   drivers which are not loaded.  Conversely, if we add too many devices
   to be probed, it might increase the probe time too much if we always
   scan all possible devices.
4) Increase the number of SCSI and IDE devices probed.
   
I was also thinking of adding calls like _probe_raid_device ("ida") (or
"rd" or "cciss") in _probe_standard_devices().  It would be smart enough
to bail if /dev/{ida,rd,cciss} didn't exist, and wouldn't continue to probe
for controllers if a previous controller didn't exist (e.g. don't check
ida/c1..c7 if ida/c0 doesn't find any devices).  Thoughts?

Cheers, Andreas
=================== parted-1.6.0-scan.diff ===============================
--- libparted/device.c.orig     Sun Dec 30 11:26:01 2001
+++ libparted/device.c  Fri Feb  1 14:59:26 2002
@@ -101,7 +101,7 @@
                return devices;
 }
 
-void
+int
 _ped_device_probe (const char* path)
 {
        char*           normalized_path;
@@ -114,7 +114,7 @@
                 * Try it anyway.  */
                normalized_path = strdup (path);
        if (!normalized_path)
-               return;
+               return 0;
 
        ped_exception_fetch_all ();
        dev = ped_device_get (normalized_path);
@@ -122,6 +122,8 @@
                ped_exception_catch ();
        ped_exception_leave_all ();
        ped_free (normalized_path);
+
+       return dev ? 1 : 0;
 }
 
 void
--- libparted/linux.c.orig      Sat Jan 26 09:38:51 2002
+++ libparted/linux.c   Fri Feb  1 17:55:31 2002
@@ -1283,13 +1283,57 @@
 }
 
 static int
+_probe_ide_device (char *device)
+{
+       static int      have_proc_ide = -1;
+       char            buf [256];
+
+       if (have_proc_ide == -1) {
+               struct stat     st;
+
+               if (stat("/proc/ide", &st) == 0 && S_ISDIR(st.st_mode))
+                       have_proc_ide = 1;
+               else
+                       have_proc_ide = 0;
+       }
+
+       if (have_proc_ide) {
+               static int      have_proc_ide_media = 0;
+               char*           ret;
+               FILE*           media;
+
+               sprintf (buf, "/proc/ide/%s/media", device);
+
+               if ((media = fopen (buf, "r")) == NULL) {
+                       if (have_proc_ide_media)
+                               return 0;
+               } else {
+                       have_proc_ide_media = 1;
+
+                       ret = fgets (buf, sizeof (buf), media);
+
+                       fclose (media);
+
+                       if (!ret || strncmp (buf, "disk", 4)
+                           || (buf [4] != '\n' && buf [4] != '\0'))
+                               return 0;
+               }
+       }
+
+       strcpy (buf, "/dev/");
+       strcat (buf, device);
+
+       return _ped_device_probe (buf);
+}
+
+static int
 _probe_proc_partitions ()
 {
        FILE*           proc_part_file;
        int             major, minor, size;
        char            buf [512];
        char            part_name [256];
-       char            dev_name [256];
+       int             count = 0;
 
        proc_part_file = fopen ("/proc/partitions", "r");
        if (!proc_part_file)
@@ -1301,53 +1345,82 @@
        while (fgets (buf, 512, proc_part_file)
               && sscanf (buf, "%d %d %d %255s", &major, &minor, &size,
                          part_name) == 4) {
+               char*           slash;
+               int             dummy;
+               int             len;
+
+               len = strlen(part_name);
+
                /* Heuristic for telling partitions and devices apart
-                * Probably needs to be improved
+                * Probably needs to be improved.  It now accepts RAID
+                * disks like ida/cXdY ideraid/dY, but not rd/cXdYpZ
                 */
-               if (isdigit (part_name [strlen (part_name) - 1]))
+               if ((slash = strrchr (part_name, '/'))
+                   && (sscanf (slash, "/c%dd%d", &dummy, &dummy) == 2
+                       || sscanf (slash, "/d%d", &dummy))) {
+                       if (part_name [len - 2] == 'p'
+                           || part_name [len - 3] == 'p')
+                               continue;
+               } else if (isdigit (part_name [len - 1]))
                        continue;
 
-               strcpy (dev_name, "/dev/");
-               strcat (dev_name, part_name);
-               _ped_device_probe (dev_name);
+               if (!strncmp (part_name, "hd", 2))
+                       count += _probe_ide_device (part_name);
+               else {
+                       char    dev_name [256];
+
+                       strcpy (dev_name, "/dev/");
+                       strcat (dev_name, part_name);
+                       count += _ped_device_probe (dev_name);
+               }
        }
 
        fclose (proc_part_file);
-       return 1;
+       return count;
 }
 
 static int
 _probe_standard_devices ()
 {
-       _ped_device_probe ("/dev/sda");
-       _ped_device_probe ("/dev/sdb");
-       _ped_device_probe ("/dev/sdc");
-       _ped_device_probe ("/dev/sdd");
-       _ped_device_probe ("/dev/sde");
-       _ped_device_probe ("/dev/sdf");
-
-       _ped_device_probe ("/dev/hda");
-       _ped_device_probe ("/dev/hdb");
-       _ped_device_probe ("/dev/hdc");
-       _ped_device_probe ("/dev/hdd");
-       _ped_device_probe ("/dev/hde");
-       _ped_device_probe ("/dev/hdf");
-       _ped_device_probe ("/dev/hdg");
-       _ped_device_probe ("/dev/hdh");
+       int count = 0;
+
+       count += _ped_device_probe ("/dev/sda");
+       count += _ped_device_probe ("/dev/sdb");
+       count += _ped_device_probe ("/dev/sdc");
+       count += _ped_device_probe ("/dev/sdd");
+       count += _ped_device_probe ("/dev/sde");
+       count += _ped_device_probe ("/dev/sdf");
+       count += _ped_device_probe ("/dev/sdg");
+       count += _ped_device_probe ("/dev/sdh");
+       count += _ped_device_probe ("/dev/sdi");
+       count += _ped_device_probe ("/dev/sdj");
+       count += _ped_device_probe ("/dev/sdk");
+       count += _ped_device_probe ("/dev/sdl");
+       count += _ped_device_probe ("/dev/sdm");
+       count += _ped_device_probe ("/dev/sdn");
+       count += _ped_device_probe ("/dev/sdo");
+       count += _ped_device_probe ("/dev/sdp");
+
+       count += _probe_ide_device ("hda");
+       count += _probe_ide_device ("hdb");
+       count += _probe_ide_device ("hdc");
+       count += _probe_ide_device ("hdd");
+       count += _probe_ide_device ("hde");
+       count += _probe_ide_device ("hdf");
+       count += _probe_ide_device ("hdg");
+       count += _probe_ide_device ("hdh");
+       count += _probe_ide_device ("hdi");
+       count += _probe_ide_device ("hdj");
 
-       return 1;
+       return count;
 }
 
 static void
 linux_probe_all ()
 {
-       _probe_proc_partitions ();
-
-       /* we should probe the standard devs too, even with /proc/partitions,
-        * because /proc/partitions might return devfs stuff, and we might not
-        * have devfs available
-        */
-       _probe_standard_devices ();
+       /* If we don't get anything from /proc/partitions, do a manual scan */
+       if (!_probe_proc_partitions ())
+               _probe_standard_devices ();
 }
 
 static char*
--
Andreas Dilger
http://sourceforge.net/projects/ext2resize/
http://www-mddsp.enel.ucalgary.ca/People/adilger/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]