chiark / gitweb /
allow rules to have labels and skip to next label
authorKay Sievers <kay.sievers@suse.de>
Sat, 16 Jul 2005 05:46:31 +0000 (07:46 +0200)
committerKay Sievers <kay.sievers@suse.de>
Sat, 16 Jul 2005 05:46:31 +0000 (07:46 +0200)
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"

Makefile
test/udev-test.pl
udev_rules.c
udev_rules.h
udev_rules_parse.c

index a8f2851cabd2eb68d8c26eaef7be69de13f09590..b740838ace3009a07bcb38202f1e99ca3c34ba9b 100644 (file)
--- 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 ; \
index 1bb60bb76e522f57929bf0b818885afbdbb48cb4..94cffeab07d9a2bb9dd77887812dcd5bae5afd55 100755 (executable)
@@ -1492,6 +1492,19 @@ EOF
                option          => "clean",
                rules           => <<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
        },
 );
index 4bf05cd43781d0c763372de8b0241627cbdfbf4c..939febe8f69e20986a5b4629f69cd5f5caddbccc 100644 (file)
@@ -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));
+                       }
                }
        }
 
index 3f37d4b0b4d3345089dda3ebe512d9015d5daa3e..d22d31f7e121edae421e6ddc45a6561f1ef26d3d 100644 (file)
@@ -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);
index 7c3c2e7fc252698aed9bb4be6c3d0c551a588b14..0259268c8faa36b0ce8e7327c844798d4d7c12e0 100644 (file)
@@ -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: