chiark / gitweb /
[PATCH] udev - create all partitions of blockdevice
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Tue, 17 Feb 2004 05:44:28 +0000 (21:44 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:32:28 +0000 (21:32 -0700)
Here is the first try to create all partitons of a blockdevice, since
removable media devices may need to acces the expected partition to
revalidate the media.

It uses the attribute syntax introduced with the last %s{file} patch.
I'm using this with my multi-slot-flash-card-reader:

  SYSFS{model}="USB Storage-SMC ", NAME{all_partitions}="smartmedia"
  SYSFS{model}="USB Storage-CFC ", NAME{all_partitions}="compactflash"
  SYSFS{model}="USB Storage-MSC ", NAME{all_partitions}="memorystick"
  SYSFS{model}="USB Storage-MMC ", NAME{all_partitions}="multimedia"

and I get:

  tree /udev/
  /udev/
  |-- memorystick
  |-- memorystick1
  |-- memorystick10
  |-- memorystick11
  |-- memorystick12
  |-- memorystick13
  |-- memorystick14
  |-- memorystick15
  |-- memorystick2
  |-- memorystick3
  |-- memorystick4
  |-- memorystick5
  |-- memorystick6
  |-- memorystick7
  |-- memorystick8
  |-- memorystick9
  |-- multimedia
  |-- multimedia1
  |-- multimedia10
  |-- multimedia11
  |-- multimedia12
  |-- multimedia13
  |-- multimedia14
  |-- multimedia15
  |-- multimedia2
  |-- multimedia3
  |-- multimedia4
  |-- multimedia5
  |-- multimedia6
  |-- multimedia7
  |-- multimedia8
  |-- multimedia9
  ...

If needed, we can make the number of partions to create
adjustable with the attribute?

namedev.c
namedev.h
namedev_parse.c
test/udev-test.pl
udev-add.c
udev-remove.c
udev.h

index cd38f25cb0979541ad42e119734b2fdb61abaa35..942788b2a2a83519ec785f209eaf589d84b597a4 100644 (file)
--- a/namedev.c
+++ b/namedev.c
@@ -820,7 +820,7 @@ found:
        /* substitute placeholder */
        apply_format(udev, udev->name, class_dev, sysfs_device);
        apply_format(udev, udev->symlink, class_dev, sysfs_device);
-
+       udev->partitions = dev->partitions;
 done:
        perm = find_perm(udev->name);
        if (perm) {
index e38c4f525741b0d4bdfd2616c50715f0a735d7d6..10a5dcaf0c53733300005e88cbcd5c85881f2933 100644 (file)
--- a/namedev.h
+++ b/namedev.h
 
 struct sysfs_class_device;
 
-#define BUS_SIZE       30
-#define FILE_SIZE      50
-#define VALUE_SIZE     100
-#define ID_SIZE                50
-#define PLACE_SIZE     50
-#define PROGRAM_SIZE   100
-
-#define FIELD_BUS      "BUS"
-#define FIELD_SYSFS    "SYSFS"
-#define FIELD_ID       "ID"
-#define FIELD_PLACE    "PLACE"
-#define FIELD_PROGRAM  "PROGRAM"
-#define FIELD_RESULT   "RESULT"
-#define FIELD_KERNEL   "KERNEL"
-#define FIELD_NAME     "NAME"
-#define FIELD_SYMLINK  "SYMLINK"
-
-#define PROGRAM_MAXARG 10
-#define MAX_SYSFS_PAIRS        5
+#define BUS_SIZE               30
+#define FILE_SIZE              50
+#define VALUE_SIZE             100
+#define ID_SIZE                        50
+#define PLACE_SIZE             50
+#define PROGRAM_SIZE           100
+
+#define FIELD_BUS              "BUS"
+#define FIELD_SYSFS            "SYSFS"
+#define FIELD_ID               "ID"
+#define FIELD_PLACE            "PLACE"
+#define FIELD_PROGRAM          "PROGRAM"
+#define FIELD_RESULT           "RESULT"
+#define FIELD_KERNEL           "KERNEL"
+#define FIELD_NAME             "NAME"
+#define FIELD_SYMLINK          "SYMLINK"
+
+#define ATTR_PARTITIONS                "all_partitions"
+#define PARTITIONS_COUNT       15
+
+
+#define PROGRAM_MAXARG         10
+#define MAX_SYSFS_PAIRS                5
 
 struct sysfs_pair {
        char file[FILE_SIZE];
@@ -65,6 +69,7 @@ struct config_device {
        char name[NAME_SIZE];
        char symlink[NAME_SIZE];
        struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
+       int partitions;
        int config_line;
 };
 
index 20ff60d640923458bf48a5861b402fb76cba7468..d5d2181cb68bb427ba34c84f187aff12187e0202 100644 (file)
@@ -91,13 +91,6 @@ static char *get_key_attribute(char *str)
        char *pos;
        char *attr;
 
-       attr = strchr(str, '_');
-       if (attr != NULL) {
-               attr++;
-               dbg("attribute='%s'", attr);
-               return attr;
-       }
-
        attr = strchr(str, '{');
        if (attr != NULL) {
                attr++;
@@ -111,6 +104,13 @@ static char *get_key_attribute(char *str)
                return attr;
        }
 
+       attr = strchr(str, '_');
+       if (attr != NULL) {
+               attr++;
+               dbg("attribute='%s'", attr);
+               return attr;
+       }
+
        return NULL;
 }
 
@@ -221,7 +221,13 @@ int namedev_init_rules(void)
                                continue;
                        }
 
-                       if (strcasecmp(temp2, FIELD_NAME) == 0) {
+                       if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) {
+                               attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1);
+                               if (attr != NULL)
+                                       if (strcasecmp(attr, ATTR_PARTITIONS) == 0) {
+                                               dbg_parse("creation of partition nodes requested");
+                                               dev.partitions = PARTITIONS_COUNT;
+                                       }
                                strfieldcpy(dev.name, temp3);
                                continue;
                        }
index abe622cf8afec7307bb1fabbd11db116ed7eea19..258d5c9596f6f1c183ce11b95a11c6f2c12a86f6 100644 (file)
@@ -350,7 +350,16 @@ KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
 EOF
        },
        {
-               desc     => "sysfs parent heirachy",
+               desc     => "create all possible partitions",
+               subsys   => "block",
+               devpath  => "block/sda",
+               expected => "boot_disk15" ,
+               conf     => <<EOF
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME{all_partitions}="boot_disk"
+EOF
+       },
+       {
+               desc     => "sysfs parent hierarchy",
                subsys   => "tty",
                devpath  => "class/tty/ttyUSB0",
                expected => "visor" ,
index 8867c8f5afc2ee5d6e125df73ea6a2ce4fa1a08b..3b3ebd5bbbcce4e397cc5fe1c9a8f7d016ac5daa 100644 (file)
@@ -99,11 +99,44 @@ static int create_path(char *file)
        return 0;
 }
 
+static int make_node(char *filename, int major, int minor, unsigned int mode, uid_t uid, gid_t gid)
+{
+       int retval;
+
+       retval = mknod(filename, mode, makedev(major, minor));
+       if (retval != 0) {
+               dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
+                   filename, mode, major, minor, strerror(errno));
+               return retval;
+       }
+
+       dbg("chmod(%s, %#o)", filename, mode);
+       retval = chmod(filename, mode);
+       if (retval != 0) {
+               dbg("chmod(%s, %#o) failed with error '%s'",
+                   filename, mode, strerror(errno));
+               return retval;
+       }
+
+       if (uid != 0 || gid != 0) {
+               dbg("chown(%s, %u, %u)", filename, uid, gid);
+               retval = chown(filename, uid, gid);
+               if (retval != 0) {
+                       dbg("chown(%s, %u, %u) failed with error '%s'",
+                           filename, uid, gid, strerror(errno));
+                       return retval;
+               }
+       }
+
+       return 0;
+}
+
 static int create_node(struct udevice *dev, int fake)
 {
        struct stat stats;
        char filename[255];
        char linktarget[255];
+       char partitionname[255];
        char *linkname;
        char *symlinks;
        int retval = 0;
@@ -135,23 +168,6 @@ static int create_node(struct udevice *dev, int fake)
        if (strrchr(dev->name, '/'))
                create_path(filename);
 
-       info("creating device node '%s'", filename);
-       dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor);
-       if (!fake) {
-               retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor));
-               if (retval != 0)
-                       dbg("mknod(%s, %#o, %u, %u) failed with error '%s'",
-                           filename, dev->mode, dev->major, dev->minor, strerror(errno));
-       }
-
-       dbg("chmod(%s, %#o)", filename, dev->mode);
-       if (!fake) {
-               retval = chmod(filename, dev->mode);
-               if (retval != 0)
-                       dbg("chmod(%s, %#o) failed with error '%s'",
-                           filename, dev->mode, strerror(errno));
-       }
-
        if (dev->owner[0] != '\0') {
                char *endptr;
                unsigned long id = strtoul(dev->owner, &endptr, 10);
@@ -180,12 +196,18 @@ static int create_node(struct udevice *dev, int fake)
                }
        }
 
-       if (uid != 0 || gid != 0) {
-               dbg("chown(%s, %u, %u)", filename, uid, gid);
-               retval = chown(filename, uid, gid);
-               if (retval != 0)
-                       dbg("chown(%s, %u, %u) failed with error '%s'",
-                           filename, uid, gid, strerror(errno));
+       if (!fake)
+               info("creating device node '%s'", filename);
+               make_node(filename, dev->major, dev->minor, dev->mode, uid, gid);
+
+       /* create partitions if requested */
+       if (dev->partitions > 0) {
+               info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions);
+               for (i = 1; i <= dev->partitions; i++) {
+                       sprintf(partitionname, "%s%i", filename, i);
+                       make_node(partitionname, dev->major, dev->minor + i,
+                                   dev->mode, uid, gid);
+               }
        }
 
        /* create symlink if requested */
@@ -222,8 +244,7 @@ static int create_node(struct udevice *dev, int fake)
                                strcpy(linktarget, "./");
                        strcat(linktarget, &dev->name[tail]);
 
-                       /* unlink existing non-directories to ensure that our symlink
-                        * is created */
+                       /* unlink existing files to ensure that our symlink is created */
                        if (!fake && (lstat(filename, &stats) == 0)) {
                                if ((stats.st_mode & S_IFMT) != S_IFDIR) {
                                        if (unlink(filename))
index c21938fae77497843abe789c3743b87a5103c89c..c20c651dc53687056d701c0a8714a7f5d39f3b9b 100644 (file)
@@ -66,9 +66,11 @@ static int delete_path(char *path)
 static int delete_node(struct udevice *dev)
 {
        char filename[255];
+       char partitionname[255];
        char *symlinks;
        char *linkname;
        int retval;
+       int i;
 
        strncpy(filename, udev_root, sizeof(filename));
        strncat(filename, dev->name, sizeof(filename));
@@ -81,11 +83,20 @@ static int delete_node(struct udevice *dev)
                return retval;
        }
 
+       /* remove partition nodes */
+       if (dev->partitions > 0) {
+               info("removing partitions '%s[1-%i]'", filename, dev->partitions);
+               for (i = 1; i <= dev->partitions; i++) {
+                       sprintf(partitionname, "%s%i", filename, i);
+                       unlink(partitionname);
+               }
+       }
+
        /* remove subdirectories */
        if (strchr(dev->name, '/'))
                delete_path(filename);
 
-       if (*dev->symlink) {
+       if (dev->symlink[0] != '\0') {
                symlinks = dev->symlink;
                while (1) {
                        linkname = strsep(&symlinks, " ");
diff --git a/udev.h b/udev.h
index e615b4c8bb9e6a88b78d1e1ac72686ae349e3b73..e8f93ad5ada2c49fb8076742a50bf14bddaad906 100644 (file)
--- a/udev.h
+++ b/udev.h
@@ -46,6 +46,7 @@ struct udevice {
        int minor;
        unsigned int mode;      /* not mode_t due to conflicting definitions in different libcs */
        char symlink[NAME_SIZE];
+       int partitions;
 
        /* private data that help us in building strings */
        char bus_id[SYSFS_NAME_LEN];