From 4801d8afe2ff1c1c075c9f0bc5631612172e0bb7 Mon Sep 17 00:00:00 2001 From: Jan Synacek Date: Mon, 7 Oct 2019 10:03:07 +0200 Subject: [PATCH] udev: introduce CONST key name Currently, there is no way to match against system-wide constants, such as architecture or virtualization type, without forking helper binaries. That potentially results in a huge number of spawned processes which output always the same answer. This patch introduces a special CONST keyword which takes a hard-coded string as its key and returns a value assigned to that key. Currently implemented are CONST{arch} and CONST{virt}, which can be used to match against the system's architecture and virtualization type. --- man/udev.xml | 26 ++++++++++++++++++++++++++ src/udev/udev-rules.c | 20 ++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/man/udev.xml b/man/udev.xml index 98d17bbb54..09254f818e 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -236,6 +236,32 @@ + + CONST{key} + + Match against a system-wide constant. Supported keys are: + + + arch + + System's architecture. See in + systemd.unit5 + for possible values. + + + + virt + + System's virtualization environment. See + systemd-detect-virt1 + for possible values. + + + + Unknown keys will never match. + + + TAG diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index b09caeb7f9..ab54067b3f 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -3,6 +3,7 @@ #include #include "alloc-util.h" +#include "architecture.h" #include "conf-files.h" #include "def.h" #include "device-util.h" @@ -28,6 +29,7 @@ #include "udev-event.h" #include "udev-rules.h" #include "user-util.h" +#include "virt.h" #define RULES_DIRS (const char* const*) CONF_PATHS_STRV("udev/rules.d") @@ -69,6 +71,7 @@ typedef enum { TK_M_DEVLINK, /* strv, sd_device_get_devlink_first(), sd_device_get_devlink_next() */ TK_M_NAME, /* string, name of network interface */ TK_M_ENV, /* string, device property, takes key through attribute */ + TK_M_CONST, /* string, system-specific hard-coded constant */ TK_M_TAG, /* strv, sd_device_get_tag_first(), sd_device_get_tag_next() */ TK_M_SUBSYSTEM, /* string, sd_device_get_subsystem() */ TK_M_DRIVER, /* string, sd_device_get_driver() */ @@ -618,6 +621,12 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp r = rule_line_add_token(rule_line, TK_A_ENV, op, value, attr); } else r = rule_line_add_token(rule_line, TK_M_ENV, op, value, attr); + } else if (streq(key, "CONST")) { + if (isempty(attr) || !STR_IN_SET(attr, "arch", "virt")) + return log_token_invalid_attr(rules, key); + if (!is_match) + return log_token_invalid_op(rules, key); + r = rule_line_add_token(rule_line, TK_M_CONST, op, value, attr); } else if (streq(key, "TAG")) { if (attr) return log_token_invalid_attr(rules, key); @@ -1574,6 +1583,17 @@ static int udev_rule_apply_token_to_event( val = hashmap_get(properties_list, token->data); return token_match_string(token, val); + case TK_M_CONST: { + const char *k = token->data; + + if (streq(k, "arch")) + val = architecture_to_string(uname_architecture()); + else if (streq(k, "virt")) + val = virtualization_to_string(detect_virtualization()); + else + assert_not_reached("Invalid CONST key"); + return token_match_string(token, val); + } case TK_M_TAG: case TK_M_PARENTS_TAG: FOREACH_DEVICE_TAG(dev, val)