wok-tiny diff busybox/stuff/0001-mdev-create-devices-from-sys-dev.patch @ rev 128

busybox/mdev: restore /sys layout
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Apr 13 19:09:32 2017 +0200 (2017-04-13)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/busybox/stuff/0001-mdev-create-devices-from-sys-dev.patch	Thu Apr 13 19:09:32 2017 +0200
     1.3 @@ -0,0 +1,198 @@
     1.4 +From 20a3262cd756aadf8771969a4764cd3c571f0a3e Mon Sep 17 00:00:00 2001
     1.5 +From: Denys Vlasenko <vda.linux@googlemail.com>
     1.6 +Date: Wed, 7 Sep 2016 14:09:01 +0200
     1.7 +Subject: [PATCH] mdev: create devices from /sys/dev
     1.8 +
     1.9 +Currently some new devices that have a bus but no class will
    1.10 +be missed by mdev coldplug device creation after boot. This
    1.11 +happens because mdev recursively searches /sys/class which will
    1.12 +by definition only find class devices.
    1.13 +
    1.14 +Some important devices such as iio and gpiochip does not have
    1.15 +a class. But users will need them.
    1.16 +
    1.17 +This switches from using /sys/class as the place to look for
    1.18 +devices to create to using /sys/dev where all char and block
    1.19 +devices are listed.
    1.20 +
    1.21 +The subsystem lookup code that provide the G.subsystem
    1.22 +environment variable is changed from using the directory
    1.23 +name of the class device to instead dereference the
    1.24 +"subsystem" symlink for the device, and look at the last
    1.25 +element of the path of the symlink for the subsystem, which
    1.26 +will work with class devices and bus devices alike. (The new
    1.27 +bus-only devices only symlink to the /sys/bus/* hierarchy.)
    1.28 +
    1.29 +We delete the legacy kernel v2.6.2x /sys/block device path
    1.30 +code as part of this change. It's too old to be kept alive.
    1.31 +
    1.32 +Tested on kernel v4.6-rc2 with a bunch of devices, including
    1.33 +some IIO and gpiochip devices.
    1.34 +
    1.35 +With a print inserted before make_device() the log looks
    1.36 +like so:
    1.37 +
    1.38 +Create device from "/sys/dev/char/1:1", subsystem "mem"
    1.39 +Create device from "/sys/dev/char/1:2", subsystem "mem"
    1.40 +Create device from "/sys/dev/char/1:3", subsystem "mem"
    1.41 +Create device from "/sys/dev/char/1:5", subsystem "mem"
    1.42 +(...)
    1.43 +Create device from "/sys/dev/block/179:56", subsystem "block"
    1.44 +Create device from "/sys/dev/block/179:64", subsystem "block"
    1.45 +
    1.46 +function                                             old     new   delta
    1.47 +mdev_main                                           1388    1346     -42
    1.48 +dirAction                                            134      14    -120
    1.49 +------------------------------------------------------------------------------
    1.50 +(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-162)           Total: -162 bytes
    1.51 +
    1.52 +Cc: Isaac Dunham <ibid.ag@gmail.com>
    1.53 +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    1.54 +Cc: Jonathan Cameron <jic23@cam.ac.uk>
    1.55 +Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
    1.56 +Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
    1.57 +---
    1.58 + util-linux/mdev.c | 88 ++++++++++++++++++++++++++-----------------------------
    1.59 + 1 file changed, 41 insertions(+), 47 deletions(-)
    1.60 +
    1.61 +diff --git a/util-linux/mdev.c b/util-linux/mdev.c
    1.62 +index 37514eb..a59115d 100644
    1.63 +--- a/util-linux/mdev.c
    1.64 ++++ b/util-linux/mdev.c
    1.65 +@@ -543,8 +543,7 @@ static char *build_alias(char *alias, const char *device_name)
    1.66 + 
    1.67 + /* mknod in /dev based on a path like "/sys/block/hda/hda1"
    1.68 +  * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes
    1.69 +- * after NUL, but we promise to not mangle (IOW: to restore NUL if needed)
    1.70 +- * path string.
    1.71 ++ * after NUL, but we promise to not mangle it (IOW: to restore NUL if needed).
    1.72 +  * NB2: "mdev -s" may call us many times, do not leak memory/fds!
    1.73 +  *
    1.74 +  * device_name = $DEVNAME (may be NULL)
    1.75 +@@ -810,41 +809,39 @@ static void make_device(char *device_name, char *path, int operation)
    1.76 + 	} /* for (;;) */
    1.77 + }
    1.78 + 
    1.79 +-/* File callback for /sys/ traversal */
    1.80 ++/* File callback for /sys/ traversal.
    1.81 ++ * We act only on "/sys/.../dev" (pseudo)file
    1.82 ++ */
    1.83 + static int FAST_FUNC fileAction(const char *fileName,
    1.84 + 		struct stat *statbuf UNUSED_PARAM,
    1.85 + 		void *userData,
    1.86 + 		int depth UNUSED_PARAM)
    1.87 + {
    1.88 + 	size_t len = strlen(fileName) - 4; /* can't underflow */
    1.89 +-	char *scratch = userData;
    1.90 +-
    1.91 +-	/* len check is for paranoid reasons */
    1.92 +-	if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX)
    1.93 +-		return FALSE;
    1.94 +-
    1.95 +-	strcpy(scratch, fileName);
    1.96 +-	scratch[len] = '\0';
    1.97 +-	make_device(/*DEVNAME:*/ NULL, scratch, OP_add);
    1.98 +-
    1.99 +-	return TRUE;
   1.100 +-}
   1.101 +-
   1.102 +-/* Directory callback for /sys/ traversal */
   1.103 +-static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
   1.104 +-		struct stat *statbuf UNUSED_PARAM,
   1.105 +-		void *userData UNUSED_PARAM,
   1.106 +-		int depth)
   1.107 +-{
   1.108 +-	/* Extract device subsystem -- the name of the directory
   1.109 +-	 * under /sys/class/ */
   1.110 +-	if (1 == depth) {
   1.111 ++	char *path = userData;	/* char array[PATH_MAX + SCRATCH_SIZE] */
   1.112 ++	char subsys[PATH_MAX];
   1.113 ++	int res;
   1.114 ++
   1.115 ++	/* Is it a ".../dev" file? (len check is for paranoid reasons) */
   1.116 ++	if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX - 32)
   1.117 ++		return FALSE; /* not .../dev */
   1.118 ++
   1.119 ++	strcpy(path, fileName);
   1.120 ++	path[len] = '\0';
   1.121 ++
   1.122 ++	/* Read ".../subsystem" symlink in the same directory where ".../dev" is */
   1.123 ++	strcpy(subsys, path);
   1.124 ++	strcpy(subsys + len, "/subsystem");
   1.125 ++	res = readlink(subsys, subsys, sizeof(subsys)-1);
   1.126 ++	if (res > 0) {
   1.127 ++		subsys[res] = '\0';
   1.128 + 		free(G.subsystem);
   1.129 + 		if (G.subsys_env) {
   1.130 + 			bb_unsetenv_and_free(G.subsys_env);
   1.131 + 			G.subsys_env = NULL;
   1.132 + 		}
   1.133 +-		G.subsystem = strrchr(fileName, '/');
   1.134 ++		/* Set G.subsystem and $SUBSYSTEM from symlink's last component */
   1.135 ++		G.subsystem = strrchr(subsys, '/');
   1.136 + 		if (G.subsystem) {
   1.137 + 			G.subsystem = xstrdup(G.subsystem + 1);
   1.138 + 			G.subsys_env = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem);
   1.139 +@@ -852,6 +849,17 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
   1.140 + 		}
   1.141 + 	}
   1.142 + 
   1.143 ++	make_device(/*DEVNAME:*/ NULL, path, OP_add);
   1.144 ++
   1.145 ++	return TRUE;
   1.146 ++}
   1.147 ++
   1.148 ++/* Directory callback for /sys/ traversal */
   1.149 ++static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
   1.150 ++		struct stat *statbuf UNUSED_PARAM,
   1.151 ++		void *userData UNUSED_PARAM,
   1.152 ++		int depth)
   1.153 ++{
   1.154 + 	return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
   1.155 + }
   1.156 + 
   1.157 +@@ -872,8 +880,9 @@ static void load_firmware(const char *firmware, const char *sysfs_path)
   1.158 + 	int firmware_fd, loading_fd;
   1.159 + 
   1.160 + 	/* check for /lib/firmware/$FIRMWARE */
   1.161 +-	xchdir("/lib/firmware");
   1.162 +-	firmware_fd = open(firmware, O_RDONLY); /* can fail */
   1.163 ++	firmware_fd = -1;
   1.164 ++	if (chdir("/lib/firmware") == 0)
   1.165 ++		firmware_fd = open(firmware, O_RDONLY); /* can fail */
   1.166 + 
   1.167 + 	/* check for /sys/$DEVPATH/loading ... give 30 seconds to appear */
   1.168 + 	xchdir(sysfs_path);
   1.169 +@@ -1065,25 +1074,10 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
   1.170 + 
   1.171 + 		putenv((char*)"ACTION=add");
   1.172 + 
   1.173 +-		/* ACTION_FOLLOWLINKS is needed since in newer kernels
   1.174 +-		 * /sys/block/loop* (for example) are symlinks to dirs,
   1.175 +-		 * not real directories.
   1.176 +-		 * (kernel's CONFIG_SYSFS_DEPRECATED makes them real dirs,
   1.177 +-		 * but we can't enforce that on users)
   1.178 +-		 */
   1.179 +-		if (access("/sys/class/block", F_OK) != 0) {
   1.180 +-			/* Scan obsolete /sys/block only if /sys/class/block
   1.181 +-			 * doesn't exist. Otherwise we'll have dupes.
   1.182 +-			 * Also, do not complain if it doesn't exist.
   1.183 +-			 * Some people configure kernel to have no blockdevs.
   1.184 +-			 */
   1.185 +-			recursive_action("/sys/block",
   1.186 +-				ACTION_RECURSE | ACTION_FOLLOWLINKS | ACTION_QUIET,
   1.187 +-				fileAction, dirAction, temp, 0);
   1.188 +-		}
   1.189 +-		recursive_action("/sys/class",
   1.190 +-			ACTION_RECURSE | ACTION_FOLLOWLINKS,
   1.191 +-			fileAction, dirAction, temp, 0);
   1.192 ++		/* Create all devices from /sys/dev hierarchy */
   1.193 ++		recursive_action("/sys/dev",
   1.194 ++				 ACTION_RECURSE | ACTION_FOLLOWLINKS,
   1.195 ++				 fileAction, dirAction, temp, 0);
   1.196 + 	} else {
   1.197 + 		char *fw;
   1.198 + 		char *seq;
   1.199 +-- 
   1.200 +2.9.2
   1.201 +