summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@suse.de>2005-07-16 07:46:31 +0200
committerKay Sievers <kay.sievers@suse.de>2005-07-16 07:46:31 +0200
commit594dd610252923591ed0f310695e82d3fb87e581 (patch)
tree7dc290f161526aca177dfac7934842e6a6d281c1
parentc609f627fae97bef5f163eb2eb993d3c8211f768 (diff)
allow rules to have labels and skip to next label
This will allow us to have whole blocks of rules to skip conditionally. The following section creates the node "yes": GOTO="TEST" NAME="no" NAME="no2", LABEL="NO" NAME="yes", LABEL="TEST" NAME="no3"
-rw-r--r--Makefile2
-rwxr-xr-xtest/udev-test.pl13
-rw-r--r--udev_rules.c5
-rw-r--r--udev_rules.h3
-rw-r--r--udev_rules_parse.c39
5 files changed, 60 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index a8f2851cab..b740838ace 100644
--- a/Makefile
+++ b/Makefile
@@ -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: