[PATCH] add ENV{} key to match agains environment variables

This commit is contained in:
kay.sievers@vrfy.org 2005-03-13 11:40:32 +01:00 committed by Greg KH
parent 79f651f4bd
commit 3e5958dee5
5 changed files with 100 additions and 43 deletions

View file

@ -256,15 +256,6 @@ EOF
exp_name => "M8-m3-n3-b0:0-sIBM" ,
conf => <<EOF
BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}"
EOF
},
{
desc => "old style SYSFS_ attribute",
subsys => "block",
devpath => "/block/sda",
exp_name => "good" ,
conf => <<EOF
BUS=="scsi", SYSFS_vendor=="IBM-ESXS", NAME="good"
EOF
},
{
@ -1169,6 +1160,29 @@ EOF
conf => <<EOF
KERNEL == "sda1" , NAME = "true"
BUS=="scsi", KERNEL=="sda1", NAME="wrong"
EOF
},
{
desc => "ENV{} test",
subsys => "block",
devpath => "/block/sda/sda1",
exp_name => "true",
conf => <<EOF
BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="go", NAME="wrong"
BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="yes", NAME="true"
BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="bad", NAME="bad"
EOF
},
{
desc => "ENV{} test",
subsys => "block",
devpath => "/block/sda/sda1",
exp_name => "true",
conf => <<EOF
BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="go", NAME="wrong"
BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sdax1", NAME="no"
BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sda1", NAME="true"
BUS=="scsi", KERNEL=="sda1", ENV{UDEV_TEST}=="bad", NAME="bad"
EOF
},
);

View file

@ -115,13 +115,17 @@ Match the kernel driver name.
Match the device number on the bus, like PCI bus id.
.TP
.BI SYSFS{ filename }
Match sysfs device attribute like label, vendor, USB serial number, SCSI UUID
or file system label. Up to 5 different sysfs files can be checked, with
all of the values being required to match the rule.
Match sysfs device attribute like vendor and product id's, USB serial number
or the SCSI disk model number. Up to 5 different sysfs files can be checked,
with all of the values being required to match the rule.
.br
Trailing whitespace characters in the sysfs attribute value are ignored, if
the key doesn't have any trailing whitespace characters by itself.
.TP
.BI ENV{ variable }
Match an environment variable. Up to 5 different environment variables can be
checked, with all of the values being required to match the rule.
.TP
.B PROGRAM
Call external program. This key is valid if the program returns successful.
The environment variables of

View file

@ -498,30 +498,6 @@ static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct
return 0;
}
static int match_sysfs_pairs(struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
{
int i;
for (i = 0; i < rule->sysfs_pair_count; i++) {
struct key_pair *pair;
pair = &rule->sysfs_pair[i];
if ((pair->name[0] == '\0') || (pair->value[0] == '\0'))
break;
if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
dbg("sysfs pair #%u does not match", i);
if (pair->operation != KEY_OP_NOMATCH)
return -1;
} else {
dbg("sysfs pair #%u matches", i);
if (pair->operation == KEY_OP_NOMATCH)
return -1;
}
}
return 0;
}
static int match_id(struct udev_rule *rule, struct sysfs_device *sysfs_device)
{
char path[PATH_SIZE];
@ -570,6 +546,33 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
dbg(KEY_SUBSYSTEM " key is true");
}
if (rule->env_pair_count) {
int i;
dbg("check for " KEY_ENV " pairs");
for (i = 0; i < rule->env_pair_count; i++) {
struct key_pair *pair;
const char *value;
pair = &rule->env_pair[i];
value = getenv(pair->name);
if (!value) {
dbg(KEY_ENV "{'%s'} is not found", pair->name);
goto exit;
}
if (strcmp_pattern(pair->value, value) != 0) {
dbg(KEY_ENV "{'%s'} is not matching", pair->name);
if (pair->operation != KEY_OP_NOMATCH)
goto exit;
} else {
dbg(KEY_ENV "{'%s'} matches", pair->name);
if (pair->operation == KEY_OP_NOMATCH)
goto exit;
}
}
dbg(KEY_ENV " key is true");
}
/* walk up the chain of physical devices and find a match */
while (1) {
/* check for matching driver */
@ -632,11 +635,23 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
}
/* check for matching sysfs pairs */
if (rule->sysfs_pair[0].name[0] != '\0') {
if (rule->sysfs_pair_count) {
int i;
dbg("check " KEY_SYSFS " pairs");
if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) {
dbg(KEY_SYSFS " is not matching");
goto try_parent;
for (i = 0; i < rule->sysfs_pair_count; i++) {
struct key_pair *pair;
pair = &rule->sysfs_pair[i];
if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
dbg(KEY_SYSFS "{'%s'} is not matching", pair->name);
if (pair->operation != KEY_OP_NOMATCH)
goto try_parent;
} else {
dbg(KEY_SYSFS "{'%s'} matches", pair->name);
if (pair->operation == KEY_OP_NOMATCH)
goto try_parent;
}
}
dbg(KEY_SYSFS " keys are true");
}

View file

@ -31,11 +31,12 @@
#define KEY_KERNEL "KERNEL"
#define KEY_SUBSYSTEM "SUBSYSTEM"
#define KEY_BUS "BUS"
#define KEY_SYSFS "SYSFS"
#define KEY_ID "ID"
#define KEY_PROGRAM "PROGRAM"
#define KEY_RESULT "RESULT"
#define KEY_DRIVER "DRIVER"
#define KEY_SYSFS "SYSFS"
#define KEY_ENV "ENV"
#define KEY_NAME "NAME"
#define KEY_SYMLINK "SYMLINK"
#define KEY_OWNER "OWNER"
@ -49,6 +50,7 @@
#define OPTION_PARTITIONS "all_partitions"
#define KEY_SYSFS_PAIRS_MAX 5
#define KEY_ENV_PAIRS_MAX 5
#define RULEFILE_SUFFIX ".rules"
@ -85,6 +87,8 @@ struct udev_rule {
enum key_operation result_operation;
struct key_pair sysfs_pair[KEY_SYSFS_PAIRS_MAX];
int sysfs_pair_count;
struct key_pair env_pair[KEY_ENV_PAIRS_MAX];
int env_pair_count;
char name[PATH_SIZE];
char symlink[PATH_SIZE];

View file

@ -278,16 +278,36 @@ static int rules_parse(struct udevice *udev, const char *filename)
goto error;
}
pair = &rule.sysfs_pair[rule.sysfs_pair_count];
rule.sysfs_pair_count++;
attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1);
if (attr == NULL) {
dbg("error parsing " KEY_SYSFS " attribute");
goto error;
}
strlcpy(pair->name, attr, sizeof(pair->name));
strlcpy(pair->value, value, sizeof(pair->value));
pair->operation = operation;
rule.sysfs_pair_count++;
valid = 1;
continue;
}
if (strncasecmp(key, KEY_ENV, sizeof(KEY_ENV)-1) == 0) {
struct key_pair *pair;
if (rule.env_pair_count >= KEY_ENV_PAIRS_MAX) {
dbg("skip rule, to many " KEY_ENV " keys in a single rule");
goto error;
}
pair = &rule.env_pair[rule.env_pair_count];
attr = get_key_attribute(key + sizeof(KEY_ENV)-1);
if (attr == NULL) {
dbg("error parsing " KEY_ENV " attribute");
continue;
}
strlcpy(pair->name, attr, sizeof(pair->name));
strlcpy(pair->value, value, sizeof(pair->value));
pair->operation = operation;
rule.env_pair_count++;
valid = 1;
continue;
}