[PATCH] udev - create all partitions of blockdevice

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?
This commit is contained in:
kay.sievers@vrfy.org 2004-02-16 21:44:28 -08:00 committed by Greg KH
parent bb73864724
commit 50e5de03d1
7 changed files with 106 additions and 53 deletions

View File

@ -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) {

View File

@ -28,25 +28,29 @@
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 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 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 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;
};

View 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;
}

View 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" ,

View 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))

View 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, " ");

1
udev.h
View File

@ -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];