[PATCH] add ENV{} key to match agains environment variables
This commit is contained in:
parent
79f651f4bd
commit
3e5958dee5
|
@ -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
|
||||
},
|
||||
);
|
||||
|
|
10
udev.8.in
10
udev.8.in
|
@ -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
|
||||
|
|
71
udev_rules.c
71
udev_rules.c
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue