linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* remove sleeps from udev as it is external now
@ 2004-10-14  2:39 Kay Sievers
  2004-10-14 20:42 ` Greg KH
  0 siblings, 1 reply; 2+ messages in thread
From: Kay Sievers @ 2004-10-14  2:39 UTC (permalink / raw)
  To: linux-hotplug

[-- Attachment #1: Type: text/plain, Size: 281 bytes --]

Here we remove all the sysfs sleep loops from udev as wait_for_sysfs
will do this for us and any other hotplug user. We still keep a small
blacklist of subsystems we don't care about but any missing entry here
will no longer lead to a spinning udev waiting for files.

Thanks,
Kay

[-- Attachment #2: udev-kill-sleep-01.patch --]
[-- Type: text/plain, Size: 12626 bytes --]

===== namedev.c 1.151 vs edited =====
--- 1.151/namedev.c	2004-10-14 01:04:51 +02:00
+++ edited/namedev.c	2004-10-14 03:26:30 +02:00
@@ -346,69 +346,6 @@
 	}
 }
 
-/* 
- * Note, we can have multiple files for different busses in here due
- * to the mess that USB has for its device tree...
- */
-static struct bus_file {
-	char *bus;
-	char *file;
-} bus_files[] = {
-	{ .bus = "scsi",	.file = "vendor" },
-	{ .bus = "usb",		.file = "idVendor" },
-	{ .bus = "usb",		.file = "iInterface" },
-	{ .bus = "usb-serial",	.file = "detach_state" },
-	{ .bus = "ide",		.file = "detach_state" },
-	{ .bus = "pci",		.file = "vendor" },
-	{}
-};
-
-static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device)
-{
-	/* sleep until we see the file for this specific bus type show up this
-	 * is needed because we can easily out-run the kernel in looking for
-	 * these files before the paticular subsystem has created them in the
-	 * sysfs tree properly.
-	 *
-	 * And people thought that the /sbin/hotplug event system was going to
-	 * be slow, poo on you for arguing that before even testing it...
-	 */
-	struct bus_file *b = &bus_files[0];
-	struct sysfs_attribute *tmpattr;
-	int found = 0;
-	int loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ;
-
-	while (1) {
-		if (b->bus == NULL) {
-			if (!found)
-				break;
-			/* give the kernel a chance to create the file */
-			usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ);
-			--loop;
-			if (loop == 0)
-				break;
-			b = &bus_files[0];
-		}
-		if (strcmp(sysfs_device->bus, b->bus) == 0) {
-			found = 1;
-			dbg("looking for file '%s' on bus '%s'", b->file, b->bus);
-			tmpattr = sysfs_get_device_attr(sysfs_device, b->file);
-			if (tmpattr) {
-				/* found it! */
-				goto exit;
-			}
-			dbg("can't find '%s' file", b->file);
-		}
-		++b;
-	}
-	if (!found)
-		dbg("did not find bus type '%s' on list of bus_id_files, "
-		    "please report to <linux-hotplug-devel@lists.sourceforge.net>",
-		    sysfs_device->bus);
-exit:
-	return; /* here to prevent compiler warning... */
-}
-
 static void fix_kernel_name(struct udevice *udev)
 {
 	char *temp = udev->kernel_name;
@@ -650,108 +587,6 @@
 	return 0;
 }
 
-static int whitelist_search(struct sysfs_class_device *class_dev)
-{
-	char *sysblock = "/sys/block";
-  	int i;
-
-  	static char *list[] = {
-  		"nb",
-  		"ram",
-  		"loop",
-		"fd",
-  		"md",
-		"dos_cd",
-		"double",
-  		"flash",
-		"msd",
-		"rflash",
-  		"rom",
-		"rrom",
-  		"sbpcd",
-  		"pcd",
-  		"pf",
-  		"scd",
-  		"ubd",
-		NULL,
-  	};
-
-	if (strncmp(class_dev->path, sysblock, strlen(sysblock)))
-		return 0;
-
-	for (i=0; list[i] != NULL; i++)
-		if (!strncmp(class_dev->name, list[i], strlen(list[i])))
-			return 1;
-
-	return 0;
-}
-
-static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev)
-{
-	struct sysfs_device *sysfs_device;
-	struct sysfs_class_device *class_dev_parent;
-	int loop;
-
-	/* Figure out where the device symlink is at.  For char devices this will
-	 * always be in the class_dev->path.  But for block devices, it's different.
-	 * The main block device will have the device symlink in it's path, but
-	 * all partitions have the symlink in its parent directory.
-	 * But we need to watch out for block devices that do not have parents, yet
-	 * look like a partition (fd0, loop0, etc.)  They all do not have a device
-	 * symlink yet.  We do sit and spin on waiting for them right now unless
-	 * they happen to be in the whitelist in which case we exit.
-	 */
-	class_dev_parent = sysfs_get_classdev_parent(class_dev);
-	if (class_dev_parent != NULL) 
-		dbg("given class device has a parent, use this instead");
-
-	loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ;
-	while (loop--) {
-		if (udev_sleep) {
-			if (whitelist_search(class_dev)) {
-				sysfs_device = NULL;
-				goto exit;
-			}
-			usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ);
-		}
-
-		if (class_dev_parent)
-			sysfs_device = sysfs_get_classdev_device(class_dev_parent);
-		else
-			sysfs_device = sysfs_get_classdev_device(class_dev);
-		if (sysfs_device != NULL)
-			goto device_found;
-	}
-	dbg("timed out waiting for device symlink, continuing on anyway...");
-
-device_found:
-        /* We have another issue with just the wait above - the sysfs part of
-	 * the kernel may not be quick enough to have created the link to the
-	 * device under the "bus" subsystem. Due to this, the sysfs_device->bus
-	 * will not contain the actual bus name :(
-	 */
-        if (sysfs_device) {
-		if (sysfs_device->bus[0] != '\0')
-			goto bus_found;
-
-		while (loop--) {
-			if (udev_sleep)
-				usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ);
-			sysfs_get_device_bus(sysfs_device);
-			
-			if (sysfs_device->bus[0] != '\0')
-				goto bus_found;
-		}
-		dbg("timed out waiting to find the device bus, continuing on anyway");
-		goto exit;
-bus_found:
-		dbg("device %s is registered with bus '%s'",
-				sysfs_device->name, sysfs_device->bus);
-	}
-exit:
-	return sysfs_device;
-}
-
 static int match_rule(struct config_device *dev, struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
 {
 	while (1) {
@@ -859,6 +694,7 @@
 
 int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev)
 {
+	struct sysfs_class_device *class_dev_parent;
 	struct sysfs_device *sysfs_device = NULL;
 	struct config_device *dev;
 	struct perm_device *perm;
@@ -866,17 +702,26 @@
 	char *pos;
 
 	udev->mode = 0;
+	dbg("class_dev->name='%s'", class_dev->name);
+
+	/* Figure out where the "device"-symlink is at.  For char devices this will
+	 * always be in the class_dev->path.  On block devices, only the main block
+	 * device will have the device symlink in it's path. All partition devices
+	 * need to look at the symlink in its parent directory.
+	 */
+	class_dev_parent = sysfs_get_classdev_parent(class_dev);
+	if (class_dev_parent != NULL) {
+		dbg("given class device has a parent, use this instead");
+		sysfs_device = sysfs_get_classdev_device(class_dev_parent);
+	} else {
+		sysfs_device = sysfs_get_classdev_device(class_dev);
+	}
 
-	/* find the sysfs_device associated with this class device */
-	sysfs_device = get_sysfs_device(class_dev);
 	if (sysfs_device) {
-		dbg("sysfs_device->path='%s'", sysfs_device->path);
-		dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id);
-		dbg("sysfs_device->bus='%s'", sysfs_device->bus);
+		dbg("found /device-device: path='%s', bus_id='%s', bus='%s'",
+		    sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus);
 		strfieldcpy(udev->bus_id, sysfs_device->bus_id);
-		wait_for_device_to_initialize(sysfs_device);
 	}
-	dbg("class_dev->name = '%s'", class_dev->name);
 
 	strfieldcpy(udev->kernel_name, class_dev->name);
 	fix_kernel_name(udev);
===== udev.8.in 1.60 vs edited =====
--- 1.60/udev.8.in	2004-09-07 13:12:59 +02:00
+++ edited/udev.8.in	2004-10-14 03:14:12 +02:00
@@ -20,13 +20,6 @@
 .B udev
 config file.
 .TP
-.B UDEV_NO_SLEEP
-The default behavior of
-.B udev
-is to wait until all the sysfs files of the device chain are populated. If set,
-.B udev
-will continue, regardless of the state of the device representation.
-.TP
 .B UDEV_NO_DEVD
 The default behavior of
 .B udev
===== udev.c 1.66 vs edited =====
--- 1.66/udev.c	2004-10-14 00:22:37 +02:00
+++ edited/udev.c	2004-10-14 04:09:31 +02:00
@@ -75,14 +75,34 @@
 	}
 }
 
-static char *subsystem_blacklist[] = {
-	"scsi_host",
-	"scsi_device",
-	"usb_host",
-	"pci_bus",
-	"pcmcia_socket",
-	""
-};
+/* list of subsystems we don't care about. not listing such systems here
+ * is not critical, but it makes it faster as we don't look for the "dev" file
+ */
+static int subsystem_without_dev(const char *subsystem)
+{
+	char *subsystem_blacklist[] = {
+		"scsi_host",
+		"scsi_device",
+		"usb_host",
+		"pci_bus",
+		"pcmcia_socket",
+		"bluetooth",
+		"i2c-adapter",
+		"pci_bus",
+		"ieee1394",
+		"ieee1394_host",
+		"ieee1394_node",
+		NULL
+	};
+	char **subsys;
+
+	for (subsys = subsystem_blacklist; *subsys != NULL; subsys++) {
+		if (strcmp(subsystem, *subsys) == 0)
+			return 1;
+	}
+
+	return 0;
+}
 
 int main(int argc, char *argv[], char *envp[])
 {
@@ -92,7 +112,6 @@
 	char *action;
 	char *devpath = "";
 	char *subsystem = "";
-	int i;
 	int retval = -EINVAL;
 	enum {
 		ADD,
@@ -143,20 +162,16 @@
 		}
 
 		/* skip blacklisted subsystems */
-		i = 0;
-		while (subsystem_blacklist[i][0] != '\0') {
-			if (strcmp(subsystem, subsystem_blacklist[i]) == 0) {
-				dbg("don't care about '%s' devices", subsystem);
-				goto exit;
-			}
-			i++;
-		}
+		if (subsystem_without_dev(subsystem)) {
+			dbg("don't care about '%s' devices", subsystem);
+			exit(0);
+		};
 	}
 
 	/* set signal handlers */
 	act.sa_handler = (void (*) (int))sig_handler;
 	sigemptyset (&act.sa_mask);
-	/* alarm must interrupt syscalls*/
+	/* alarm must not restart syscalls*/
 	sigaction(SIGALRM, &act, NULL);
 	sigaction(SIGINT, &act, NULL);
 	sigaction(SIGTERM, &act, NULL);
@@ -172,7 +187,6 @@
 	case UDEVSTART:
 		dbg("udevstart");
 		namedev_init();
-		udev_sleep = 0;
 		retval = udev_start();
 		break;
 	case ADD:
===== udev.h 1.63 vs edited =====
--- 1.63/udev.h	2004-10-13 23:16:25 +02:00
+++ edited/udev.h	2004-10-14 03:16:33 +02:00
@@ -27,8 +27,6 @@
 #include "libsysfs/sysfs/libsysfs.h"
 
 #define ALARM_TIMEOUT			30
-#define WAIT_FOR_FILE_SECONDS		10
-#define WAIT_FOR_FILE_RETRY_FREQ	10
 #define COMMENT_CHARACTER		'#'
 
 #define NAME_SIZE			256
@@ -90,7 +88,6 @@
 extern char default_owner_str[OWNER_SIZE];
 extern char default_group_str[GROUP_SIZE];
 extern int udev_log;
-extern int udev_sleep;
 extern int udev_dev_d;
 
 #endif
===== udev_add.c 1.76 vs edited =====
--- 1.76/udev_add.c	2004-10-13 22:31:48 +02:00
+++ edited/udev_add.c	2004-10-14 04:32:18 +02:00
@@ -52,14 +52,9 @@
 
 #include "selinux.h"
 
-/* 
- * Right now the major/minor of a device is stored in a file called
- * "dev" in sysfs.
- * The number is stored as:
- * 	MM:mm
- * 		MM is the major
- * 		mm is the minor
- * 		The value is in decimal.
+/*
+ * the major/minor of a device is stored in a file called "dev"
+ * The number is stored in decimal values in the format: M:m
  */
 static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev)
 {
@@ -345,35 +340,6 @@
 	return class_dev;
 }
 
-/* wait for the "dev" file to show up in the directory in sysfs.
- * If it doesn't happen in about 10 seconds, give up.
- */
-static int sleep_for_file(const char *path, char* file)
-{
-	char filename[SYSFS_PATH_MAX + 6];
-	int loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ;
-	int retval;
-
-	strfieldcpy(filename, sysfs_path);
-	strfieldcat(filename, path);
-	strfieldcat(filename, file);
-
-	while (loop--) {
-		struct stat buf;
-
-		dbg("looking for '%s'", filename);
-		retval = stat(filename, &buf);
-		if (retval == 0)
-			goto exit;
-
-		/* sleep to give the kernel a chance to create the dev file */
-		usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ);
-	}
-	retval = -ENODEV;
-exit:
-	return retval;
-}
-
 static int rename_net_if(struct udevice *dev, int fake)
 {
 	int sk;
@@ -408,25 +374,11 @@
 	struct udevice dev;
 	char devpath[DEVPATH_SIZE];
 	char *pos;
-	int retval;
+	int retval = 0;
 
 	memset(&dev, 0x00, sizeof(dev));
 
 	dev.type = get_device_type(path, subsystem);
-	switch (dev.type) {
-	case 'b':
-	case 'c':
-		retval = sleep_for_file(path, "/dev");
-		break;
-
-	case 'n':
-		retval = sleep_for_file(path, "/address");
-		break;
-
-	default:
-		dbg("unknown device type '%c'", dev.type);
-		return -1;
-	}
 
 	class_dev = get_class_dev(path);
 	if (class_dev == NULL)
@@ -435,8 +387,8 @@
 	if (dev.type == 'b' || dev.type == 'c') {
 		retval = get_major_minor(class_dev, &dev);
 		if (retval != 0) {
-			dbg("get_major_minor failed");
-			goto exit;
+			dbg("no dev-file found, do nothing");
+			goto close;
 		}
 	}
 
@@ -484,6 +436,7 @@
 
 exit:
 	selinux_restore();
+close:
 	sysfs_close_class_device(class_dev);
 
 	return retval;
===== udev_config.c 1.21 vs edited =====
--- 1.21/udev_config.c	2004-09-14 16:02:10 +02:00
+++ edited/udev_config.c	2004-10-14 03:13:13 +02:00
@@ -50,7 +50,6 @@
 char default_owner_str[OWNER_SIZE];
 char default_group_str[GROUP_SIZE];
 int udev_log;
-int udev_sleep;
 int udev_dev_d;
 
 
@@ -78,11 +77,6 @@
 	strfieldcpy(udev_rules_filename, UDEV_RULES_FILE);
 	strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE);
 	udev_log = string_is_true(UDEV_LOG_DEFAULT);
-
-	udev_sleep = 1;
-	env = getenv("UDEV_NO_SLEEP");
-	if (env && string_is_true(env))
-		udev_sleep = 0;
 
 	udev_dev_d = 1;
 	env = getenv("UDEV_NO_DEVD");

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-10-14 20:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-14  2:39 remove sleeps from udev as it is external now Kay Sievers
2004-10-14 20:42 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).