diff options
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | test/udev-test.pl | 13 | ||||
-rw-r--r-- | udev_rules.c | 5 | ||||
-rw-r--r-- | udev_rules.h | 3 | ||||
-rw-r--r-- | udev_rules_parse.c | 39 |
5 files changed, 60 insertions, 2 deletions
@@ -377,8 +377,8 @@ install: install-config install-man all $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) ifndef DESTDIR - killall $(DAEMON) - - $(sbindir)/$(DAEMON) --daemon - rm -rf $(udevdb) + - $(sbindir)/$(DAEMON) --daemon endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff --git a/test/udev-test.pl b/test/udev-test.pl index 1bb60bb76e..94cffeab07 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1494,6 +1494,19 @@ EOF KERNEL=="sda1", IMPORT{parent}="PARENT*", NAME="parentenv-\$env{PARENT_KEY}\$env{WRONG_PARENT_KEY}" EOF }, + { + desc => "GOTO test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "right", + rules => <<EOF +KERNEL=="sda1", GOTO="TEST" +KERNEL=="sda1", NAME="wrong" +KERNEL=="sda1", NAME="", LABEL="NO" +KERNEL=="sda1", NAME="right", LABEL="TEST" +KERNEL=="sda1", NAME="wrong2" +EOF + }, ); # set env diff --git a/udev_rules.c b/udev_rules.c index 4bf05cd437..939febe8f6 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -1069,6 +1069,11 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s dbg("last rule to be applied"); break; } + + if (rule->goto_label.operation != KEY_OP_UNSET) { + dbg("moving forward to label '%s'", key_val(rule, &rule->goto_label)); + udev_rules_iter_label(rules, key_val(rule, &rule->goto_label)); + } } } diff --git a/udev_rules.h b/udev_rules.h index 3f37d4b0b4..d22d31f7e1 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -62,6 +62,8 @@ enum import_type { }; struct udev_rule { + struct key label; + struct key goto_label; struct key kernel_name; struct key subsystem; struct key action; @@ -108,6 +110,7 @@ extern void udev_rules_close(struct udev_rules *rules); extern void udev_rules_iter_init(struct udev_rules *rules); extern struct udev_rule *udev_rules_iter_next(struct udev_rules *rules); +extern struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const char *label); extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct sysfs_class_device *class_dev); extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device); diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 7c3c2e7fc2..0259268c8f 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -52,8 +52,10 @@ struct udev_rule *udev_rules_iter_next(struct udev_rules *rules) return NULL; dbg("current=%zi", rules->current); - if (rules->current >= rules->bufsize) + if (rules->current >= rules->bufsize) { + dbg("no more rules"); return NULL; + } /* get next rule */ rule = (struct udev_rule *) (rules->buf + rules->current); @@ -62,6 +64,28 @@ struct udev_rule *udev_rules_iter_next(struct udev_rules *rules) return rule; } +struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const char *label) +{ + static struct udev_rule *rule; + +next: + dbg("current=%zi", rules->current); + if (rules->current >= rules->bufsize) { + dbg("no more rules"); + return NULL; + } + rule = (struct udev_rule *) (rules->buf + rules->current); + + if (strcmp(&rule->buf[rule->label.val_off], label) != 0) { + dbg("moving forward, looking for label '%s'", label); + rules->current += sizeof(struct udev_rule) + rule->bufsize; + goto next; + } + + dbg("found label '%s'", label); + return rule; +} + static int get_key(char **line, char **key, enum key_operation *operation, char **value) { char *linepos; @@ -237,6 +261,18 @@ static int add_to_rules(struct udev_rules *rules, char *line) if (retval) break; + if (strcasecmp(key, "LABEL") == 0) { + add_rule_key(rule, &rule->label, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "GOTO") == 0) { + add_rule_key(rule, &rule->goto_label, operation, value); + valid = 1; + continue; + } + if (strcasecmp(key, "KERNEL") == 0) { add_rule_key(rule, &rule->kernel_name, operation, value); valid = 1; @@ -475,6 +511,7 @@ static int add_to_rules(struct udev_rules *rules, char *line) err("realloc failed"); goto exit; } + dbg("adding rule to offset %zi", rules->bufsize); memcpy(rules->buf + rules->bufsize, rule, rule_size); rules->bufsize += rule_size; exit: |