Dear,

Here's the patch correcting mdev, using recursive_action :

We noticed that some devices were not attached to /dev/ using "mdev -s".
Looking at the source code, the function which walk through the /sys/ tree
make use of lstat, but the /sys tree can use symlink as seen here :

$ ls -l /sys/class/misc/
lrwxrwxrwx    1 root     root            0 Jan  1  1970 watchdog ->
../../devices/platform/at91sam9x_wdt/watchdog

Doing so, the function can't walk through symbolic links. By replacing lstat
by stat, the problem is corrected.
To avoid infinite loop, we added a walking through depth limit to 2 (see
udevstart.c).

Cheers
diff -Nru busybox-1.4.1/util-linux/mdev.c busybox-1.4.1_modified/util-linux/mdev.c
--- busybox-1.4.1/util-linux/mdev.c	2007-01-24 22:34:51.000000000 +0100
+++ busybox-1.4.1_modified/util-linux/mdev.c	2007-06-11 09:47:25.187221688 +0200
@@ -1,4 +1,3 @@
-/* vi: set sw=4 ts=4: */
 /*
  *
  * mdev - Mini udev for busybox
@@ -14,6 +13,8 @@
 
 #define DEV_PATH	"/dev"
 
+#define MAX_DEPTH	3
+
 struct mdev_globals
 {
 	int root_major, root_minor;
@@ -194,41 +195,34 @@
 	if (delete) unlink(device_name);
 }
 
-/* Recursive search of /sys/block or /sys/class.  path must be a writeable
- * buffer of size PATH_MAX containing the directory string to start at. */
 
-static void find_dev(char *path)
+int faction(const char *fileName, struct stat *statbuf, void* userData, int depth)
 {
-	DIR *dir;
-	size_t len = strlen(path);
-	struct dirent *entry;
-
-	dir = opendir(path);
-	if (dir == NULL)
-		return;
-
-	while ((entry = readdir(dir)) != NULL) {
-		struct stat st;
-
-		/* Skip "." and ".." (also skips hidden files, which is ok) */
-
-		if (entry->d_name[0] == '.')
-			continue;
-
-		// uClibc doesn't fill out entry->d_type reliably. so we use lstat().
+	char *pt;
+	
+	/* Remove path from fileName */
+	pt = strrchr(fileName,'/');
+	
+	if(!pt || strcmp(pt, DEV_PATH))
+		return FALSE;
+		
+	make_device(xasprintf("%.*s",pt-fileName,fileName), 0);
 
-		snprintf(path+len, PATH_MAX-len, "/%s", entry->d_name);
-		if (!lstat(path, &st) && S_ISDIR(st.st_mode)) find_dev(path);
-		path[len] = 0;
-
-		/* If there's a dev entry, mknod it */
-
-		if (!strcmp(entry->d_name, "dev")) make_device(path, 0);
-	}
+	return TRUE;	
+}
 
-	closedir(dir);
+int daction(const char *fileName, struct stat *statbuf, void* userData, int depth)
+{
+	/* Maximum depth */ 
+	if(depth>=MAX_DEPTH)
+		return SKIP;
+		
+	return TRUE;
 }
 
+/* Recursive search of /sys/block or /sys/class.  
+ * The recursive depth is limited to avoid inifinite loop (circular symlinks)
+ */
 int mdev_main(int argc, char *argv[])
 {
 	char *action;
@@ -245,10 +239,10 @@
 		xstat("/", &st);
 		bbg.root_major = major(st.st_dev);
 		bbg.root_minor = minor(st.st_dev);
-		strcpy(temp,"/sys/block");
-		find_dev(temp);
-		strcpy(temp,"/sys/class");
-		find_dev(temp);
+		recursive_action("/sys/block", TRUE, TRUE, FALSE, 
+			faction, daction, NULL, 0);
+		recursive_action("/sys/class", TRUE, TRUE, FALSE, 
+			faction, daction, NULL, 0);
 
 	/* Hotplug */
 
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to