1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-10-28 03:25:27 +03:00

Merge pull request #11931 from yuwata/condition-test-list

split static condition tests from net_match_config()
This commit is contained in:
Yu Watanabe 2019-03-22 02:30:57 +09:00 committed by GitHub
commit b239288f72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 260 additions and 278 deletions

View File

@ -113,52 +113,55 @@
<varlistentry> <varlistentry>
<term><varname>Host=</varname></term> <term><varname>Host=</varname></term>
<listitem> <listitem>
<para>Matches against the hostname or machine <para>Matches against the hostname or machine ID of the host. See <varname>ConditionHost=</varname> in
ID of the host. See <varname>ConditionHost=</varname> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para> for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Virtualization=</varname></term> <term><varname>Virtualization=</varname></term>
<listitem> <listitem>
<para>Checks whether the system is executed in <para>Checks whether the system is executed in a virtualized environment and optionally test
a virtualized environment and optionally test whether it is a specific implementation. See <varname>ConditionVirtualization=</varname> in
whether it is a specific implementation. See
<varname>ConditionVirtualization=</varname> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para> for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>KernelCommandLine=</varname></term> <term><varname>KernelCommandLine=</varname></term>
<listitem> <listitem>
<para>Checks whether a specific kernel command line option <para>Checks whether a specific kernel command line option is set. See
is set (or if prefixed with the exclamation mark unset). See
<varname>ConditionKernelCommandLine=</varname> in <varname>ConditionKernelCommandLine=</varname> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para> for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>KernelVersion=</varname></term> <term><varname>KernelVersion=</varname></term>
<listitem> <listitem>
<para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain <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 expression. See <varname>ConditionKernelVersion=</varname> in
<varname>ConditionKernelVersion=</varname> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details. details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Architecture=</varname></term> <term><varname>Architecture=</varname></term>
<listitem> <listitem>
<para>Checks whether the system is running on a specific <para>Checks whether the system is running on a specific architecture. See
architecture. See <varname>ConditionArchitecture=</varname> <varname>ConditionArchitecture=</varname> in
in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para> for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View File

@ -190,53 +190,55 @@
<varlistentry> <varlistentry>
<term><varname>Host=</varname></term> <term><varname>Host=</varname></term>
<listitem> <listitem>
<para>Matches against the hostname or machine ID of the <para>Matches against the hostname or machine ID of the host. See
host. See <literal>ConditionHost=</literal> in <literal>ConditionHost=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Virtualization=</varname></term> <term><varname>Virtualization=</varname></term>
<listitem> <listitem>
<para>Checks whether the system is executed in a virtualized <para>Checks whether the system is executed in a virtualized environment and optionally test
environment and optionally test whether it is a specific whether it is a specific implementation. See <literal>ConditionVirtualization=</literal> in
implementation. See
<literal>ConditionVirtualization=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>KernelCommandLine=</varname></term> <term><varname>KernelCommandLine=</varname></term>
<listitem> <listitem>
<para>Checks whether a specific kernel command line option <para>Checks whether a specific kernel command line option is set. See
is set (or if prefixed with the exclamation mark unset). See
<literal>ConditionKernelCommandLine=</literal> in <literal>ConditionKernelCommandLine=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>KernelVersion=</varname></term> <term><varname>KernelVersion=</varname></term>
<listitem> <listitem>
<para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a
expression (or if prefixed with the exclamation mark does not match it). See certain expression. See <literal>ConditionKernelVersion=</literal> in
<literal>ConditionKernelVersion=</literal> in <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Architecture=</varname></term> <term><varname>Architecture=</varname></term>
<listitem> <listitem>
<para>Checks whether the system is running on a specific <para>Checks whether the system is running on a specific architecture. See
architecture. See <literal>ConditionArchitecture=</literal> in <literal>ConditionArchitecture=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -137,53 +137,55 @@
<varlistentry> <varlistentry>
<term><varname>Host=</varname></term> <term><varname>Host=</varname></term>
<listitem> <listitem>
<para>Matches against the hostname or machine ID of the <para>Matches against the hostname or machine ID of the host. See
host. See <literal>ConditionHost=</literal> in <literal>ConditionHost=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Virtualization=</varname></term> <term><varname>Virtualization=</varname></term>
<listitem> <listitem>
<para>Checks whether the system is executed in a virtualized <para>Checks whether the system is executed in a virtualized environment and optionally test
environment and optionally test whether it is a specific whether it is a specific implementation. See <literal>ConditionVirtualization=</literal> in
implementation. See <literal>ConditionVirtualization=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>KernelCommandLine=</varname></term> <term><varname>KernelCommandLine=</varname></term>
<listitem> <listitem>
<para>Checks whether a specific kernel command line option is <para>Checks whether a specific kernel command line option is set. See
set (or if prefixed with the exclamation mark unset). See
<literal>ConditionKernelCommandLine=</literal> in <literal>ConditionKernelCommandLine=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>KernelVersion=</varname></term> <term><varname>KernelVersion=</varname></term>
<listitem> <listitem>
<para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a certain <para>Checks whether the kernel version (as reported by <command>uname -r</command>) matches a
expression (or if prefixed with the exclamation mark does not match it). See certain expression. See <literal>ConditionKernelVersion=</literal> in
<literal>ConditionKernelVersion=</literal> in <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> for for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
details. If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Architecture=</varname></term> <term><varname>Architecture=</varname></term>
<listitem> <listitem>
<para>Checks whether the system is running on a specific <para>Checks whether the system is running on a specific architecture. See
architecture. See <literal>ConditionArchitecture=</literal> in <literal>ConditionArchitecture=</literal> in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. for details. When prefixed with an exclamation mark (<literal>!</literal>), the result is negated.
If an empty string is assigned, then previously assigned value is cleared.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1021,35 +1021,35 @@
<para><varname>ConditionArchitecture=</varname> may be used to <para><varname>ConditionArchitecture=</varname> may be used to
check whether the system is running on a specific check whether the system is running on a specific
architecture. Takes one of architecture. Takes one of
<varname>x86</varname>, <literal>x86</literal>,
<varname>x86-64</varname>, <literal>x86-64</literal>,
<varname>ppc</varname>, <literal>ppc</literal>,
<varname>ppc-le</varname>, <literal>ppc-le</literal>,
<varname>ppc64</varname>, <literal>ppc64</literal>,
<varname>ppc64-le</varname>, <literal>ppc64-le</literal>,
<varname>ia64</varname>, <literal>ia64</literal>,
<varname>parisc</varname>, <literal>parisc</literal>,
<varname>parisc64</varname>, <literal>parisc64</literal>,
<varname>s390</varname>, <literal>s390</literal>,
<varname>s390x</varname>, <literal>s390x</literal>,
<varname>sparc</varname>, <literal>sparc</literal>,
<varname>sparc64</varname>, <literal>sparc64</literal>,
<varname>mips</varname>, <literal>mips</literal>,
<varname>mips-le</varname>, <literal>mips-le</literal>,
<varname>mips64</varname>, <literal>mips64</literal>,
<varname>mips64-le</varname>, <literal>mips64-le</literal>,
<varname>alpha</varname>, <literal>alpha</literal>,
<varname>arm</varname>, <literal>arm</literal>,
<varname>arm-be</varname>, <literal>arm-be</literal>,
<varname>arm64</varname>, <literal>arm64</literal>,
<varname>arm64-be</varname>, <literal>arm64-be</literal>,
<varname>sh</varname>, <literal>sh</literal>,
<varname>sh64</varname>, <literal>sh64</literal>,
<varname>m68k</varname>, <literal>m68k</literal>,
<varname>tilegx</varname>, <literal>tilegx</literal>,
<varname>cris</varname>, <literal>cris</literal>,
<varname>arc</varname>, <literal>arc</literal>,
<varname>arc-be</varname> to test <literal>arc-be</literal> to test
against a specific architecture. The architecture is against a specific architecture. The architecture is
determined from the information returned by determined from the information returned by
<citerefentry project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry> <citerefentry project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
@ -1057,7 +1057,7 @@
<citerefentry><refentrytitle>personality</refentrytitle><manvolnum>2</manvolnum></citerefentry>. <citerefentry><refentrytitle>personality</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
Note that a <varname>Personality=</varname> setting in the Note that a <varname>Personality=</varname> setting in the
same unit file has no effect on this condition. A special same unit file has no effect on this condition. A special
architecture name <varname>native</varname> is mapped to the architecture name <literal>native</literal> is mapped to the
architecture the system manager itself is compiled for. The architecture the system manager itself is compiled for. The
test may be negated by prepending an exclamation mark.</para> test may be negated by prepending an exclamation mark.</para>
@ -1066,30 +1066,30 @@
environment and optionally test whether it is a specific environment and optionally test whether it is a specific
implementation. Takes either boolean value to check if being implementation. Takes either boolean value to check if being
executed in any virtualized environment, or one of executed in any virtualized environment, or one of
<varname>vm</varname> and <literal>vm</literal> and
<varname>container</varname> to test against a generic type of <literal>container</literal> to test against a generic type of
virtualization solution, or one of virtualization solution, or one of
<varname>qemu</varname>, <literal>qemu</literal>,
<varname>kvm</varname>, <literal>kvm</literal>,
<varname>zvm</varname>, <literal>zvm</literal>,
<varname>vmware</varname>, <literal>vmware</literal>,
<varname>microsoft</varname>, <literal>microsoft</literal>,
<varname>oracle</varname>, <literal>oracle</literal>,
<varname>xen</varname>, <literal>xen</literal>,
<varname>bochs</varname>, <literal>bochs</literal>,
<varname>uml</varname>, <literal>uml</literal>,
<varname>bhyve</varname>, <literal>bhyve</literal>,
<varname>qnx</varname>, <literal>qnx</literal>,
<varname>openvz</varname>, <literal>openvz</literal>,
<varname>lxc</varname>, <literal>lxc</literal>,
<varname>lxc-libvirt</varname>, <literal>lxc-libvirt</literal>,
<varname>systemd-nspawn</varname>, <literal>systemd-nspawn</literal>,
<varname>docker</varname>, <literal>docker</literal>,
<varname>rkt</varname>, <literal>rkt</literal>,
<varname>wsl</varname>, <literal>wsl</literal>,
<varname>acrn</varname> to test <literal>acrn</literal> to test
against a specific implementation, or against a specific implementation, or
<varname>private-users</varname> to check whether we are running in a user namespace. See <literal>private-users</literal> to check whether we are running in a user namespace. See
<citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
for a full list of known virtualization technologies and their for a full list of known virtualization technologies and their
identifiers. If multiple virtualization technologies are identifiers. If multiple virtualization technologies are
@ -1131,10 +1131,10 @@
<para><varname>ConditionSecurity=</varname> may be used to check <para><varname>ConditionSecurity=</varname> may be used to check
whether the given security technology is enabled on the whether the given security technology is enabled on the
system. Currently, the recognized values are system. Currently, the recognized values are
<varname>selinux</varname>, <varname>apparmor</varname>, <literal>selinux</literal>, <literal>apparmor</literal>,
<varname>tomoyo</varname>, <varname>ima</varname>, <literal>tomoyo</literal>, <literal>ima</literal>,
<varname>smack</varname>, <varname>audit</varname> and <literal>smack</literal>, <literal>audit</literal> and
<varname>uefi-secureboot</varname>. The test may be negated by <literal>uefi-secureboot</literal>. The test may be negated by
prepending an exclamation mark.</para> prepending an exclamation mark.</para>
<para><varname>ConditionCapability=</varname> may be used to <para><varname>ConditionCapability=</varname> may be used to
@ -1150,11 +1150,11 @@
<para><varname>ConditionACPower=</varname> may be used to <para><varname>ConditionACPower=</varname> may be used to
check whether the system has AC power, or is exclusively check whether the system has AC power, or is exclusively
battery powered at the time of activation of the unit. This battery powered at the time of activation of the unit. This
takes a boolean argument. If set to <varname>true</varname>, takes a boolean argument. If set to <literal>true</literal>,
the condition will hold only if at least one AC connector of the condition will hold only if at least one AC connector of
the system is connected to a power source, or if no AC the system is connected to a power source, or if no AC
connectors are known. Conversely, if set to connectors are known. Conversely, if set to
<varname>false</varname>, the condition will hold only if <literal>false</literal>, the condition will hold only if
there is at least one AC connector known and all AC connectors there is at least one AC connector known and all AC connectors
are disconnected from a power source.</para> are disconnected from a power source.</para>
@ -1244,16 +1244,16 @@
does not have a special value <literal>@system</literal>.</para> does not have a special value <literal>@system</literal>.</para>
<para><varname>ConditionControlGroupController=</varname> takes a <para><varname>ConditionControlGroupController=</varname> takes a
cgroup controller name (eg. <option>cpu</option>), verifying that it is cgroup controller name (eg. <literal>cpu</literal>), verifying that it is
available for use on the system. For example, a particular controller available for use on the system. For example, a particular controller
may not be available if it was disabled on the kernel command line with may not be available if it was disabled on the kernel command line with
<varname>cgroup_disable=controller</varname>. Multiple controllers may <varname>cgroup_disable=controller</varname>. Multiple controllers may
be passed with a space separating them; in this case the condition will be passed with a space separating them; in this case the condition will
only pass if all listed controllers are available for use. Controllers only pass if all listed controllers are available for use. Controllers
unknown to systemd are ignored. Valid controllers are unknown to systemd are ignored. Valid controllers are
<option>cpu</option>, <option>cpuacct</option>, <option>io</option>, <literal>cpu</literal>, <literal>cpuacct</literal>, <literal>io</literal>,
<option>blkio</option>, <option>memory</option>, <literal>blkio</literal>, <literal>memory</literal>,
<option>devices</option>, and <option>pids</option>.</para> <literal>devices</literal>, and <literal>pids</literal>.</para>
<para>If multiple conditions are specified, the unit will be <para>If multiple conditions are specified, the unit will be
executed if all of them apply (i.e. a logical AND is applied). executed if all of them apply (i.e. a logical AND is applied).

View File

@ -699,8 +699,7 @@ int log_internal_realm(
return r; return r;
} }
_printf_(10,0) int log_object_internalv(
static int log_object_internalv(
int level, int level,
int error, int error,
const char *file, const char *file,

View File

@ -115,6 +115,19 @@ int log_internalv_realm(
log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__) log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
/* Realm is fixed to LOG_REALM_SYSTEMD for those */ /* Realm is fixed to LOG_REALM_SYSTEMD for those */
int log_object_internalv(
int level,
int error,
const char *file,
int line,
const char *func,
const char *object_field,
const char *object,
const char *extra_field,
const char *extra,
const char *format,
va_list ap) _printf_(10,0);
int log_object_internal( int log_object_internal(
int level, int level,
int error, int error,

View File

@ -1589,55 +1589,32 @@ fail:
return log_unit_debug_errno(u, r, "Failed to load configuration: %m"); return log_unit_debug_errno(u, r, "Failed to load configuration: %m");
} }
static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to_string)(ConditionType t)) { _printf_(7, 8)
Condition *c; static int log_unit_internal(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) {
int triggered = -1; Unit *u = userdata;
va_list ap;
assert(u);
assert(to_string);
/* If the condition list is empty, then it is true */
if (!first)
return true;
/* Otherwise, if all of the non-trigger conditions apply and
* if any of the trigger conditions apply (unless there are
* none) we return true */
LIST_FOREACH(conditions, c, first) {
int r; int r;
r = condition_test(c); va_start(ap, format);
if (r < 0) if (u)
log_unit_warning(u, r = log_object_internalv(level, error, file, line, func,
"Couldn't determine result for %s=%s%s%s, assuming failed: %m", u->manager->unit_log_field,
to_string(c->type), u->id,
c->trigger ? "|" : "", u->manager->invocation_log_field,
c->negate ? "!" : "", u->invocation_id_string,
c->parameter); format, ap);
else else
log_unit_debug(u, r = log_internalv(level, error, file, line, func, format, ap);
"%s=%s%s%s %s.", va_end(ap);
to_string(c->type),
c->trigger ? "|" : "",
c->negate ? "!" : "",
c->parameter,
condition_result_to_string(c->result));
if (!c->trigger && r <= 0) return r;
return false;
if (c->trigger && triggered <= 0)
triggered = r > 0;
}
return triggered != 0;
} }
static bool unit_test_condition(Unit *u) { static bool unit_test_condition(Unit *u) {
assert(u); assert(u);
dual_timestamp_get(&u->condition_timestamp); dual_timestamp_get(&u->condition_timestamp);
u->condition_result = unit_condition_test_list(u, u->conditions, condition_type_to_string); u->condition_result = condition_test_list(u->conditions, condition_type_to_string, log_unit_internal, u);
unit_add_to_dbus_queue(u); unit_add_to_dbus_queue(u);
@ -1648,7 +1625,7 @@ static bool unit_test_assert(Unit *u) {
assert(u); assert(u);
dual_timestamp_get(&u->assert_timestamp); dual_timestamp_get(&u->assert_timestamp);
u->assert_result = unit_condition_test_list(u, u->asserts, assert_type_to_string); u->assert_result = condition_test_list(u->asserts, assert_type_to_string, log_unit_internal, u);
unit_add_to_dbus_queue(u); unit_add_to_dbus_queue(u);

View File

@ -100,32 +100,12 @@ bool net_match_config(Set *match_mac,
char * const *match_drivers, char * const *match_drivers,
char * const *match_types, char * const *match_types,
char * const *match_names, char * const *match_names,
Condition *match_host,
Condition *match_virt,
Condition *match_kernel_cmdline,
Condition *match_kernel_version,
Condition *match_arch,
const struct ether_addr *dev_mac, const struct ether_addr *dev_mac,
const char *dev_path, const char *dev_path,
const char *dev_driver, const char *dev_driver,
const char *dev_type, const char *dev_type,
const char *dev_name) { const char *dev_name) {
if (match_host && condition_test(match_host) <= 0)
return false;
if (match_virt && condition_test(match_virt) <= 0)
return false;
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)
return false;
if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac))) if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac)))
return false; return false;
@ -156,32 +136,31 @@ int config_parse_net_condition(const char *unit,
void *userdata) { void *userdata) {
ConditionType cond = ltype; ConditionType cond = ltype;
Condition **ret = data; Condition **list = data, *c;
bool negate; bool negate;
Condition *c;
_cleanup_free_ char *s = NULL;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(data); assert(data);
if (isempty(rvalue)) {
*list = condition_free_list_type(*list, cond);
return 0;
}
negate = rvalue[0] == '!'; negate = rvalue[0] == '!';
if (negate) if (negate)
rvalue++; rvalue++;
s = strdup(rvalue); c = condition_new(cond, rvalue, false, negate);
if (!s)
return log_oom();
c = condition_new(cond, s, false, negate);
if (!c) if (!c)
return log_oom(); return log_oom();
if (*ret) /* Drop previous assignment. */
condition_free(*ret); *list = condition_free_list_type(*list, cond);
*ret = c; LIST_PREPEND(conditions, *list, c);
return 0; return 0;
} }

View File

@ -6,7 +6,6 @@
#include "sd-device.h" #include "sd-device.h"
#include "sd-dhcp-lease.h" #include "sd-dhcp-lease.h"
#include "condition.h"
#include "conf-parser.h" #include "conf-parser.h"
#include "def.h" #include "def.h"
#include "set.h" #include "set.h"
@ -20,11 +19,6 @@ bool net_match_config(Set *match_mac,
char * const *match_driver, char * const *match_driver,
char * const *match_type, char * const *match_type,
char * const *match_name, char * const *match_name,
Condition *match_host,
Condition *match_virt,
Condition *match_kernel_cmdline,
Condition *match_kernel_version,
Condition *match_arch,
const struct ether_addr *dev_mac, const struct ether_addr *dev_mac,
const char *dev_path, const char *dev_path,
const char *dev_driver, const char *dev_driver,

View File

@ -34,11 +34,11 @@ struct ConfigPerfItem;
%struct-type %struct-type
%includes %includes
%% %%
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, match_host) Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(NetDev, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, match_virt) Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(NetDev, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, match_kernel_cmdline) Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(NetDev, conditions)
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(NetDev, match_kernel_version) Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(NetDev, conditions)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, match_arch) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(NetDev, conditions)
NetDev.Description, config_parse_string, 0, offsetof(NetDev, description) NetDev.Description, config_parse_string, 0, offsetof(NetDev, description)
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname) NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind) NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)

View File

@ -174,12 +174,7 @@ static NetDev *netdev_free(NetDev *netdev) {
free(netdev->description); free(netdev->description);
free(netdev->ifname); free(netdev->ifname);
free(netdev->mac); free(netdev->mac);
condition_free_list(netdev->conditions);
condition_free_list(netdev->match_host);
condition_free_list(netdev->match_virt);
condition_free_list(netdev->match_kernel_cmdline);
condition_free_list(netdev->match_kernel_version);
condition_free_list(netdev->match_arch);
/* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that /* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
* because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure * because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure
@ -683,11 +678,7 @@ int netdev_load_one(Manager *manager, const char *filename) {
return r; return r;
/* skip out early if configuration does not match the environment */ /* skip out early if configuration does not match the environment */
if (!net_match_config(NULL, NULL, NULL, NULL, NULL, if (!condition_test_list(netdev_raw->conditions, NULL, NULL, NULL)) {
netdev_raw->match_host, netdev_raw->match_virt,
netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version,
netdev_raw->match_arch,
NULL, NULL, NULL, NULL, NULL)) {
log_debug("%s: Conditions in the file do not match the system environment, skipping.", filename); log_debug("%s: Conditions in the file do not match the system environment, skipping.", filename);
return 0; return 0;
} }

View File

@ -81,11 +81,7 @@ typedef struct NetDev {
char *filename; char *filename;
Condition *match_host; Condition *conditions;
Condition *match_virt;
Condition *match_kernel_cmdline;
Condition *match_kernel_version;
Condition *match_arch;
NetDevState state; NetDevState state;
NetDevKind kind; NetDevKind kind;

View File

@ -25,11 +25,11 @@ Match.Path, config_parse_strv,
Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver) Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver)
Match.Type, config_parse_strv, 0, offsetof(Network, match_type) Match.Type, config_parse_strv, 0, offsetof(Network, match_type)
Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel_cmdline) Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, conditions)
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, match_kernel_version) Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, conditions)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, conditions)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu) Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu)
Link.ARP, config_parse_tristate, 0, offsetof(Network, arp) Link.ARP, config_parse_tristate, 0, offsetof(Network, arp)

View File

@ -174,10 +174,7 @@ int network_verify(Network *network) {
assert(network->filename); assert(network->filename);
/* skip out early if configuration does not match the environment */ /* skip out early if configuration does not match the environment */
if (!net_match_config(NULL, NULL, NULL, NULL, NULL, if (!condition_test_list(network->conditions, NULL, NULL, NULL))
network->match_host, network->match_virt, network->match_kernel_cmdline,
network->match_kernel_version, network->match_arch,
NULL, NULL, NULL, NULL, NULL))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Conditions in the file do not match the system environment, skipping.", "%s: Conditions in the file do not match the system environment, skipping.",
network->filename); network->filename);
@ -497,6 +494,7 @@ void network_free(Network *network) {
strv_free(network->match_driver); strv_free(network->match_driver);
strv_free(network->match_type); strv_free(network->match_type);
strv_free(network->match_name); strv_free(network->match_name);
condition_free_list(network->conditions);
free(network->description); free(network->description);
free(network->dhcp_vendor_class_identifier); free(network->dhcp_vendor_class_identifier);
@ -568,12 +566,6 @@ void network_free(Network *network) {
free(network->name); free(network->name);
condition_free_list(network->match_host);
condition_free_list(network->match_virt);
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); free(network->dhcp_server_timezone);
free(network->dhcp_server_dns); free(network->dhcp_server_dns);
free(network->dhcp_server_ntp); free(network->dhcp_server_ntp);
@ -619,9 +611,7 @@ int network_get(Manager *manager, sd_device *device,
LIST_FOREACH(networks, network, manager->networks) { LIST_FOREACH(networks, network, manager->networks) {
if (net_match_config(network->match_mac, network->match_path, if (net_match_config(network->match_mac, network->match_path,
network->match_driver, network->match_type, network->match_driver, network->match_type,
network->match_name, network->match_host, network->match_name,
network->match_virt, network->match_kernel_cmdline,
network->match_kernel_version, network->match_arch,
address, path, driver, devtype, ifname)) { address, path, driver, devtype, ifname)) {
if (network->match_name && device) { if (network->match_name && device) {
const char *attr; const char *attr;

View File

@ -97,12 +97,7 @@ struct Network {
char **match_driver; char **match_driver;
char **match_type; char **match_type;
char **match_name; char **match_name;
Condition *conditions;
Condition *match_host;
Condition *match_virt;
Condition *match_kernel_cmdline;
Condition *match_kernel_version;
Condition *match_arch;
char *description; char *description;

View File

@ -77,13 +77,17 @@ void condition_free(Condition *c) {
free(c); free(c);
} }
Condition* condition_free_list(Condition *first) { Condition* condition_free_list_type(Condition *first, ConditionType type) {
Condition *c, *n; Condition *c, *n, *r = NULL;
LIST_FOREACH_SAFE(conditions, c, n, first) LIST_FOREACH_SAFE(conditions, c, n, first)
if (type < 0 || c->type == type)
condition_free(c); condition_free(c);
else if (!r)
r = c;
return NULL; assert(type >= 0 || !r);
return r;
} }
static int condition_test_kernel_command_line(Condition *c) { static int condition_test_kernel_command_line(Condition *c) {
@ -644,6 +648,52 @@ int condition_test(Condition *c) {
return b; return b;
} }
bool condition_test_list(Condition *first, const char *(*to_string)(ConditionType t), condition_test_logger_t logger, void *userdata) {
Condition *c;
int triggered = -1;
assert(!!logger == !!to_string);
/* If the condition list is empty, then it is true */
if (!first)
return true;
/* Otherwise, if all of the non-trigger conditions apply and
* if any of the trigger conditions apply (unless there are
* none) we return true */
LIST_FOREACH(conditions, c, first) {
int r;
r = condition_test(c);
if (logger) {
if (r < 0)
logger(userdata, LOG_WARNING, r, __FILE__, __LINE__, __func__,
"Couldn't determine result for %s=%s%s%s, assuming failed: %m",
to_string(c->type),
c->trigger ? "|" : "",
c->negate ? "!" : "",
c->parameter);
else
logger(userdata, LOG_DEBUG, 0, __FILE__, __LINE__, __func__,
"%s=%s%s%s %s.",
to_string(c->type),
c->trigger ? "|" : "",
c->negate ? "!" : "",
c->parameter,
condition_result_to_string(c->result));
}
if (!c->trigger && r <= 0)
return false;
if (c->trigger && triggered <= 0)
triggered = r > 0;
}
return triggered != 0;
}
void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) { void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)) {
assert(c); assert(c);
assert(f); assert(f);

View File

@ -65,9 +65,14 @@ typedef struct Condition {
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate); Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate);
void condition_free(Condition *c); void condition_free(Condition *c);
Condition* condition_free_list(Condition *c); Condition* condition_free_list_type(Condition *first, ConditionType type);
static inline Condition* condition_free_list(Condition *first) {
return condition_free_list_type(first, _CONDITION_TYPE_INVALID);
}
int condition_test(Condition *c); int condition_test(Condition *c);
typedef int (*condition_test_logger_t)(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) _printf_(7, 8);
bool condition_test_list(Condition *first, const char *(*to_string)(ConditionType t), condition_test_logger_t logger, void *userdata);
void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)); void condition_dump(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));
void condition_dump_list(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t)); void condition_dump_list(Condition *c, FILE *f, const char *prefix, const char *(*to_string)(ConditionType t));

View File

@ -24,11 +24,11 @@ Match.OriginalName, config_parse_ifnames, 0,
Match.Path, config_parse_strv, 0, offsetof(link_config, match_path) Match.Path, config_parse_strv, 0, offsetof(link_config, match_path)
Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver) Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver)
Match.Type, config_parse_strv, 0, offsetof(link_config, match_type) 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.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, match_virt) Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel_cmdline) Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, conditions)
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, match_kernel_version) Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, conditions)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, match_arch) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, conditions)
Link.Description, config_parse_string, 0, offsetof(link_config, description) Link.Description, config_parse_string, 0, offsetof(link_config, description)
Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy) Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac) Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)

View File

@ -51,12 +51,7 @@ static void link_config_free(link_config *link) {
strv_free(link->match_driver); strv_free(link->match_driver);
strv_free(link->match_type); strv_free(link->match_type);
strv_free(link->match_name); strv_free(link->match_name);
condition_free_list(link->conditions);
condition_free_list(link->match_host);
condition_free_list(link->match_virt);
condition_free_list(link->match_kernel_cmdline);
condition_free_list(link->match_kernel_version);
condition_free_list(link->match_arch);
free(link->description); free(link->description);
free(link->mac); free(link->mac);
@ -164,10 +159,7 @@ int link_load_one(link_config_ctx *ctx, const char *filename) {
if (link->speed > UINT_MAX) if (link->speed > UINT_MAX)
return -ERANGE; return -ERANGE;
if (!net_match_config(NULL, NULL, NULL, NULL, NULL, if (!condition_test_list(link->conditions, NULL, NULL, NULL)) {
link->match_host, link->match_virt, link->match_kernel_cmdline,
link->match_kernel_version, link->match_arch,
NULL, NULL, NULL, NULL, NULL)) {
log_debug("%s: Conditions do not match the system environment, skipping.", filename); log_debug("%s: Conditions do not match the system environment, skipping.", filename);
return 0; return 0;
} }
@ -251,9 +243,7 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
(void) sd_device_get_sysname(device, &sysname); (void) sd_device_get_sysname(device, &sysname);
if (net_match_config(link->match_mac, link->match_path, link->match_driver, if (net_match_config(link->match_mac, link->match_path, link->match_driver,
link->match_type, link->match_name, link->match_host, link->match_type, link->match_name,
link->match_virt, link->match_kernel_cmdline,
link->match_kernel_version, link->match_arch,
address ? ether_aton(address) : NULL, address ? ether_aton(address) : NULL,
id_path, id_path,
id_net_driver, id_net_driver,

View File

@ -40,11 +40,7 @@ struct link_config {
char **match_driver; char **match_driver;
char **match_type; char **match_type;
char **match_name; char **match_name;
Condition *match_host; Condition *conditions;
Condition *match_virt;
Condition *match_kernel_cmdline;
Condition *match_kernel_version;
Condition *match_arch;
char *description; char *description;
struct ether_addr *mac; struct ether_addr *mac;