diff options
-rwxr-xr-x | test/udev-test.pl | 12 | ||||
-rw-r--r-- | udev_rules.c | 32 | ||||
-rw-r--r-- | udev_rules.h | 1 | ||||
-rw-r--r-- | udev_rules_parse.c | 6 |
4 files changed, 32 insertions, 19 deletions
diff --git a/test/udev-test.pl b/test/udev-test.pl index 53499d8871..a2043080e9 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -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", diff --git a/udev_rules.c b/udev_rules.c index 400ebad9e3..daf3d7fff7 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -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"); diff --git a/udev_rules.h b/udev_rules.h index 556f55087d..0ad4ec3271 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -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; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 124410a340..81c24b9cc1 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -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; } |