]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: introduce CONST key name
authorJan Synacek <jsynacek@redhat.com>
Mon, 7 Oct 2019 08:03:07 +0000 (10:03 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 14 Oct 2019 13:01:11 +0000 (22:01 +0900)
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
src/udev/udev-rules.c

index 98d17bbb54a8ca606cc542fe9e02ded933ce8b3c..09254f818ec16775e40a06bd4a87bc63d4dfca83 100644 (file)
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>CONST{<replaceable>key</replaceable>}</varname></term>
+          <listitem>
+            <para>Match against a system-wide constant. Supported keys are:</para>
+            <variablelist>
+              <varlistentry>
+                <term><literal>arch</literal></term>
+                <listitem>
+                  <para>System's architecture. See <option>ConditionArchitecture=</option> in
+                  <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                  for possible values.</para>
+                </listitem>
+              </varlistentry>
+              <varlistentry>
+                <term><literal>virt</literal></term>
+                <listitem>
+                  <para>System's virtualization environment. See
+                  <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                  for possible values.</para>
+                </listitem>
+              </varlistentry>
+            </variablelist>
+            <para>Unknown keys will never match.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>TAG</varname></term>
           <listitem>
index b09caeb7f9a6c8d7cae6d981181c2b41cc2253e4..ab54067b3f16232c030b906d6e19a01d71737e92 100644 (file)
@@ -3,6 +3,7 @@
 #include <ctype.h>
 
 #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)