summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-04-26 16:40:01 +0200
committerGitHub <noreply@github.com>2023-04-26 16:40:01 +0200
commit1db4acbe5d78a6337ffb163d9bd12eabac2fdda4 (patch)
treeb8de8842cea4e416e5f98418116fef011735db5c
parent0f566980795b002776ee86add17fa794699120d3 (diff)
parenta101d91988a889e2c9f4b661a4d290d21fc4d77e (diff)
downloadsystemd-1db4acbe5d78a6337ffb163d9bd12eabac2fdda4.tar.gz
Merge pull request #27398 from yuwata/udev-rule-negative-match
udev-rule: fix negative match
-rw-r--r--man/udev.xml15
-rw-r--r--src/udev/udev-rules.c4
-rwxr-xr-xtest/udev-test.pl11
3 files changed, 19 insertions, 11 deletions
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 @@
<varlistentry>
<term><varname>SYMLINK</varname></term>
<listitem>
- <para>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.
- </para>
+ <para>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 <literal>!=</literal>, the token returns true only if there is no
+ symlink matched.</para>
</listitem>
</varlistentry>
@@ -287,14 +287,17 @@
<varlistentry>
<term><varname>TAG</varname></term>
<listitem>
- <para>Match against a device tag.</para>
+ <para>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
+ <literal>!=</literal>, the token returns true only if there is no tag matched.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TAGS</varname></term>
<listitem>
- <para>Search the devpath upwards for a device with matching tag.</para>
+ <para>Search the devpath upwards for a device with matching tag. If the operator is
+ <literal>!=</literal>, the token returns true only if there is no tag matched.</para>
</listitem>
</varlistentry>
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 => <<EOF
@@ -250,6 +251,8 @@ SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", OPTIONS="s
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ENV{.HOGE}="env with space", SYMLINK+="%E{.HOGE}"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", ENV{.HOGE}="default/replace/mode?foo;;hoge", SYMLINK+="%E{.HOGE}"
SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", OPTIONS="string_escape=replace", ENV{.HOGE}="replace/env/harder?foo;;hoge", SYMLINK+="%E{.HOGE}"
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", SYMLINK=="link1", SYMLINK+="match"
+SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", ATTRS{model}=="ST910021AS", SYMLINK!="removed1", SYMLINK+="unmatch"
EOF
},
{
@@ -1853,13 +1856,15 @@ EOF
devices => [
{
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 => <<EOF
KERNEL=="sda", TAG="foo"
TAGS=="foo|", SYMLINK+="found"
TAGS=="aaa|", SYMLINK+="bad"
+KERNEL=="sda", TAGS!="hoge", SYMLINK+="found2"
+KERNEL=="sda", TAGS!="foo", SYMLINK+="bad2"
EOF
},
{