mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
[PATCH] add ability to have up to 5 SYSFS_ file/value pairs for the LABEL rule.
This commit is contained in:
parent
f4f3939a6c
commit
a8b01705c6
91
namedev.c
91
namedev.c
@ -102,19 +102,6 @@ static int strcmp_pattern(const char *p, const char *s)
|
||||
if (strlen(b->var)) \
|
||||
strcpy(a->var, b->var);
|
||||
|
||||
int add_config_dev(struct config_device *new_dev)
|
||||
{
|
||||
struct config_device *tmp_dev;
|
||||
|
||||
tmp_dev = malloc(sizeof(*tmp_dev));
|
||||
if (tmp_dev == NULL)
|
||||
return -ENOMEM;
|
||||
memcpy(tmp_dev, new_dev, sizeof(*tmp_dev));
|
||||
list_add_tail(&tmp_dev->node, &config_device_list);
|
||||
//dump_config_dev(tmp_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_perm_dev(struct perm_device *new_dev)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
@ -432,12 +419,50 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
|
||||
static int match_pair(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
|
||||
{
|
||||
struct sysfs_attribute *tmpattr = NULL;
|
||||
char *c;
|
||||
|
||||
if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0'))
|
||||
return -ENODEV;
|
||||
|
||||
dbg("look for device attribute '%s'", pair->file);
|
||||
/* try to find the attribute in the class device directory */
|
||||
tmpattr = sysfs_get_classdev_attr(class_dev, pair->file);
|
||||
if (tmpattr)
|
||||
goto label_found;
|
||||
|
||||
/* look in the class device directory if present */
|
||||
if (sysfs_device) {
|
||||
tmpattr = sysfs_get_device_attr(sysfs_device, pair->file);
|
||||
if (tmpattr)
|
||||
goto label_found;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
|
||||
label_found:
|
||||
c = tmpattr->value + strlen(tmpattr->value)-1;
|
||||
if (*c == '\n')
|
||||
*c = 0x00;
|
||||
dbg("compare attribute '%s' value '%s' with '%s'",
|
||||
pair->file, tmpattr->value, pair->value);
|
||||
if (strcmp_pattern(pair->value, tmpattr->value) != 0)
|
||||
return -ENODEV;
|
||||
|
||||
dbg("found matching attribute '%s' with value '%s'",
|
||||
pair->file, pair->value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
|
||||
{
|
||||
struct sysfs_pair *pair;
|
||||
struct config_device *dev;
|
||||
struct list_head *tmp;
|
||||
char *c;
|
||||
int i;
|
||||
int match;
|
||||
|
||||
list_for_each(tmp, &config_device_list) {
|
||||
dev = list_entry(tmp, struct config_device, node);
|
||||
@ -450,34 +475,24 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev,
|
||||
continue;
|
||||
}
|
||||
|
||||
dbg("look for device attribute '%s'", dev->sysfs_file);
|
||||
/* try to find the attribute in the class device directory */
|
||||
tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file);
|
||||
if (tmpattr)
|
||||
goto label_found;
|
||||
|
||||
/* look in the class device directory if present */
|
||||
if (sysfs_device) {
|
||||
tmpattr = sysfs_get_device_attr(sysfs_device, dev->sysfs_file);
|
||||
if (tmpattr)
|
||||
goto label_found;
|
||||
match = 1;
|
||||
for (i = 0; i < MAX_SYSFS_PAIRS; ++i) {
|
||||
pair = &dev->sysfs_pair[i];
|
||||
if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
|
||||
break;
|
||||
if (match_pair(class_dev, sysfs_device, pair) != 0) {
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
label_found:
|
||||
c = tmpattr->value + strlen(tmpattr->value)-1;
|
||||
if (*c == '\n')
|
||||
*c = 0x00;
|
||||
dbg("compare attribute '%s' value '%s' with '%s'",
|
||||
dev->sysfs_file, tmpattr->value, dev->sysfs_value);
|
||||
if (strcmp_pattern(dev->sysfs_value, tmpattr->value) != 0)
|
||||
if (match == 0)
|
||||
continue;
|
||||
|
||||
/* found match */
|
||||
strfieldcpy(udev->name, dev->name);
|
||||
strfieldcpy(udev->symlink, dev->symlink);
|
||||
dbg("found matching attribute '%s', '%s' becomes '%s' ",
|
||||
dev->sysfs_file, class_dev->name, udev->name);
|
||||
dbg("found matching attribute, '%s' becomes '%s' ",
|
||||
class_dev->name, udev->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
10
namedev.h
10
namedev.h
@ -60,20 +60,25 @@ enum config_type {
|
||||
#define FIELD_SYMLINK "SYMLINK"
|
||||
|
||||
#define CALLOUT_MAXARG 8
|
||||
#define MAX_SYSFS_PAIRS 5
|
||||
|
||||
struct sysfs_pair {
|
||||
char file[FILE_SIZE];
|
||||
char value[VALUE_SIZE];
|
||||
};
|
||||
|
||||
struct config_device {
|
||||
struct list_head node;
|
||||
|
||||
enum config_type type;
|
||||
char bus[BUS_SIZE];
|
||||
char sysfs_file[FILE_SIZE];
|
||||
char sysfs_value[VALUE_SIZE];
|
||||
char id[ID_SIZE];
|
||||
char place[PLACE_SIZE];
|
||||
char kernel_name[NAME_SIZE];
|
||||
char exec_program[FILE_SIZE];
|
||||
char name[NAME_SIZE];
|
||||
char symlink[NAME_SIZE];
|
||||
struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
|
||||
};
|
||||
|
||||
struct perm_device {
|
||||
@ -93,7 +98,6 @@ extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udev
|
||||
extern int namedev_init_permissions(void);
|
||||
extern int namedev_init_rules(void);
|
||||
|
||||
extern int add_config_dev(struct config_device *new_dev);
|
||||
extern int add_perm_dev(struct perm_device *new_dev);
|
||||
extern void dump_config_dev(struct config_device *dev);
|
||||
extern void dump_config_dev_list(void);
|
||||
|
@ -36,6 +36,19 @@
|
||||
#include "udev.h"
|
||||
#include "namedev.h"
|
||||
|
||||
static int add_config_dev(struct config_device *new_dev)
|
||||
{
|
||||
struct config_device *tmp_dev;
|
||||
|
||||
tmp_dev = malloc(sizeof(*tmp_dev));
|
||||
if (tmp_dev == NULL)
|
||||
return -ENOMEM;
|
||||
memcpy(tmp_dev, new_dev, sizeof(*tmp_dev));
|
||||
list_add_tail(&tmp_dev->node, &config_device_list);
|
||||
//dump_config_dev(tmp_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_pair(char **orig_string, char **left, char **right)
|
||||
{
|
||||
char *temp;
|
||||
@ -78,8 +91,8 @@ void dump_config_dev(struct config_device *dev)
|
||||
dbg_parse("KERNEL name='%s'", dev->name);
|
||||
break;
|
||||
case LABEL:
|
||||
dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s'",
|
||||
dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value);
|
||||
dbg_parse("LABEL name='%s', bus='%s', sysfs_file[0]='%s', sysfs_value[0]='%s'",
|
||||
dev->name, dev->bus, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value);
|
||||
break;
|
||||
case NUMBER:
|
||||
dbg_parse("NUMBER name='%s', bus='%s', id='%s'",
|
||||
@ -225,9 +238,23 @@ keys:
|
||||
}
|
||||
|
||||
if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) {
|
||||
/* remove prepended 'SYSFS_' */
|
||||
strfieldcpy(dev.sysfs_file, temp2 + sizeof(FIELD_SYSFS)-1);
|
||||
strfieldcpy(dev.sysfs_value, temp3);
|
||||
struct sysfs_pair *pair = &dev.sysfs_pair[0];
|
||||
int sysfs_pair_num = 0;
|
||||
|
||||
/* find first unused pair */
|
||||
while (pair->file[0] != '\0') {
|
||||
++sysfs_pair_num;
|
||||
if (sysfs_pair_num >= MAX_SYSFS_PAIRS) {
|
||||
pair = NULL;
|
||||
break;
|
||||
}
|
||||
++pair;
|
||||
}
|
||||
if (pair) {
|
||||
/* remove prepended 'SYSFS_' */
|
||||
strfieldcpy(pair->file, temp2 + sizeof(FIELD_SYSFS)-1);
|
||||
strfieldcpy(pair->value, temp3);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -258,13 +285,13 @@ keys:
|
||||
switch (dev.type) {
|
||||
case LABEL:
|
||||
dbg_parse(TYPE_LABEL " name='%s', bus='%s', "
|
||||
"sysfs_file='%s', sysfs_value='%s', symlink='%s'",
|
||||
dev.name, dev.bus, dev.sysfs_file,
|
||||
dev.sysfs_value, dev.symlink);
|
||||
"sysfs_file[0]='%s', sysfs_value[0]='%s', symlink='%s'",
|
||||
dev.name, dev.bus, dev.sysfs_pair[0].file,
|
||||
dev.sysfs_pair[0].value, dev.symlink);
|
||||
if ((*dev.name == '\0') ||
|
||||
(*dev.bus == '\0') ||
|
||||
(*dev.sysfs_file == '\0') ||
|
||||
(*dev.sysfs_value == '\0'))
|
||||
(*dev.sysfs_pair[0].file == '\0') ||
|
||||
(*dev.sysfs_pair[0].value == '\0'))
|
||||
goto error;
|
||||
break;
|
||||
case NUMBER:
|
||||
|
Loading…
Reference in New Issue
Block a user