[Top][All Lists]
[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/
- [PATCH] improve device probing heuristics,
Andreas Dilger <=
- Re: [PATCH] improve device probing heuristics, Andrew Clausen, 2002/02/06
- Re: [PATCH] improve device probing heuristics, Andreas Dilger, 2002/02/06
- Re: [PATCH] improve device probing heuristics, Andrew Clausen, 2002/02/06
- Re: [PATCH] improve device probing heuristics, Andreas Dilger, 2002/02/07
- Re: [PATCH] improve device probing heuristics, Andrew Clausen, 2002/02/07
- Re: [PATCH] improve device probing heuristics, Andreas Dilger, 2002/02/08
- Re: [PATCH] improve device probing heuristics, Andrew Clausen, 2002/02/08