add support for renaming/relocating device nodes
authorMike Frysinger <vapier@gentoo.org>
Fri, 1 Feb 2008 06:53:50 +0000 (06:53 -0000)
committerMike Frysinger <vapier@gentoo.org>
Fri, 1 Feb 2008 06:53:50 +0000 (06:53 -0000)
docs/mdev.txt
util-linux/Config.in
util-linux/mdev.c

index 4a4451b4dd956245c0c558ed707ebf40c7172ed1..38f1da9641387dd345800720b0243b93b4b203e1 100644 (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:
        .* 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
 the format:
        <device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]
index 8ec466bb87a76c7ae29708433052b54c8cd88bb4..d236b77b6f30878ed0d2f4d140a248233d898380 100644 (file)
@@ -301,6 +301,15 @@ config FEATURE_MDEV_CONF
 
          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
        bool "Support command execution at device addition/removal"
        default n
index 65b4da4f48e07359304bcefa9e4515372e23fd72..a18fc0916dd7fa8c83d2863d90b6b3cba4ea94ab 100644 (file)
@@ -31,6 +31,10 @@ static void make_device(char *path, int delete)
        gid_t gid = 0;
        char *temp = path + strlen(path);
        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
         * 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;
 
                        /* 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 */
                                char *val;
@@ -131,7 +135,16 @@ static void make_device(char *path, int delete)
                                        /* Mode device permissions */
                                        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 */
                                        const char *s = "@$*";
@@ -167,20 +180,45 @@ static void make_device(char *path, int delete)
  end_parse:    /* nothing */ ;
        }
 
-       umask(0);
        if (!delete) {
                if (sscanf(temp, "%d:%d", &major, &minor) != 2)
                        return;
+
+               if (ENABLE_FEATURE_MDEV_RENAME)
+                       unlink(device_name);
+
                if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST)
                        bb_perror_msg_and_die("mknod %s", device_name);
 
                if (major == root_major && minor == root_minor)
                        symlink(device_name, "root");
 
-               if (ENABLE_FEATURE_MDEV_CONF)
+               if (ENABLE_FEATURE_MDEV_CONF) {
                        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 */
                char *s = xasprintf("MDEV=%s", device_name);
                putenv(s);