wok-tiny annotate 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
rev   line source
pascal@128 1 From 20a3262cd756aadf8771969a4764cd3c571f0a3e Mon Sep 17 00:00:00 2001
pascal@128 2 From: Denys Vlasenko <vda.linux@googlemail.com>
pascal@128 3 Date: Wed, 7 Sep 2016 14:09:01 +0200
pascal@128 4 Subject: [PATCH] mdev: create devices from /sys/dev
pascal@128 5
pascal@128 6 Currently some new devices that have a bus but no class will
pascal@128 7 be missed by mdev coldplug device creation after boot. This
pascal@128 8 happens because mdev recursively searches /sys/class which will
pascal@128 9 by definition only find class devices.
pascal@128 10
pascal@128 11 Some important devices such as iio and gpiochip does not have
pascal@128 12 a class. But users will need them.
pascal@128 13
pascal@128 14 This switches from using /sys/class as the place to look for
pascal@128 15 devices to create to using /sys/dev where all char and block
pascal@128 16 devices are listed.
pascal@128 17
pascal@128 18 The subsystem lookup code that provide the G.subsystem
pascal@128 19 environment variable is changed from using the directory
pascal@128 20 name of the class device to instead dereference the
pascal@128 21 "subsystem" symlink for the device, and look at the last
pascal@128 22 element of the path of the symlink for the subsystem, which
pascal@128 23 will work with class devices and bus devices alike. (The new
pascal@128 24 bus-only devices only symlink to the /sys/bus/* hierarchy.)
pascal@128 25
pascal@128 26 We delete the legacy kernel v2.6.2x /sys/block device path
pascal@128 27 code as part of this change. It's too old to be kept alive.
pascal@128 28
pascal@128 29 Tested on kernel v4.6-rc2 with a bunch of devices, including
pascal@128 30 some IIO and gpiochip devices.
pascal@128 31
pascal@128 32 With a print inserted before make_device() the log looks
pascal@128 33 like so:
pascal@128 34
pascal@128 35 Create device from "/sys/dev/char/1:1", subsystem "mem"
pascal@128 36 Create device from "/sys/dev/char/1:2", subsystem "mem"
pascal@128 37 Create device from "/sys/dev/char/1:3", subsystem "mem"
pascal@128 38 Create device from "/sys/dev/char/1:5", subsystem "mem"
pascal@128 39 (...)
pascal@128 40 Create device from "/sys/dev/block/179:56", subsystem "block"
pascal@128 41 Create device from "/sys/dev/block/179:64", subsystem "block"
pascal@128 42
pascal@128 43 function old new delta
pascal@128 44 mdev_main 1388 1346 -42
pascal@128 45 dirAction 134 14 -120
pascal@128 46 ------------------------------------------------------------------------------
pascal@128 47 (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-162) Total: -162 bytes
pascal@128 48
pascal@128 49 Cc: Isaac Dunham <ibid.ag@gmail.com>
pascal@128 50 Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
pascal@128 51 Cc: Jonathan Cameron <jic23@cam.ac.uk>
pascal@128 52 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
pascal@128 53 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
pascal@128 54 ---
pascal@128 55 util-linux/mdev.c | 88 ++++++++++++++++++++++++++-----------------------------
pascal@128 56 1 file changed, 41 insertions(+), 47 deletions(-)
pascal@128 57
pascal@128 58 diff --git a/util-linux/mdev.c b/util-linux/mdev.c
pascal@128 59 index 37514eb..a59115d 100644
pascal@128 60 --- a/util-linux/mdev.c
pascal@128 61 +++ b/util-linux/mdev.c
pascal@128 62 @@ -543,8 +543,7 @@ static char *build_alias(char *alias, const char *device_name)
pascal@128 63
pascal@128 64 /* mknod in /dev based on a path like "/sys/block/hda/hda1"
pascal@128 65 * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes
pascal@128 66 - * after NUL, but we promise to not mangle (IOW: to restore NUL if needed)
pascal@128 67 - * path string.
pascal@128 68 + * after NUL, but we promise to not mangle it (IOW: to restore NUL if needed).
pascal@128 69 * NB2: "mdev -s" may call us many times, do not leak memory/fds!
pascal@128 70 *
pascal@128 71 * device_name = $DEVNAME (may be NULL)
pascal@128 72 @@ -810,41 +809,39 @@ static void make_device(char *device_name, char *path, int operation)
pascal@128 73 } /* for (;;) */
pascal@128 74 }
pascal@128 75
pascal@128 76 -/* File callback for /sys/ traversal */
pascal@128 77 +/* File callback for /sys/ traversal.
pascal@128 78 + * We act only on "/sys/.../dev" (pseudo)file
pascal@128 79 + */
pascal@128 80 static int FAST_FUNC fileAction(const char *fileName,
pascal@128 81 struct stat *statbuf UNUSED_PARAM,
pascal@128 82 void *userData,
pascal@128 83 int depth UNUSED_PARAM)
pascal@128 84 {
pascal@128 85 size_t len = strlen(fileName) - 4; /* can't underflow */
pascal@128 86 - char *scratch = userData;
pascal@128 87 -
pascal@128 88 - /* len check is for paranoid reasons */
pascal@128 89 - if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX)
pascal@128 90 - return FALSE;
pascal@128 91 -
pascal@128 92 - strcpy(scratch, fileName);
pascal@128 93 - scratch[len] = '\0';
pascal@128 94 - make_device(/*DEVNAME:*/ NULL, scratch, OP_add);
pascal@128 95 -
pascal@128 96 - return TRUE;
pascal@128 97 -}
pascal@128 98 -
pascal@128 99 -/* Directory callback for /sys/ traversal */
pascal@128 100 -static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
pascal@128 101 - struct stat *statbuf UNUSED_PARAM,
pascal@128 102 - void *userData UNUSED_PARAM,
pascal@128 103 - int depth)
pascal@128 104 -{
pascal@128 105 - /* Extract device subsystem -- the name of the directory
pascal@128 106 - * under /sys/class/ */
pascal@128 107 - if (1 == depth) {
pascal@128 108 + char *path = userData; /* char array[PATH_MAX + SCRATCH_SIZE] */
pascal@128 109 + char subsys[PATH_MAX];
pascal@128 110 + int res;
pascal@128 111 +
pascal@128 112 + /* Is it a ".../dev" file? (len check is for paranoid reasons) */
pascal@128 113 + if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX - 32)
pascal@128 114 + return FALSE; /* not .../dev */
pascal@128 115 +
pascal@128 116 + strcpy(path, fileName);
pascal@128 117 + path[len] = '\0';
pascal@128 118 +
pascal@128 119 + /* Read ".../subsystem" symlink in the same directory where ".../dev" is */
pascal@128 120 + strcpy(subsys, path);
pascal@128 121 + strcpy(subsys + len, "/subsystem");
pascal@128 122 + res = readlink(subsys, subsys, sizeof(subsys)-1);
pascal@128 123 + if (res > 0) {
pascal@128 124 + subsys[res] = '\0';
pascal@128 125 free(G.subsystem);
pascal@128 126 if (G.subsys_env) {
pascal@128 127 bb_unsetenv_and_free(G.subsys_env);
pascal@128 128 G.subsys_env = NULL;
pascal@128 129 }
pascal@128 130 - G.subsystem = strrchr(fileName, '/');
pascal@128 131 + /* Set G.subsystem and $SUBSYSTEM from symlink's last component */
pascal@128 132 + G.subsystem = strrchr(subsys, '/');
pascal@128 133 if (G.subsystem) {
pascal@128 134 G.subsystem = xstrdup(G.subsystem + 1);
pascal@128 135 G.subsys_env = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem);
pascal@128 136 @@ -852,6 +849,17 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
pascal@128 137 }
pascal@128 138 }
pascal@128 139
pascal@128 140 + make_device(/*DEVNAME:*/ NULL, path, OP_add);
pascal@128 141 +
pascal@128 142 + return TRUE;
pascal@128 143 +}
pascal@128 144 +
pascal@128 145 +/* Directory callback for /sys/ traversal */
pascal@128 146 +static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM,
pascal@128 147 + struct stat *statbuf UNUSED_PARAM,
pascal@128 148 + void *userData UNUSED_PARAM,
pascal@128 149 + int depth)
pascal@128 150 +{
pascal@128 151 return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
pascal@128 152 }
pascal@128 153
pascal@128 154 @@ -872,8 +880,9 @@ static void load_firmware(const char *firmware, const char *sysfs_path)
pascal@128 155 int firmware_fd, loading_fd;
pascal@128 156
pascal@128 157 /* check for /lib/firmware/$FIRMWARE */
pascal@128 158 - xchdir("/lib/firmware");
pascal@128 159 - firmware_fd = open(firmware, O_RDONLY); /* can fail */
pascal@128 160 + firmware_fd = -1;
pascal@128 161 + if (chdir("/lib/firmware") == 0)
pascal@128 162 + firmware_fd = open(firmware, O_RDONLY); /* can fail */
pascal@128 163
pascal@128 164 /* check for /sys/$DEVPATH/loading ... give 30 seconds to appear */
pascal@128 165 xchdir(sysfs_path);
pascal@128 166 @@ -1065,25 +1074,10 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
pascal@128 167
pascal@128 168 putenv((char*)"ACTION=add");
pascal@128 169
pascal@128 170 - /* ACTION_FOLLOWLINKS is needed since in newer kernels
pascal@128 171 - * /sys/block/loop* (for example) are symlinks to dirs,
pascal@128 172 - * not real directories.
pascal@128 173 - * (kernel's CONFIG_SYSFS_DEPRECATED makes them real dirs,
pascal@128 174 - * but we can't enforce that on users)
pascal@128 175 - */
pascal@128 176 - if (access("/sys/class/block", F_OK) != 0) {
pascal@128 177 - /* Scan obsolete /sys/block only if /sys/class/block
pascal@128 178 - * doesn't exist. Otherwise we'll have dupes.
pascal@128 179 - * Also, do not complain if it doesn't exist.
pascal@128 180 - * Some people configure kernel to have no blockdevs.
pascal@128 181 - */
pascal@128 182 - recursive_action("/sys/block",
pascal@128 183 - ACTION_RECURSE | ACTION_FOLLOWLINKS | ACTION_QUIET,
pascal@128 184 - fileAction, dirAction, temp, 0);
pascal@128 185 - }
pascal@128 186 - recursive_action("/sys/class",
pascal@128 187 - ACTION_RECURSE | ACTION_FOLLOWLINKS,
pascal@128 188 - fileAction, dirAction, temp, 0);
pascal@128 189 + /* Create all devices from /sys/dev hierarchy */
pascal@128 190 + recursive_action("/sys/dev",
pascal@128 191 + ACTION_RECURSE | ACTION_FOLLOWLINKS,
pascal@128 192 + fileAction, dirAction, temp, 0);
pascal@128 193 } else {
pascal@128 194 char *fw;
pascal@128 195 char *seq;
pascal@128 196 --
pascal@128 197 2.9.2
pascal@128 198