chiark / gitweb /
allow SYMLINK== match
authorKay Sievers <kay.sievers@vrfy.org>
Mon, 16 Jul 2007 11:29:28 +0000 (13:29 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Mon, 16 Jul 2007 11:29:28 +0000 (13:29 +0200)
test/udev-test.pl
udev_rules.c
udev_rules.h
udev_rules_parse.c

index 53499d8..a204308 100755 (executable)
@@ -1519,18 +1519,6 @@ KERNEL=="sda1", NAME=="node*", SYMLINK+="link2"
 EOF
        },
        {
-               desc            => "NAME compare test 2",
-               subsys          => "block",
-               devpath         => "/block/sda/sda1",
-               exp_name        => "link2",
-               exp_target      => "sda1",
-               not_exp_name    => "link",
-               rules           => <<EOF
-KERNEL=="sda1", NAME=="?*", SYMLINK+="link"
-KERNEL=="sda1", NAME!="?*", SYMLINK+="link2"
-EOF
-       },
-       {
                desc            => "invalid key operation",
                subsys          => "block",
                devpath         => "/block/sda/sda1",
index 400ebad..daf3d7f 100644 (file)
@@ -940,10 +940,25 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
        if (match_key("DRIVER", rule, &rule->driver, udev->dev->driver))
                goto nomatch;
 
-       /* match NAME against a value assigned by an earlier rule */
        if (match_key("NAME", rule, &rule->name, udev->name))
                goto nomatch;
 
+       /* match against current list of symlinks */
+       if (rule->symlink_match.operation == KEY_OP_MATCH ||
+           rule->symlink_match.operation == KEY_OP_NOMATCH) {
+               struct name_entry *name_loop;
+               int match = 0;
+
+               list_for_each_entry(name_loop, &udev->symlink_list, node) {
+                       if (match_key("SYMLINK", rule, &rule->symlink_match, name_loop->name) == 0) {
+                               match = 1;
+                               break;
+                       }
+               }
+               if (!match)
+                       goto nomatch;
+       }
+
        for (i = 0; i < rule->env.count; i++) {
                struct key_pair *pair = &rule->env.keys[i];
 
@@ -1250,6 +1265,9 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
        dbg("udev->dev->devpath='%s'", udev->dev->devpath);
        dbg("udev->dev->kernel='%s'", udev->dev->kernel);
 
+       /* use kernel name as default node name */
+       strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name));
+
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
        while (1) {
@@ -1311,14 +1329,18 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
                        }
 
                        /* collect symlinks */
-                       if (!udev->symlink_final && rule->symlink.operation != KEY_OP_UNSET) {
+                       if (!udev->symlink_final &&
+                           (rule->symlink.operation == KEY_OP_ASSIGN ||
+                            rule->symlink.operation == KEY_OP_ASSIGN_FINAL ||
+                            rule->symlink.operation == KEY_OP_ADD)) {
                                char temp[PATH_SIZE];
                                char *pos, *next;
                                int count;
 
                                if (rule->symlink.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->symlink_final = 1;
-                               if (rule->symlink.operation == KEY_OP_ASSIGN || rule->symlink.operation == KEY_OP_ASSIGN_FINAL) {
+                               if (rule->symlink.operation == KEY_OP_ASSIGN ||
+                                   rule->symlink.operation == KEY_OP_ASSIGN_FINAL) {
                                        info("reset symlink list");
                                        name_list_cleanup(&udev->symlink_list);
                                }
@@ -1400,10 +1422,8 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
                }
        }
 
-       if (!name_set) {
-               strlcpy(udev->name, udev->dev->kernel, sizeof(udev->name));
+       if (!name_set)
                info("no node name set, will use kernel name '%s'", udev->name);
-       }
 
        if (udev->tmp_node[0] != '\0') {
                dbg("removing temporary device node");
index 556f550..0ad4ec3 100644 (file)
@@ -90,6 +90,7 @@ struct udev_rule {
 
        struct key name;
        struct key symlink;
+       struct key symlink_match;
        struct key owner;
        struct key group;
        mode_t mode;
index 124410a..81c24b9 100644 (file)
@@ -525,7 +525,11 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                }
 
                if (strcasecmp(key, "SYMLINK") == 0) {
-                       add_rule_key(rule, &rule->symlink, operation, value);
+                       if (operation == KEY_OP_MATCH ||
+                           operation == KEY_OP_NOMATCH)
+                               add_rule_key(rule, &rule->symlink_match, operation, value);
+                       else
+                               add_rule_key(rule, &rule->symlink, operation, value);
                        valid = 1;
                        continue;
                }