rules: implement TAGS== match
authorKay Sievers <kay.sievers@vrfy.org>
Wed, 25 May 2011 19:08:52 +0000 (21:08 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Wed, 25 May 2011 19:08:52 +0000 (21:08 +0200)
NEWS
TODO
udev/udev-rules.c
udev/udev.xml

diff --git a/NEWS b/NEWS
index 0dc85ec..c9ac618 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+udev 171
+========
+!!! revert: "systemd: trigger - run after udev.service (for now)"
+
+The systemd service files require systemd version 28. The systemd
+socket activation make it possible now to start 'udevd' and 'udevadm
+trigger' in parallel.
+
 udev 170
 ========
 Fix bug in control message handling, which can lead to a failing
diff --git a/TODO b/TODO
index 43e2b98..ab7a5e8 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,8 +1,3 @@
- - add TAGS=="foo" match
-
- - revert: "systemd: trigger - run after udev.service (for now)"
-   after systemd has a new release we can depend on
-
  - delete mobile-action-modeswitch
    (moved to usb_modeswitch)
 
index c24da0c..a77e1e2 100644 (file)
@@ -136,6 +136,7 @@ enum token_type {
        TK_M_SUBSYSTEMS,                /* val */
        TK_M_DRIVERS,                   /* val */
        TK_M_ATTRS,                     /* val, attr */
+       TK_M_TAGS,                      /* val */
        TK_M_PARENTS_MAX,
 
        TK_M_TEST,                      /* val, mode_t */
@@ -271,6 +272,7 @@ static const char *token_str(enum token_type type)
                [TK_M_SUBSYSTEMS] =             "M SUBSYSTEMS",
                [TK_M_DRIVERS] =                "M DRIVERS",
                [TK_M_ATTRS] =                  "M ATTRS",
+               [TK_M_TAGS] =                   "M TAGS",
                [TK_M_PARENTS_MAX] =            "M PARENTS_MAX",
 
                [TK_M_TEST] =                   "M TEST",
@@ -342,6 +344,7 @@ static void dump_token(struct udev_rules *rules, struct token *token)
        case TK_M_KERNELS:
        case TK_M_SUBSYSTEMS:
        case TK_M_DRIVERS:
+       case TK_M_TAGS:
        case TK_M_PROGRAM:
        case TK_M_IMPORT_FILE:
        case TK_M_IMPORT_PROG:
@@ -1013,6 +1016,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
        case TK_M_KERNELS:
        case TK_M_SUBSYSTEMS:
        case TK_M_DRIVERS:
+       case TK_M_TAGS:
        case TK_M_PROGRAM:
        case TK_M_IMPORT_FILE:
        case TK_M_IMPORT_PROG:
@@ -1342,6 +1346,15 @@ static int add_rule(struct udev_rules *rules, char *line,
                        continue;
                }
 
+               if (strcmp(key, "TAGS") == 0) {
+                       if (op > OP_MATCH_MAX) {
+                               err(rules->udev, "invalid TAGS operation\n");
+                               goto invalid;
+                       }
+                       rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
+                       continue;
+               }
+
                if (strncmp(key, "SYSFS{", sizeof("SYSFS{")-1) == 0) {
                        if (!sysfs_warn) {
                                sysfs_warn = true;
@@ -2165,7 +2178,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                case TK_M_KERNELS:
                case TK_M_SUBSYSTEMS:
                case TK_M_DRIVERS:
-               case TK_M_ATTRS: {
+               case TK_M_ATTRS:
+               case TK_M_TAGS: {
                        struct token *next;
 
                        /* get whole sequence of parent matches */
@@ -2199,13 +2213,21 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                                if (match_attr(rules, event->dev_parent, event, key) != 0)
                                                        goto try_parent;
                                                break;
+                                       case TK_M_TAGS: {
+                                               bool match = udev_device_has_tag(event->dev_parent, &rules->buf[cur->key.value_off]);
+
+                                               if (match && key->key.op == OP_NOMATCH)
+                                                       goto try_parent;
+                                               if (!match && key->key.op == OP_MATCH)
+                                                       goto try_parent;
+                                               break;
+                                       }
                                        default:
                                                goto nomatch;
                                        }
                                        dbg(event->udev, "parent key matched\n");
                                }
                                dbg(event->udev, "all parent keys matched\n");
-                               /* all keys matched */
                                break;
 
                        try_parent:
index 8a4212f..abbfee7 100644 (file)
         </varlistentry>
 
         <varlistentry>
+          <term><option>TAGS</option></term>
+          <listitem>
+            <para>Search the devpath upwards for a device with matching tag.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
           <term><option>ENV{<replaceable>key</replaceable>}</option></term>
           <listitem>
             <para>Match against a device property value.</para>