add support for renaming/relocating device nodes

This commit is contained in:
Mike Frysinger 2008-02-01 06:53:50 +00:00
parent c348e0bc7b
commit f0044c480c
3 changed files with 61 additions and 5 deletions

View File

@ -53,6 +53,15 @@ matched, then the default of 0:0 660 is used. To set your own default, simply
create your own total match like so: create your own total match like so:
.* 1:1 777 .* 1:1 777
You can rename/relocate device nodes by using the next optional field.
<device regex> <uid>:<gid> <octal permissions> [>path]
So if you want to place the device node into a subdirectory, make sure the path
has a trailing /. If you want to rename the device node, just place the name.
hda 0:3 660 >drives/
This will relocate "hda" into the drives/ subdirectory.
hdb 0:3 660 >cdrom
This will rename "hdb" to "cdrom".
If you also enable support for executing your own commands, then the file has If you also enable support for executing your own commands, then the file has
the format: the format:
<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>] <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]

View File

@ -301,6 +301,15 @@ config FEATURE_MDEV_CONF
For more information, please see docs/mdev.txt For more information, please see docs/mdev.txt
config FEATURE_MDEV_RENAME
bool "Support subdirs/symlinks"
default n
depends on FEATURE_MDEV_CONF
help
Add support for renaming devices and creating symlinks.
For more information, please see docs/mdev.txt
config FEATURE_MDEV_EXEC config FEATURE_MDEV_EXEC
bool "Support command execution at device addition/removal" bool "Support command execution at device addition/removal"
default n default n

View File

@ -31,6 +31,10 @@ static void make_device(char *path, int delete)
gid_t gid = 0; gid_t gid = 0;
char *temp = path + strlen(path); char *temp = path + strlen(path);
char *command = NULL; char *command = NULL;
char *alias = NULL;
/* Force the configuration file settings exactly. */
umask(0);
/* Try to read major/minor string. Note that the kernel puts \n after /* Try to read major/minor string. Note that the kernel puts \n after
* the data, so we don't need to worry about null terminating the string * the data, so we don't need to worry about null terminating the string
@ -70,7 +74,7 @@ static void make_device(char *path, int delete)
++lineno; ++lineno;
/* Three fields: regex, uid:gid, mode */ /* Three fields: regex, uid:gid, mode */
for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_EXEC); ++field) { for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_RENAME + ENABLE_FEATURE_MDEV_EXEC); ++field) {
/* Find a non-empty field */ /* Find a non-empty field */
char *val; char *val;
@ -131,7 +135,16 @@ static void make_device(char *path, int delete)
/* Mode device permissions */ /* Mode device permissions */
mode = strtoul(val, NULL, 8); mode = strtoul(val, NULL, 8);
} else if (ENABLE_FEATURE_MDEV_EXEC && field == 3) { } else if (ENABLE_FEATURE_MDEV_RENAME && field == 3) {
if (*val != '>')
++field;
else
alias = xstrdup(val + 1);
}
if (ENABLE_FEATURE_MDEV_EXEC && field == 3 + ENABLE_FEATURE_MDEV_RENAME) {
/* Optional command to run */ /* Optional command to run */
const char *s = "@$*"; const char *s = "@$*";
@ -167,20 +180,45 @@ static void make_device(char *path, int delete)
end_parse: /* nothing */ ; end_parse: /* nothing */ ;
} }
umask(0);
if (!delete) { if (!delete) {
if (sscanf(temp, "%d:%d", &major, &minor) != 2) if (sscanf(temp, "%d:%d", &major, &minor) != 2)
return; return;
if (ENABLE_FEATURE_MDEV_RENAME)
unlink(device_name);
if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
bb_perror_msg_and_die("mknod %s", device_name); bb_perror_msg_and_die("mknod %s", device_name);
if (major == root_major && minor == root_minor) if (major == root_major && minor == root_minor)
symlink(device_name, "root"); symlink(device_name, "root");
if (ENABLE_FEATURE_MDEV_CONF) if (ENABLE_FEATURE_MDEV_CONF) {
chown(device_name, uid, gid); chown(device_name, uid, gid);
if (ENABLE_FEATURE_MDEV_RENAME && alias) {
char *dest;
temp = strrchr(alias, '/');
if (temp) {
if (temp[1] != '\0')
/* given a file name, so rename it */
*temp = '\0';
bb_make_directory(alias, 0755, FILEUTILS_RECUR);
dest = concat_path_file(alias, device_name);
} else
dest = alias;
rename(device_name, dest);
symlink(dest, device_name);
if (alias != dest)
free(alias);
free(dest);
}
}
} }
if (command) { if (ENABLE_FEATURE_MDEV_EXEC && command) {
/* setenv will leak memory, so use putenv */ /* setenv will leak memory, so use putenv */
char *s = xasprintf("MDEV=%s", device_name); char *s = xasprintf("MDEV=%s", device_name);
putenv(s); putenv(s);