[PATCH] add ability to have up to 5 SYSFS_ file/value pairs for the LABEL rule.

This commit is contained in:
greg@kroah.com 2003-12-22 22:31:35 -08:00 committed by Greg KH
parent f4f3939a6c
commit a8b01705c6
3 changed files with 97 additions and 51 deletions

View File

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

View File

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

View File

@ -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: