diff --git a/man/udev.xml b/man/udev.xml index 98d17bbb54a..09254f818ec 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 b09caeb7f9a..ab54067b3f1 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)