|
|
ddca0b |
From d6210c3d053d70175d72ed1d1719497eed76000b Mon Sep 17 00:00:00 2001
|
|
|
ddca0b |
From: Jan Synacek <jsynacek@redhat.com>
|
|
|
ddca0b |
Date: Thu, 17 Oct 2019 09:37:35 +0200
|
|
|
ddca0b |
Subject: [PATCH] udev: introduce CONST key name
|
|
|
ddca0b |
|
|
|
ddca0b |
Currently, there is no way to match against system-wide constants, such
|
|
|
ddca0b |
as architecture or virtualization type, without forking helper binaries.
|
|
|
ddca0b |
That potentially results in a huge number of spawned processes which
|
|
|
ddca0b |
output always the same answer.
|
|
|
ddca0b |
|
|
|
ddca0b |
This patch introduces a special CONST keyword which takes a hard-coded
|
|
|
ddca0b |
string as its key and returns a value assigned to that key. Currently
|
|
|
ddca0b |
implemented are CONST{arch} and CONST{virt}, which can be used to match
|
|
|
ddca0b |
against the system's architecture and virtualization type.
|
|
|
ddca0b |
|
|
|
ddca0b |
(based on commit 4801d8afe2ff1c1c075c9f0bc5631612172e0bb7)
|
|
|
ddca0b |
|
|
|
ddca0b |
Resolves: #1762679
|
|
|
ddca0b |
---
|
|
|
ddca0b |
man/udev.xml | 26 ++++++++++++++++++++++++++
|
|
|
ddca0b |
rules/40-redhat.rules | 6 +++---
|
|
|
ddca0b |
src/udev/udev-rules.c | 32 ++++++++++++++++++++++++++++++++
|
|
|
ddca0b |
test/rule-syntax-check.py | 2 +-
|
|
|
ddca0b |
4 files changed, 62 insertions(+), 4 deletions(-)
|
|
|
ddca0b |
|
|
|
ddca0b |
diff --git a/man/udev.xml b/man/udev.xml
|
|
|
ddca0b |
index bdf901a8f0..8c1eb41787 100644
|
|
|
ddca0b |
--- a/man/udev.xml
|
|
|
ddca0b |
+++ b/man/udev.xml
|
|
|
ddca0b |
@@ -236,6 +236,32 @@
|
|
|
ddca0b |
</listitem>
|
|
|
ddca0b |
</varlistentry>
|
|
|
ddca0b |
|
|
|
ddca0b |
+ <varlistentry>
|
|
|
ddca0b |
+ <term><varname>CONST{<replaceable>key</replaceable>}</varname></term>
|
|
|
ddca0b |
+ <listitem>
|
|
|
ddca0b |
+ <para>Match against a system-wide constant. Supported keys are:</para>
|
|
|
ddca0b |
+ <variablelist>
|
|
|
ddca0b |
+ <varlistentry>
|
|
|
ddca0b |
+ <term><literal>arch</literal></term>
|
|
|
ddca0b |
+ <listitem>
|
|
|
ddca0b |
+ <para>System's architecture. See <option>ConditionArchitecture=</option> in
|
|
|
ddca0b |
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
|
|
ddca0b |
+ for possible values.</para>
|
|
|
ddca0b |
+ </listitem>
|
|
|
ddca0b |
+ </varlistentry>
|
|
|
ddca0b |
+ <varlistentry>
|
|
|
ddca0b |
+ <term><literal>virt</literal></term>
|
|
|
ddca0b |
+ <listitem>
|
|
|
ddca0b |
+ <para>System's virtualization environment. See
|
|
|
ddca0b |
+ <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
|
|
ddca0b |
+ for possible values.</para>
|
|
|
ddca0b |
+ </listitem>
|
|
|
ddca0b |
+ </varlistentry>
|
|
|
ddca0b |
+ </variablelist>
|
|
|
ddca0b |
+ <para>Unknown keys will never match.</para>
|
|
|
ddca0b |
+ </listitem>
|
|
|
ddca0b |
+ </varlistentry>
|
|
|
ddca0b |
+
|
|
|
ddca0b |
<varlistentry>
|
|
|
ddca0b |
<term><varname>TAG</varname></term>
|
|
|
ddca0b |
<listitem>
|
|
|
ddca0b |
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
|
|
|
ddca0b |
index fadc6e59f1..3c95cd2df0 100644
|
|
|
ddca0b |
--- a/rules/40-redhat.rules
|
|
|
ddca0b |
+++ b/rules/40-redhat.rules
|
|
|
ddca0b |
@@ -6,11 +6,11 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}
|
|
|
ddca0b |
# Memory hotadd request
|
|
|
ddca0b |
SUBSYSTEM!="memory", GOTO="memory_hotplug_end"
|
|
|
ddca0b |
ACTION!="add", GOTO="memory_hotplug_end"
|
|
|
ddca0b |
-PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end"
|
|
|
ddca0b |
-PROGRAM="/bin/uname -p", RESULT=="ppc64*", GOTO="memory_hotplug_end"
|
|
|
ddca0b |
+CONST{arch}=="s390*", GOTO="memory_hotplug_end"
|
|
|
ddca0b |
+CONST{arch}=="ppc64*", GOTO="memory_hotplug_end"
|
|
|
ddca0b |
|
|
|
ddca0b |
ENV{.state}="online"
|
|
|
ddca0b |
-PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable"
|
|
|
ddca0b |
+CONST{virt}=="none", ENV{.state}="online_movable"
|
|
|
ddca0b |
ATTR{state}=="offline", ATTR{state}="$env{.state}"
|
|
|
ddca0b |
|
|
|
ddca0b |
LABEL="memory_hotplug_end"
|
|
|
ddca0b |
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
|
|
|
ddca0b |
index 58af863f3d..a246cbe67e 100644
|
|
|
ddca0b |
--- a/src/udev/udev-rules.c
|
|
|
ddca0b |
+++ b/src/udev/udev-rules.c
|
|
|
ddca0b |
@@ -17,6 +17,7 @@
|
|
|
ddca0b |
#include <unistd.h>
|
|
|
ddca0b |
|
|
|
ddca0b |
#include "alloc-util.h"
|
|
|
ddca0b |
+#include "architecture.h"
|
|
|
ddca0b |
#include "conf-files.h"
|
|
|
ddca0b |
#include "dirent-util.h"
|
|
|
ddca0b |
#include "escape.h"
|
|
|
ddca0b |
@@ -34,6 +35,7 @@
|
|
|
ddca0b |
#include "udev.h"
|
|
|
ddca0b |
#include "user-util.h"
|
|
|
ddca0b |
#include "util.h"
|
|
|
ddca0b |
+#include "virt.h"
|
|
|
ddca0b |
|
|
|
ddca0b |
#define PREALLOC_TOKEN 2048
|
|
|
ddca0b |
|
|
|
ddca0b |
@@ -123,6 +125,7 @@ enum token_type {
|
|
|
ddca0b |
TK_M_DEVLINK, /* val */
|
|
|
ddca0b |
TK_M_NAME, /* val */
|
|
|
ddca0b |
TK_M_ENV, /* val, attr */
|
|
|
ddca0b |
+ TK_M_CONST, /* val, attr */
|
|
|
ddca0b |
TK_M_TAG, /* val */
|
|
|
ddca0b |
TK_M_SUBSYSTEM, /* val */
|
|
|
ddca0b |
TK_M_DRIVER, /* val */
|
|
|
ddca0b |
@@ -259,6 +262,7 @@ static const char *token_str(enum token_type type) {
|
|
|
ddca0b |
[TK_M_DEVLINK] = "M DEVLINK",
|
|
|
ddca0b |
[TK_M_NAME] = "M NAME",
|
|
|
ddca0b |
[TK_M_ENV] = "M ENV",
|
|
|
ddca0b |
+ [TK_M_CONST] = "M CONST",
|
|
|
ddca0b |
[TK_M_TAG] = "M TAG",
|
|
|
ddca0b |
[TK_M_SUBSYSTEM] = "M SUBSYSTEM",
|
|
|
ddca0b |
[TK_M_DRIVER] = "M DRIVER",
|
|
|
ddca0b |
@@ -370,6 +374,7 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
|
|
|
ddca0b |
case TK_M_SYSCTL:
|
|
|
ddca0b |
case TK_M_ATTRS:
|
|
|
ddca0b |
case TK_M_ENV:
|
|
|
ddca0b |
+ case TK_M_CONST:
|
|
|
ddca0b |
case TK_A_ATTR:
|
|
|
ddca0b |
case TK_A_SYSCTL:
|
|
|
ddca0b |
case TK_A_ENV:
|
|
|
ddca0b |
@@ -903,6 +908,7 @@ static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
|
|
|
ddca0b |
token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
|
|
|
ddca0b |
break;
|
|
|
ddca0b |
case TK_M_ENV:
|
|
|
ddca0b |
+ case TK_M_CONST:
|
|
|
ddca0b |
case TK_M_ATTR:
|
|
|
ddca0b |
case TK_M_SYSCTL:
|
|
|
ddca0b |
case TK_M_ATTRS:
|
|
|
ddca0b |
@@ -1226,6 +1232,17 @@ static void add_rule(struct udev_rules *rules, char *line,
|
|
|
ddca0b |
rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr);
|
|
|
ddca0b |
}
|
|
|
ddca0b |
|
|
|
ddca0b |
+ } else if (startswith(key, "CONST{")) {
|
|
|
ddca0b |
+ attr = get_key_attribute(rules->udev, key + STRLEN("CONST"));
|
|
|
ddca0b |
+ if (attr == NULL || !STR_IN_SET(attr, "arch", "virt"))
|
|
|
ddca0b |
+ LOG_AND_RETURN("error parsing %s attribute", "CONST");
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ if (op == OP_REMOVE)
|
|
|
ddca0b |
+ LOG_AND_RETURN("invalid %s operation", "CONST");
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ if (op < OP_MATCH_MAX)
|
|
|
ddca0b |
+ rule_add_key(&rule_tmp, TK_M_CONST, op, value, attr);
|
|
|
ddca0b |
+
|
|
|
ddca0b |
} else if (streq(key, "TAG")) {
|
|
|
ddca0b |
if (op < OP_MATCH_MAX)
|
|
|
ddca0b |
rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
|
|
|
ddca0b |
@@ -1855,6 +1872,21 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
|
|
ddca0b |
goto nomatch;
|
|
|
ddca0b |
break;
|
|
|
ddca0b |
}
|
|
|
ddca0b |
+ case TK_M_CONST: {
|
|
|
ddca0b |
+ const char *key_name = rules_str(rules, cur->key.attr_off);
|
|
|
ddca0b |
+ const char *value = NULL;
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ if (streq(key_name, "arch")) {
|
|
|
ddca0b |
+ value = architecture_to_string(uname_architecture());
|
|
|
ddca0b |
+ } else if (streq(key_name, "virt")) {
|
|
|
ddca0b |
+ value = virtualization_to_string(detect_virtualization());
|
|
|
ddca0b |
+ } else
|
|
|
ddca0b |
+ assert_not_reached("Invalid CONST key");
|
|
|
ddca0b |
+
|
|
|
ddca0b |
+ if (match_key(rules, cur, value))
|
|
|
ddca0b |
+ goto nomatch;
|
|
|
ddca0b |
+ break;
|
|
|
ddca0b |
+ }
|
|
|
ddca0b |
case TK_M_TAG: {
|
|
|
ddca0b |
struct udev_list_entry *list_entry;
|
|
|
ddca0b |
bool match = false;
|
|
|
ddca0b |
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
|
|
|
ddca0b |
index c7c0a1a656..6e59f421f5 100755
|
|
|
ddca0b |
--- a/test/rule-syntax-check.py
|
|
|
ddca0b |
+++ b/test/rule-syntax-check.py
|
|
|
ddca0b |
@@ -19,7 +19,7 @@ quoted_string_re = r'"(?:[^\\"]|\\.)*"'
|
|
|
ddca0b |
no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$')
|
|
|
ddca0b |
# PROGRAM can also be specified as an assignment.
|
|
|
ddca0b |
program_assign = re.compile(r'PROGRAM\s*=\s*' + quoted_string_re + '$')
|
|
|
ddca0b |
-args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
|
|
|
ddca0b |
+args_tests = re.compile(r'(ATTRS?|ENV|CONST|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
|
|
|
ddca0b |
no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
|
|
|
ddca0b |
args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
|
|
|
ddca0b |
# Find comma-separated groups, but allow commas that are inside quoted strings.
|