mdev : bug corrected (patch attached) - recursive_action version

Bernhard Fischer rep.dot.nop at gmail.com
Mon Jun 11 13:40:37 UTC 2007


On Mon, Jun 11, 2007 at 09:56:37AM +0200, Renaud Cerrato wrote:
>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)

This has to be static.

>+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);

This has to be static.

>+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);

Very nice. What is the size(1) output for the original binary and the
new one?

Please comment each of these arguments (see e.g. tail of find.c).
>+		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
>busybox at busybox.net
>http://busybox.net/cgi-bin/mailman/listinfo/busybox



More information about the busybox mailing list