chiark / gitweb /
[PATCH] add ENV{} key to match agains environment variables
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Sun, 13 Mar 2005 10:40:32 +0000 (11:40 +0100)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 06:53:18 +0000 (23:53 -0700)
test/udev-test.pl
udev.8.in
udev_rules.c
udev_rules.h
udev_rules_parse.c

index ebceccecb23608fafc2eeeeb8aeaec3ff6c26da1..2ece4317351a747431bdae0bed6f1975bc7e6ec5 100644 (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
        },
 );
index dbba2979728f3f57ed0db18f030d0bc3ef549a7e..84d8a313dafb1bac5166466469fb5ec00868566c 100644 (file)
--- a/udev.8.in
+++ b/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
index d1192614aa25488928f64ed94848673493a65383..551c06131b43843d1ee4bf69f69c9736d169e500 100644 (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");
                }
index 94a5d9d5fd11c3e9143229d8c30714799f678d71..423a6f641ecb1f24632c4c5eeeecc595caf0e44a 100644 (file)
 #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];
index c4c684d05927a8d4aa9e880a968bdb57f12705ca..face496ab33b68880635fa099d417035e053a5a4 100644 (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;
                        }