aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util-linux/mdev.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 43527f645..003a27b56 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -10,6 +10,41 @@
10#include "libbb.h" 10#include "libbb.h"
11#include "xregex.h" 11#include "xregex.h"
12 12
13/* "mdev -s" scans /sys/class/xxx, looking for directories which have dev
14 * file (it is of the form "M:m\n"). Example: /sys/class/tty/tty0/dev
15 * contains "4:0\n". Directory name is taken as device name, path component
16 * directly after /sys/class/ as subsystem. In this example, "tty0" and "tty".
17 * Then mdev creates the /dev/device_name node.
18 *
19 * mdev w/o parameters is called as hotplug helper. It takes device
20 * and subsystem names from $DEVPATH and $SUBSYSTEM, extracts
21 * maj,min from "/sys/$DEVPATH/dev" and also examines
22 * $ACTION ("add"/"delete") and $FIRMWARE.
23 *
24 * If action is "add", mdev creates /dev/device_name similarly to mdev -s.
25 * (todo: explain "delete" and $FIRMWARE)
26 *
27 * If /etc/mdev.conf exists, it may modify /dev/device_name's properties.
28 * /etc/mdev.conf file format:
29 *
30 * [-][subsystem/]device user:grp mode [>|=path] [@|$|*command args...]
31 * [-]@maj,min[-min2] user:grp mode [>|=path] [@|$|*command args...]
32 *
33 * The device name or "subsystem/device" combo is matched against 1st field
34 * (which is a regex), or maj,min is matched against 1st field.
35 *
36 * Leading minus in 1st field means "don't stop on this line", otherwise
37 * search is stopped after the matching line is encountered.
38 *
39 * When line matches, the device node is created, chmod'ed and chown'ed.
40 * Then it moved to path, and if >path, a symlink to moved node is created
41 * Examples:
42 * =loop/ - moves to /dev/loop
43 * >disk/sda%1 - moves to /dev/disk/sdaN, makes /dev/sdaN a symlink
44 * Then "command args" is executed (via sh -c 'command args').
45 * @:execute on creation, $:on deletion, *:on both.
46 */
47
13struct globals { 48struct globals {
14 int root_major, root_minor; 49 int root_major, root_minor;
15 char *subsystem; 50 char *subsystem;
@@ -96,8 +131,11 @@ static void make_device(char *path, int delete)
96 if (strstr(path, "/block/")) 131 if (strstr(path, "/block/"))
97 type = S_IFBLK; 132 type = S_IFBLK;
98 133
99 /* Make path point to subsystem/device_name */ 134 /* Make path point to "subsystem/device_name" */
100 path += sizeof("/sys/class/") - 1; 135 if (path[5] == 'b') /* legacy /sys/block? */
136 path += sizeof("/sys/") - 1;
137 else
138 path += sizeof("/sys/class/") - 1;
101 139
102#if !ENABLE_FEATURE_MDEV_CONF 140#if !ENABLE_FEATURE_MDEV_CONF
103 mode = 0660; 141 mode = 0660;
@@ -131,8 +169,8 @@ static void make_device(char *path, int delete)
131 keep_matching = ('-' == val[0]); 169 keep_matching = ('-' == val[0]);
132 val += keep_matching; /* swallow leading dash */ 170 val += keep_matching; /* swallow leading dash */
133 171
134 /* Match against either subsystem/device_name 172 /* Match against either "subsystem/device_name"
135 * or device_name alone */ 173 * or "device_name" alone */
136 name = strchr(val, '/') ? path : (char *) device_name; 174 name = strchr(val, '/') ? path : (char *) device_name;
137 175
138 /* Fields: regex uid:gid mode [alias] [cmd] */ 176 /* Fields: regex uid:gid mode [alias] [cmd] */