diff --git a/man/udev.xml b/man/udev.xml
index 142f295f3e..332c7ac096 100644
--- a/man/udev.xml
+++ b/man/udev.xml
@@ -186,10 +186,10 @@
SYMLINK
- Match the name of a symlink targeting the node. It can
- be used once a SYMLINK key has been set in one of the preceding
- rules. There may be multiple symlinks; only one needs to match.
-
+ Match the name of a symlink targeting the node. It can be used once a SYMLINK key has
+ been set in one of the preceding rules. There may be multiple symlinks; only one needs to
+ match. If the operator is !=, the token returns true only if there is no
+ symlink matched.
@@ -287,14 +287,17 @@
TAG
- Match against a device tag.
+ Match against one of device tags. It can be used once a TAG key has been set in one of
+ the preceding rules. There may be multiple tags; only one needs to match. If the operator is
+ !=, the token returns true only if there is no tag matched.
TAGS
- Search the devpath upwards for a device with matching tag.
+ Search the devpath upwards for a device with matching tag. If the operator is
+ !=, the token returns true only if there is no tag matched.
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index e3d2adbafd..d6e701f3cc 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -1896,7 +1896,7 @@ static int udev_rule_apply_token_to_event(
const char *val;
FOREACH_DEVICE_DEVLINK(dev, val)
- if (token_match_string(token, strempty(startswith(val, "/dev/"))))
+ if (token_match_string(token, strempty(startswith(val, "/dev/"))) == (token->op == OP_MATCH))
return token->op == OP_MATCH;
return token->op == OP_NOMATCH;
}
@@ -1926,7 +1926,7 @@ static int udev_rule_apply_token_to_event(
const char *val;
FOREACH_DEVICE_CURRENT_TAG(dev, val)
- if (token_match_string(token, val))
+ if (token_match_string(token, val) == (token->op == OP_MATCH))
return token->op == OP_MATCH;
return token->op == OP_NOMATCH;
}
diff --git a/test/udev-test.pl b/test/udev-test.pl
index 0164c158b5..855c6aec3c 100755
--- a/test/udev-test.pl
+++ b/test/udev-test.pl
@@ -231,7 +231,8 @@ EOF
"string_escape___replace/foo_bbb",
"env_with_space",
"default/replace/mode_foo__hoge",
- "replace_env_harder_foo__hoge"],
+ "replace_env_harder_foo__hoge",
+ "match", "unmatch"],
not_exp_links => ["removed1", "removed2", "removed3", "unsafe/../../path", "/nondev/path/will/be/refused"],
}],
rules => < [
{
devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda",
- exp_links => ["found"],
- not_exp_name => "bad",
+ exp_links => ["found", "found2"],
+ not_exp_name => ["bad", "bad2"],
}],
rules => <