diff options
-rw-r--r-- | util-linux/mdev.c | 46 |
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 | |||
13 | struct globals { | 48 | struct 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] */ |