summaryrefslogtreecommitdiff
path: root/udev
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2010-04-22 18:12:36 +0200
committerKay Sievers <kay.sievers@vrfy.org>2010-04-22 18:12:36 +0200
commit28460195c2ae90892bf556aff2b80705a8f37795 (patch)
tree8c3783342e1bf033b6f0e596985b250c2f2e5d4c /udev
parente7964b93e826274d0e92d58e458decb49e502bf5 (diff)
add TAG= to improve event filtering and device enumeration
Diffstat (limited to 'udev')
-rw-r--r--udev/udev-event.c1
-rw-r--r--udev/udev-rules.c14
-rw-r--r--udev/udev.xml13
-rw-r--r--udev/udevadm-monitor.c17
-rw-r--r--udev/udevadm-trigger.c7
-rw-r--r--udev/udevadm.xml13
6 files changed, 62 insertions, 3 deletions
diff --git a/udev/udev-event.c b/udev/udev-event.c
index b2e1baee1f..212ccc7950 100644
--- a/udev/udev-event.c
+++ b/udev/udev-event.c
@@ -543,7 +543,6 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
if (strcmp(udev_device_get_action(dev), "remove") == 0) {
udev_device_read_db(dev);
- udev_device_set_info_loaded(dev);
udev_device_delete_db(dev);
if (major(udev_device_get_devnum(dev)) != 0)
diff --git a/udev/udev-rules.c b/udev/udev-rules.c
index 6eb8350343..b5016d0bc3 100644
--- a/udev/udev-rules.c
+++ b/udev/udev-rules.c
@@ -157,6 +157,7 @@ enum token_type {
TK_A_GROUP_ID, /* gid_t */
TK_A_MODE_ID, /* mode_t */
TK_A_ENV, /* val, attr */
+ TK_A_TAG, /* val */
TK_A_NAME, /* val */
TK_A_DEVLINK, /* val */
TK_A_EVENT_TIMEOUT, /* int */
@@ -285,6 +286,7 @@ static const char *token_str(enum token_type type)
[TK_A_GROUP_ID] = "A GROUP_ID",
[TK_A_MODE_ID] = "A MODE_ID",
[TK_A_ENV] = "A ENV",
+ [TK_A_TAG] = "A ENV",
[TK_A_NAME] = "A NAME",
[TK_A_DEVLINK] = "A DEVLINK",
[TK_A_EVENT_TIMEOUT] = "A EVENT_TIMEOUT",
@@ -354,6 +356,9 @@ static void dump_token(struct udev_rules *rules, struct token *token)
dbg(rules->udev, "%s %s '%s' '%s'(%s)\n",
token_str(type), operation_str(op), attr, value, string_glob_str(glob));
break;
+ case TK_A_TAG:
+ dbg(rules->udev, "%s %s '%s'\n", token_str(type), operation_str(op), value);
+ break;
case TK_A_STRING_ESCAPE_NONE:
case TK_A_STRING_ESCAPE_REPLACE:
dbg(rules->udev, "%s\n", token_str(type));
@@ -1003,6 +1008,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
case TK_A_MODE:
case TK_A_NAME:
case TK_A_GOTO:
+ case TK_A_TAG:
token->key.value_off = add_string(rule_tmp->rules, value);
break;
case TK_M_ENV:
@@ -1350,6 +1356,11 @@ static int add_rule(struct udev_rules *rules, char *line,
continue;
}
+ if (strcmp(key, "TAG") == 0) {
+ rule_add_key(&rule_tmp, TK_A_TAG, op, value, NULL);
+ continue;
+ }
+
if (strcmp(key, "PROGRAM") == 0) {
rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL);
continue;
@@ -2408,6 +2419,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
}
break;
}
+ case TK_A_TAG:
+ udev_device_add_tag(event->dev, &rules->buf[cur->key.value_off]);
+ break;
case TK_A_NAME:
{
const char *name = &rules->buf[cur->key.value_off];
diff --git a/udev/udev.xml b/udev/udev.xml
index 192a6f1238..842fd5d52a 100644
--- a/udev/udev.xml
+++ b/udev/udev.xml
@@ -349,6 +349,19 @@
</varlistentry>
<varlistentry>
+ <term><option>TAG</option></term>
+ <listitem>
+ <para>Attach a tag to a device. This is used to filter events for users
+ of libudev's monitor functionality, or to enumerate a group of tagged
+ devices. The implementation can only work efficiently if only a few
+ tags are attached to a device. It is only meant to be used in
+ contexts with specific device filter requirements, and not as a
+ general-purpose flag. Excessive use might result in inefficient event
+ handling.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>RUN</option></term>
<listitem>
<para>Add a program to the list of programs to be executed for a specific
diff --git a/udev/udevadm-monitor.c b/udev/udevadm-monitor.c
index d136c6070a..fb650846bc 100644
--- a/udev/udevadm-monitor.c
+++ b/udev/udevadm-monitor.c
@@ -73,6 +73,7 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
int print_kernel = 0;
int print_udev = 0;
struct udev_list_node subsystem_match_list;
+ struct udev_list_node tag_match_list;
struct udev_monitor *udev_monitor = NULL;
struct udev_monitor *kernel_monitor = NULL;
fd_set readfds;
@@ -84,13 +85,15 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
{ "kernel", no_argument, NULL, 'k' },
{ "udev", no_argument, NULL, 'u' },
{ "subsystem-match", required_argument, NULL, 's' },
+ { "tag-match", required_argument, NULL, 't' },
{ "help", no_argument, NULL, 'h' },
{}
};
udev_list_init(&subsystem_match_list);
+ udev_list_init(&tag_match_list);
while (1) {
- option = getopt_long(argc, argv, "epkus:h", options, NULL);
+ option = getopt_long(argc, argv, "pekus:t:h", options, NULL);
if (option == -1)
break;
@@ -119,12 +122,16 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
udev_list_entry_add(udev, &subsystem_match_list, subsys, devtype, 0, 0);
break;
}
+ case 't':
+ udev_list_entry_add(udev, &tag_match_list, optarg, NULL, 0, 0);
+ break;
case 'h':
printf("Usage: udevadm monitor [--property] [--kernel] [--udev] [--help]\n"
" --property print the event properties\n"
" --kernel print kernel uevents\n"
" --udev print udev events\n"
" --subsystem-match=<subsystem[/devtype]> filter events by subsystem\n"
+ " --tag-match=<tag> filter events by tag\n"
" --help\n\n");
default:
goto out;
@@ -168,6 +175,13 @@ int udevadm_monitor(struct udev *udev, int argc, char *argv[])
fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys);
}
+ udev_list_entry_foreach(entry, udev_list_get_entry(&tag_match_list)) {
+ const char *tag = udev_list_entry_get_name(entry);
+
+ if (udev_monitor_filter_add_match_tag(udev_monitor, tag) < 0)
+ fprintf(stderr, "error: unable to apply tag filter '%s'\n", tag);
+ }
+
if (udev_monitor_enable_receiving(udev_monitor) < 0) {
fprintf(stderr, "error: unable to subscribe to udev events\n");
rc = 2;
@@ -244,5 +258,6 @@ out:
udev_monitor_unref(udev_monitor);
udev_monitor_unref(kernel_monitor);
udev_list_cleanup_entries(udev, &subsystem_match_list);
+ udev_list_cleanup_entries(udev, &tag_match_list);
return rc;
}
diff --git a/udev/udevadm-trigger.c b/udev/udevadm-trigger.c
index 03aa53437f..3cb07dda9a 100644
--- a/udev/udevadm-trigger.c
+++ b/udev/udevadm-trigger.c
@@ -101,6 +101,7 @@ int udevadm_trigger(struct udev *udev, int argc, char *argv[])
{ "attr-match", required_argument, NULL, 'a' },
{ "attr-nomatch", required_argument, NULL, 'A' },
{ "property-match", required_argument, NULL, 'p' },
+ { "tag-match", required_argument, NULL, 'g' },
{ "sysname-match", required_argument, NULL, 'y' },
{ "help", no_argument, NULL, 'h' },
{}
@@ -127,7 +128,7 @@ int udevadm_trigger(struct udev *udev, int argc, char *argv[])
const char *val;
char buf[UTIL_PATH_SIZE];
- option = getopt_long(argc, argv, "vnFo:t:hcp:s:S:a:A:y:", options, NULL);
+ option = getopt_long(argc, argv, "vng:o:t:hcp:s:S:a:A:y:", options, NULL);
if (option == -1)
break;
@@ -172,6 +173,9 @@ int udevadm_trigger(struct udev *udev, int argc, char *argv[])
key = keyval(optarg, &val, buf, sizeof(buf));
udev_enumerate_add_match_property(udev_enumerate, key, val);
break;
+ case 'g':
+ udev_enumerate_add_match_tag(udev_enumerate, optarg);
+ break;
case 'y':
udev_enumerate_add_match_sysname(udev_enumerate, optarg);
break;
@@ -190,6 +194,7 @@ int udevadm_trigger(struct udev *udev, int argc, char *argv[])
" --attr-match=<file[=<value>]> trigger devices with a matching attribute\n"
" --attr-nomatch=<file[=<value>]> exclude devices with a matching attribute\n"
" --property-match=<key>=<value> trigger devices with a matching property\n"
+ " --tag-match=<key>=<value> trigger devices with a matching property\n"
" --sysname-match=<name> trigger devices with a matching name\n"
" --help\n\n");
goto exit;
diff --git a/udev/udevadm.xml b/udev/udevadm.xml
index fa1742bada..73e6f110a6 100644
--- a/udev/udevadm.xml
+++ b/udev/udevadm.xml
@@ -217,6 +217,13 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><option>--tag-match=<replaceable>property</replaceable></option></term>
+ <listitem>
+ <para>Trigger events for devices with a matching tag. This option can be
+ specified multiple times.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>--sysname-match=<replaceable>name</replaceable></option></term>
<listitem>
<para>Trigger events for devices with a matching sys device name. This option can be
@@ -356,6 +363,12 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><option>--tag-match=<replaceable>string</replaceable></option></term>
+ <listitem>
+ <para>Filter events by property. Only udev events with a given tag attached will pass.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><option>--help</option></term>
<listitem>
<para>Print help text.</para>