[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:
parent
bb73864724
commit
50e5de03d1
|
@ -820,7 +820,7 @@ found:
|
||||||
/* substitute placeholder */
|
/* substitute placeholder */
|
||||||
apply_format(udev, udev->name, class_dev, sysfs_device);
|
apply_format(udev, udev->name, class_dev, sysfs_device);
|
||||||
apply_format(udev, udev->symlink, class_dev, sysfs_device);
|
apply_format(udev, udev->symlink, class_dev, sysfs_device);
|
||||||
|
udev->partitions = dev->partitions;
|
||||||
done:
|
done:
|
||||||
perm = find_perm(udev->name);
|
perm = find_perm(udev->name);
|
||||||
if (perm) {
|
if (perm) {
|
||||||
|
|
39
namedev.h
39
namedev.h
|
@ -28,25 +28,29 @@
|
||||||
|
|
||||||
struct sysfs_class_device;
|
struct sysfs_class_device;
|
||||||
|
|
||||||
#define BUS_SIZE 30
|
#define BUS_SIZE 30
|
||||||
#define FILE_SIZE 50
|
#define FILE_SIZE 50
|
||||||
#define VALUE_SIZE 100
|
#define VALUE_SIZE 100
|
||||||
#define ID_SIZE 50
|
#define ID_SIZE 50
|
||||||
#define PLACE_SIZE 50
|
#define PLACE_SIZE 50
|
||||||
#define PROGRAM_SIZE 100
|
#define PROGRAM_SIZE 100
|
||||||
|
|
||||||
#define FIELD_BUS "BUS"
|
#define FIELD_BUS "BUS"
|
||||||
#define FIELD_SYSFS "SYSFS"
|
#define FIELD_SYSFS "SYSFS"
|
||||||
#define FIELD_ID "ID"
|
#define FIELD_ID "ID"
|
||||||
#define FIELD_PLACE "PLACE"
|
#define FIELD_PLACE "PLACE"
|
||||||
#define FIELD_PROGRAM "PROGRAM"
|
#define FIELD_PROGRAM "PROGRAM"
|
||||||
#define FIELD_RESULT "RESULT"
|
#define FIELD_RESULT "RESULT"
|
||||||
#define FIELD_KERNEL "KERNEL"
|
#define FIELD_KERNEL "KERNEL"
|
||||||
#define FIELD_NAME "NAME"
|
#define FIELD_NAME "NAME"
|
||||||
#define FIELD_SYMLINK "SYMLINK"
|
#define FIELD_SYMLINK "SYMLINK"
|
||||||
|
|
||||||
#define PROGRAM_MAXARG 10
|
#define ATTR_PARTITIONS "all_partitions"
|
||||||
#define MAX_SYSFS_PAIRS 5
|
#define PARTITIONS_COUNT 15
|
||||||
|
|
||||||
|
|
||||||
|
#define PROGRAM_MAXARG 10
|
||||||
|
#define MAX_SYSFS_PAIRS 5
|
||||||
|
|
||||||
struct sysfs_pair {
|
struct sysfs_pair {
|
||||||
char file[FILE_SIZE];
|
char file[FILE_SIZE];
|
||||||
|
@ -65,6 +69,7 @@ struct config_device {
|
||||||
char name[NAME_SIZE];
|
char name[NAME_SIZE];
|
||||||
char symlink[NAME_SIZE];
|
char symlink[NAME_SIZE];
|
||||||
struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
|
struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
|
||||||
|
int partitions;
|
||||||
int config_line;
|
int config_line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -91,13 +91,6 @@ static char *get_key_attribute(char *str)
|
||||||
char *pos;
|
char *pos;
|
||||||
char *attr;
|
char *attr;
|
||||||
|
|
||||||
attr = strchr(str, '_');
|
|
||||||
if (attr != NULL) {
|
|
||||||
attr++;
|
|
||||||
dbg("attribute='%s'", attr);
|
|
||||||
return attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
attr = strchr(str, '{');
|
attr = strchr(str, '{');
|
||||||
if (attr != NULL) {
|
if (attr != NULL) {
|
||||||
attr++;
|
attr++;
|
||||||
|
@ -111,6 +104,13 @@ static char *get_key_attribute(char *str)
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attr = strchr(str, '_');
|
||||||
|
if (attr != NULL) {
|
||||||
|
attr++;
|
||||||
|
dbg("attribute='%s'", attr);
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,13 @@ int namedev_init_rules(void)
|
||||||
continue;
|
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);
|
strfieldcpy(dev.name, temp3);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,7 +350,16 @@ KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
|
||||||
EOF
|
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",
|
subsys => "tty",
|
||||||
devpath => "class/tty/ttyUSB0",
|
devpath => "class/tty/ttyUSB0",
|
||||||
expected => "visor" ,
|
expected => "visor" ,
|
||||||
|
|
71
udev-add.c
71
udev-add.c
|
@ -99,11 +99,44 @@ static int create_path(char *file)
|
||||||
return 0;
|
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)
|
static int create_node(struct udevice *dev, int fake)
|
||||||
{
|
{
|
||||||
struct stat stats;
|
struct stat stats;
|
||||||
char filename[255];
|
char filename[255];
|
||||||
char linktarget[255];
|
char linktarget[255];
|
||||||
|
char partitionname[255];
|
||||||
char *linkname;
|
char *linkname;
|
||||||
char *symlinks;
|
char *symlinks;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
@ -135,23 +168,6 @@ static int create_node(struct udevice *dev, int fake)
|
||||||
if (strrchr(dev->name, '/'))
|
if (strrchr(dev->name, '/'))
|
||||||
create_path(filename);
|
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') {
|
if (dev->owner[0] != '\0') {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
unsigned long id = strtoul(dev->owner, &endptr, 10);
|
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) {
|
if (!fake)
|
||||||
dbg("chown(%s, %u, %u)", filename, uid, gid);
|
info("creating device node '%s'", filename);
|
||||||
retval = chown(filename, uid, gid);
|
make_node(filename, dev->major, dev->minor, dev->mode, uid, gid);
|
||||||
if (retval != 0)
|
|
||||||
dbg("chown(%s, %u, %u) failed with error '%s'",
|
/* create partitions if requested */
|
||||||
filename, uid, gid, strerror(errno));
|
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 */
|
/* create symlink if requested */
|
||||||
|
@ -222,8 +244,7 @@ static int create_node(struct udevice *dev, int fake)
|
||||||
strcpy(linktarget, "./");
|
strcpy(linktarget, "./");
|
||||||
strcat(linktarget, &dev->name[tail]);
|
strcat(linktarget, &dev->name[tail]);
|
||||||
|
|
||||||
/* unlink existing non-directories to ensure that our symlink
|
/* unlink existing files to ensure that our symlink is created */
|
||||||
* is created */
|
|
||||||
if (!fake && (lstat(filename, &stats) == 0)) {
|
if (!fake && (lstat(filename, &stats) == 0)) {
|
||||||
if ((stats.st_mode & S_IFMT) != S_IFDIR) {
|
if ((stats.st_mode & S_IFMT) != S_IFDIR) {
|
||||||
if (unlink(filename))
|
if (unlink(filename))
|
||||||
|
|
|
@ -66,9 +66,11 @@ static int delete_path(char *path)
|
||||||
static int delete_node(struct udevice *dev)
|
static int delete_node(struct udevice *dev)
|
||||||
{
|
{
|
||||||
char filename[255];
|
char filename[255];
|
||||||
|
char partitionname[255];
|
||||||
char *symlinks;
|
char *symlinks;
|
||||||
char *linkname;
|
char *linkname;
|
||||||
int retval;
|
int retval;
|
||||||
|
int i;
|
||||||
|
|
||||||
strncpy(filename, udev_root, sizeof(filename));
|
strncpy(filename, udev_root, sizeof(filename));
|
||||||
strncat(filename, dev->name, sizeof(filename));
|
strncat(filename, dev->name, sizeof(filename));
|
||||||
|
@ -81,11 +83,20 @@ static int delete_node(struct udevice *dev)
|
||||||
return retval;
|
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 */
|
/* remove subdirectories */
|
||||||
if (strchr(dev->name, '/'))
|
if (strchr(dev->name, '/'))
|
||||||
delete_path(filename);
|
delete_path(filename);
|
||||||
|
|
||||||
if (*dev->symlink) {
|
if (dev->symlink[0] != '\0') {
|
||||||
symlinks = dev->symlink;
|
symlinks = dev->symlink;
|
||||||
while (1) {
|
while (1) {
|
||||||
linkname = strsep(&symlinks, " ");
|
linkname = strsep(&symlinks, " ");
|
||||||
|
|
1
udev.h
1
udev.h
|
@ -46,6 +46,7 @@ struct udevice {
|
||||||
int minor;
|
int minor;
|
||||||
unsigned int mode; /* not mode_t due to conflicting definitions in different libcs */
|
unsigned int mode; /* not mode_t due to conflicting definitions in different libcs */
|
||||||
char symlink[NAME_SIZE];
|
char symlink[NAME_SIZE];
|
||||||
|
int partitions;
|
||||||
|
|
||||||
/* private data that help us in building strings */
|
/* private data that help us in building strings */
|
||||||
char bus_id[SYSFS_NAME_LEN];
|
char bus_id[SYSFS_NAME_LEN];
|
||||||
|
|
Loading…
Reference in a new issue