summaryrefslogtreecommitdiff
path: root/udev
diff options
context:
space:
mode:
Diffstat (limited to 'udev')
-rw-r--r--udev/udev-rules.c26
-rw-r--r--udev/udev.xml7
2 files changed, 31 insertions, 2 deletions
diff --git a/udev/udev-rules.c b/udev/udev-rules.c
index c24da0c497..a77e1e223f 100644
--- a/udev/udev-rules.c
+++ b/udev/udev-rules.c
@@ -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:
diff --git a/udev/udev.xml b/udev/udev.xml
index 8a4212fd54..abbfee7ad1 100644
--- a/udev/udev.xml
+++ b/udev/udev.xml
@@ -234,6 +234,13 @@
</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>