for details.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>KernelVersion=</varname></term>
+ <listitem>
+ <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain
+ expression (or if prefixed with the exclamation mark does not match it). See
+ <literal>ConditionKernelVersion=</literal> in
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+ details.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>Architecture=</varname></term>
<listitem>
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>KernelVersion=</varname></term>
+ <listitem>
+ <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain
+ expression (or if prefixed with the exclamation mark does not match it). See
+ <literal>ConditionKernelVersion=</literal> in
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Architecture=</varname></term>
<listitem>
<para>Checks whether the system is running on a specific
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>KernelVersion=</varname></term>
+ <listitem>
+ <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain
+ expression (or if prefixed with the exclamation mark does not match it). See
+ <literal>ConditionKernelVersion=</literal> in
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+ details.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Architecture=</varname></term>
<listitem>
<para>Checks whether the system is running on a specific
<term><varname>ConditionVirtualization=</varname></term>
<term><varname>ConditionHost=</varname></term>
<term><varname>ConditionKernelCommandLine=</varname></term>
+ <term><varname>ConditionKernelVersion=</varname></term>
<term><varname>ConditionSecurity=</varname></term>
<term><varname>ConditionCapability=</varname></term>
<term><varname>ConditionACPower=</varname></term>
the exact assignment is looked for with right and left hand
side matching.</para>
+ <para><varname>ConditionKernelVersion=</varname> may be used to check whether the kernel version (as reported
+ by <command>uname -r</command>) matches a certain expression (or if prefixed with the exclamation mark does not
+ match it). The argument must be a single string, optionally containing shell-style globs.</para>
+
<para><varname>ConditionSecurity=</varname> may be used to
check whether the given security module is enabled on the
system. Currently, the recognized values are
<term><varname>AssertVirtualization=</varname></term>
<term><varname>AssertHost=</varname></term>
<term><varname>AssertKernelCommandLine=</varname></term>
+ <term><varname>AssertKernelVersion=</varname></term>
<term><varname>AssertSecurity=</varname></term>
<term><varname>AssertCapability=</varname></term>
<term><varname>AssertACPower=</varname></term>
Unit.ConditionNeedsUpdate, config_parse_unit_condition_path, CONDITION_NEEDS_UPDATE, offsetof(Unit, conditions)
Unit.ConditionFirstBoot, config_parse_unit_condition_string, CONDITION_FIRST_BOOT, offsetof(Unit, conditions)
Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, conditions)
+Unit.ConditionKernelVersion, config_parse_unit_condition_string, CONDITION_KERNEL_VERSION, offsetof(Unit, conditions)
Unit.ConditionArchitecture, config_parse_unit_condition_string, CONDITION_ARCHITECTURE, offsetof(Unit, conditions)
Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, offsetof(Unit, conditions)
Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, offsetof(Unit, conditions)
Unit.AssertNeedsUpdate, config_parse_unit_condition_path, CONDITION_NEEDS_UPDATE, offsetof(Unit, asserts)
Unit.AssertFirstBoot, config_parse_unit_condition_string, CONDITION_FIRST_BOOT, offsetof(Unit, asserts)
Unit.AssertKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, asserts)
+Unit.AssertKernelVersion, config_parse_unit_condition_string, CONDITION_KERNEL_VERSION, offsetof(Unit, asserts)
Unit.AssertArchitecture, config_parse_unit_condition_string, CONDITION_ARCHITECTURE, offsetof(Unit, asserts)
Unit.AssertVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, offsetof(Unit, asserts)
Unit.AssertSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, offsetof(Unit, asserts)
char * const *match_names,
Condition *match_host,
Condition *match_virt,
- Condition *match_kernel,
+ Condition *match_kernel_cmdline,
+ Condition *match_kernel_version,
Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,
if (match_virt && condition_test(match_virt) <= 0)
return false;
- if (match_kernel && condition_test(match_kernel) <= 0)
+ if (match_kernel_cmdline && condition_test(match_kernel_cmdline) <= 0)
+ return false;
+
+ if (match_kernel_version && condition_test(match_kernel_version) <= 0)
return false;
if (match_arch && condition_test(match_arch) <= 0)
char * const *match_name,
Condition *match_host,
Condition *match_virt,
- Condition *match_kernel,
+ Condition *match_kernel_cmdline,
+ Condition *match_kernel_version,
Condition *match_arch,
const struct ether_addr *dev_mac,
const char *dev_path,
%%
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel_cmdline)
+Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(NetDev, match_kernel_version)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch)
NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
condition_free_list(netdev->match_host);
condition_free_list(netdev->match_virt);
- condition_free_list(netdev->match_kernel);
+ condition_free_list(netdev->match_kernel_cmdline);
+ condition_free_list(netdev->match_kernel_version);
condition_free_list(netdev->match_arch);
if (NETDEV_VTABLE(netdev) &&
/* skip out early if configuration does not match the environment */
if (net_match_config(NULL, NULL, NULL, NULL, NULL,
netdev_raw->match_host, netdev_raw->match_virt,
- netdev_raw->match_kernel, netdev_raw->match_arch,
+ netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version,
+ netdev_raw->match_arch,
NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
return 0;
Condition *match_host;
Condition *match_virt;
- Condition *match_kernel;
+ Condition *match_kernel_cmdline;
+ Condition *match_kernel_version;
Condition *match_arch;
NetDevState state;
Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel_cmdline)
+Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, match_kernel_version)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu)
condition_free_list(network->match_host);
condition_free_list(network->match_virt);
- condition_free_list(network->match_kernel);
+ condition_free_list(network->match_kernel_cmdline);
+ condition_free_list(network->match_kernel_version);
condition_free_list(network->match_arch);
free(network->dhcp_server_timezone);
if (net_match_config(network->match_mac, network->match_path,
network->match_driver, network->match_type,
network->match_name, network->match_host,
- network->match_virt, network->match_kernel,
- network->match_arch,
+ network->match_virt, network->match_kernel_cmdline,
+ network->match_kernel_version, network->match_arch,
address, path, parent_driver, driver,
devtype, ifname)) {
if (network->match_name && device) {
Condition *match_host;
Condition *match_virt;
- Condition *match_kernel;
+ Condition *match_kernel_cmdline;
+ Condition *match_kernel_version;
Condition *match_arch;
char *description;
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>
return false;
}
+static int condition_test_kernel_version(Condition *c) {
+ struct utsname u;
+
+ assert(c);
+ assert(c->parameter);
+ assert(c->type == CONDITION_KERNEL_VERSION);
+
+ assert_se(uname(&u) >= 0);
+
+ return fnmatch(c->parameter, u.release, 0) == 0;
+}
+
static int condition_test_user(Condition *c) {
uid_t id;
int r;
[CONDITION_FILE_NOT_EMPTY] = condition_test_file_not_empty,
[CONDITION_FILE_IS_EXECUTABLE] = condition_test_file_is_executable,
[CONDITION_KERNEL_COMMAND_LINE] = condition_test_kernel_command_line,
+ [CONDITION_KERNEL_VERSION] = condition_test_kernel_version,
[CONDITION_VIRTUALIZATION] = condition_test_virtualization,
[CONDITION_SECURITY] = condition_test_security,
[CONDITION_CAPABILITY] = condition_test_capability,
[CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
[CONDITION_HOST] = "ConditionHost",
[CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
+ [CONDITION_KERNEL_VERSION] = "ConditionKernelVersion",
[CONDITION_SECURITY] = "ConditionSecurity",
[CONDITION_CAPABILITY] = "ConditionCapability",
[CONDITION_AC_POWER] = "ConditionACPower",
[CONDITION_VIRTUALIZATION] = "AssertVirtualization",
[CONDITION_HOST] = "AssertHost",
[CONDITION_KERNEL_COMMAND_LINE] = "AssertKernelCommandLine",
+ [CONDITION_KERNEL_VERSION] = "AssertKernelVersion",
[CONDITION_SECURITY] = "AssertSecurity",
[CONDITION_CAPABILITY] = "AssertCapability",
[CONDITION_AC_POWER] = "AssertACPower",
CONDITION_VIRTUALIZATION,
CONDITION_HOST,
CONDITION_KERNEL_COMMAND_LINE,
+ CONDITION_KERNEL_VERSION,
CONDITION_SECURITY,
CONDITION_CAPABILITY,
CONDITION_AC_POWER,
#include <stdio.h>
#include <sys/types.h>
+#include <sys/utsname.h>
#include <unistd.h>
#include "sd-id128.h"
#include "selinux-util.h"
#include "set.h"
#include "smack-util.h"
+#include "string-util.h"
#include "strv.h"
-#include "virt.h"
-#include "util.h"
#include "user-util.h"
+#include "util.h"
+#include "virt.h"
static void test_condition_test_path(void) {
Condition *condition;
condition_free(condition);
}
+static void test_condition_test_kernel_version(void) {
+ Condition *condition;
+ struct utsname u;
+
+ condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false);
+ assert_se(condition);
+ assert_se(!condition_test(condition));
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false);
+ assert_se(condition);
+ assert_se(condition_test(condition));
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false);
+ assert_se(condition);
+ assert_se(!condition_test(condition));
+ condition_free(condition);
+
+ assert_se(uname(&u) >= 0);
+
+ condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
+ assert_se(condition);
+ assert_se(condition_test(condition));
+ condition_free(condition);
+
+ strshorten(u.release, 4);
+ strcpy(strchr(u.release, 0), "*");
+
+ condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
+ assert_se(condition);
+ assert_se(condition_test(condition));
+ condition_free(condition);
+}
+
static void test_condition_test_null(void) {
Condition *condition;
test_condition_test_host();
test_condition_test_architecture();
test_condition_test_kernel_command_line();
+ test_condition_test_kernel_version();
test_condition_test_null();
test_condition_test_security();
test_condition_test_virtualization();
Match.Type, config_parse_strv, 0, offsetof(link_config, match_type)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, match_host)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel_cmdline)
+Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, match_kernel_version)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, match_arch)
Link.Description, config_parse_string, 0, offsetof(link_config, description)
Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy)
free(link->match_name);
free(link->match_host);
free(link->match_virt);
- free(link->match_kernel);
+ free(link->match_kernel_cmdline);
+ free(link->match_kernel_version);
free(link->match_arch);
free(link->description);
if (net_match_config(link->match_mac, link->match_path, link->match_driver,
link->match_type, link->match_name, link->match_host,
- link->match_virt, link->match_kernel, link->match_arch,
+ link->match_virt, link->match_kernel_cmdline,
+ link->match_kernel_version, link->match_arch,
attr_value ? ether_aton(attr_value) : NULL,
udev_device_get_property_value(device, "ID_PATH"),
udev_device_get_driver(udev_device_get_parent(device)),
char **match_name;
Condition *match_host;
Condition *match_virt;
- Condition *match_kernel;
+ Condition *match_kernel_cmdline;
+ Condition *match_kernel_version;
Condition *match_arch;
char *description;