mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
[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 */
|
||||
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) {
|
||||
|
39
namedev.h
39
namedev.h
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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" ,
|
||||
|
71
udev-add.c
71
udev-add.c
@ -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))
|
||||
|
@ -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, " ");
|
||||
|
Loading…
Reference in New Issue
Block a user