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