core,udev,networkd: add ConditionKernelVersion=
This adds a simple condition/assert/match to the service manager, to udev's .link handling and to networkd, for matching the kernel version string. In this version we only do fnmatch() based globbing, but we might want to extend that to version comparisons later on, if we like, by slightly extending the syntax with ">=", "<=", ">", "<" and "==" expressions.
This commit is contained in:
@@ -172,6 +172,17 @@
|
||||
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>
|
||||
|
||||
@@ -232,6 +232,16 @@
|
||||
</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>
|
||||
|
||||
@@ -193,6 +193,17 @@
|
||||
</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>
|
||||
|
||||
@@ -923,6 +923,7 @@
|
||||
<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>
|
||||
@@ -1050,6 +1051,10 @@
|
||||
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
|
||||
@@ -1201,6 +1206,7 @@
|
||||
<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>
|
||||
|
||||
@@ -241,6 +241,7 @@ Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_F
|
||||
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)
|
||||
@@ -263,6 +264,7 @@ Unit.AssertFileIsExecutable, config_parse_unit_condition_path, CONDITION_F
|
||||
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)
|
||||
|
||||
@@ -116,7 +116,8 @@ bool net_match_config(const struct ether_addr *match_mac,
|
||||
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,
|
||||
@@ -131,7 +132,10 @@ bool net_match_config(const struct ether_addr *match_mac,
|
||||
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)
|
||||
|
||||
@@ -37,7 +37,8 @@ bool net_match_config(const struct ether_addr *match_mac,
|
||||
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,
|
||||
|
||||
@@ -33,7 +33,8 @@ struct ConfigPerfItem;
|
||||
%%
|
||||
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)
|
||||
|
||||
@@ -149,7 +149,8 @@ static void netdev_free(NetDev *netdev) {
|
||||
|
||||
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) &&
|
||||
@@ -642,7 +643,8 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
/* 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;
|
||||
|
||||
|
||||
@@ -93,7 +93,8 @@ typedef struct NetDev {
|
||||
|
||||
Condition *match_host;
|
||||
Condition *match_virt;
|
||||
Condition *match_kernel;
|
||||
Condition *match_kernel_cmdline;
|
||||
Condition *match_kernel_version;
|
||||
Condition *match_arch;
|
||||
|
||||
NetDevState state;
|
||||
|
||||
@@ -27,7 +27,8 @@ Match.Type, config_parse_strv,
|
||||
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)
|
||||
|
||||
@@ -431,7 +431,8 @@ void network_free(Network *network) {
|
||||
|
||||
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);
|
||||
@@ -485,8 +486,8 @@ int network_get(Manager *manager, struct udev_device *device,
|
||||
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) {
|
||||
|
||||
@@ -112,7 +112,8 @@ struct Network {
|
||||
|
||||
Condition *match_host;
|
||||
Condition *match_virt;
|
||||
Condition *match_kernel;
|
||||
Condition *match_kernel_cmdline;
|
||||
Condition *match_kernel_version;
|
||||
Condition *match_arch;
|
||||
|
||||
char *description;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -143,6 +144,18 @@ static int condition_test_kernel_command_line(Condition *c) {
|
||||
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;
|
||||
@@ -552,6 +565,7 @@ int condition_test(Condition *c) {
|
||||
[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,
|
||||
@@ -612,6 +626,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[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",
|
||||
@@ -639,6 +654,7 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
|
||||
[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",
|
||||
|
||||
@@ -31,6 +31,7 @@ typedef enum ConditionType {
|
||||
CONDITION_VIRTUALIZATION,
|
||||
CONDITION_HOST,
|
||||
CONDITION_KERNEL_COMMAND_LINE,
|
||||
CONDITION_KERNEL_VERSION,
|
||||
CONDITION_SECURITY,
|
||||
CONDITION_CAPABILITY,
|
||||
CONDITION_AC_POWER,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-id128.h"
|
||||
@@ -38,10 +39,11 @@
|
||||
#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;
|
||||
@@ -298,6 +300,41 @@ static void test_condition_test_kernel_command_line(void) {
|
||||
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;
|
||||
|
||||
@@ -556,6 +593,7 @@ int main(int argc, char *argv[]) {
|
||||
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();
|
||||
|
||||
@@ -26,7 +26,8 @@ Match.Driver, config_parse_strv, 0,
|
||||
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)
|
||||
|
||||
@@ -77,7 +77,8 @@ static void link_config_free(link_config *link) {
|
||||
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);
|
||||
@@ -248,7 +249,8 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device,
|
||||
|
||||
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)),
|
||||
|
||||
@@ -58,7 +58,8 @@ struct link_config {
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user