diff options
-rw-r--r-- | man/systemd.unit.xml | 26 | ||||
-rw-r--r-- | src/condition.c | 27 | ||||
-rw-r--r-- | src/condition.h | 1 | ||||
-rw-r--r-- | src/load-fragment.c | 30 |
4 files changed, 80 insertions, 4 deletions
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 14ec4561b2..fa8821afe5 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -575,6 +575,7 @@ <term><varname>ConditionPathExists=</varname></term> <term><varname>ConditionDirectoryNotEmpty=</varname></term> <term><varname>ConditionKernelCommandLine=</varname></term> + <term><varname>ConditionVirtualization=</varname></term> <term><varname>ConditionNull=</varname></term> <listitem><para>Before starting a unit @@ -615,7 +616,24 @@ assignment. In the latter case the exact assignment is looked for with right and left hand side - matching. Finally, + matching. <varname>ConditionVirtualization=</varname> + may be used to check whether the + system is executed in a virtualized + environment and optionally test + whether it is a specific + implementation. Takes either boolean + value to check if being executed in any + virtual environment or one of the + <varname>qemu</varname>, + <varname>kvm</varname>, + <varname>vmware</varname>, + <varname>microsoft</varname>, + <varname>oracle</varname>, + <varname>xen</varname>, + <varname>openvz</varname> to test + against a specific implementation. The + test may be negated by prepending an + exclamation mark. Finally, <varname>ConditionNull=</varname> may be used to add a constant condition check value to the unit. It takes a @@ -623,9 +641,9 @@ <varname>false</varname> the condition will always fail, otherwise succeed. If multiple conditions are - specified the unit will be executed - if at least one of them applies - (i.e. a logical OR is + specified the unit will be executed if + at least one of them applies (i.e. a + logical OR is applied).</para></listitem> </varlistentry> </variablelist> diff --git a/src/condition.c b/src/condition.c index 21da2eb9e9..3ab4d4e225 100644 --- a/src/condition.c +++ b/src/condition.c @@ -64,6 +64,8 @@ static bool test_kernel_command_line(const char *parameter) { size_t l, pl; bool found = false; + assert(parameter); + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); return false; @@ -98,6 +100,28 @@ static bool test_kernel_command_line(const char *parameter) { return found; } +static bool test_virtualization(const char *parameter) { + int r, b; + const char *id; + + assert(parameter); + + if ((r = detect_virtualization(&id)) < 0) { + log_warning("Failed to detect virtualization, ignoring: %s", strerror(-r)); + return false; + } + + b = parse_boolean(parameter); + + if (r > 0 && b > 0) + return true; + + if (r == 0 && b == 0) + return true; + + return streq(parameter, id); +} + bool condition_test(Condition *c) { assert(c); @@ -116,6 +140,9 @@ bool condition_test(Condition *c) { case CONDITION_KERNEL_COMMAND_LINE: return !!test_kernel_command_line(c->parameter) == !c->negate; + case CONDITION_VIRTUALIZATION: + return !!test_virtualization(c->parameter) == !c->negate; + case CONDITION_NULL: return !c->negate; diff --git a/src/condition.h b/src/condition.h index 2f2689cc6d..f4903d76d9 100644 --- a/src/condition.h +++ b/src/condition.h @@ -30,6 +30,7 @@ typedef enum ConditionType { CONDITION_PATH_EXISTS, CONDITION_DIRECTORY_NOT_EMPTY, CONDITION_KERNEL_COMMAND_LINE, + CONDITION_VIRTUALIZATION, CONDITION_NULL, _CONDITION_TYPE_MAX, _CONDITION_TYPE_INVALID = -1 diff --git a/src/load-fragment.c b/src/load-fragment.c index eaeaadaea4..2e67eccc00 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1503,6 +1503,34 @@ static int config_parse_condition_kernel( return 0; } +static int config_parse_condition_virt( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + bool negate; + Condition *c; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((negate = rvalue[0] == '!')) + rvalue++; + + if (!(c = condition_new(CONDITION_VIRTUALIZATION, rvalue, negate))) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->meta.conditions, c); + return 0; +} + static int config_parse_condition_null( const char *filename, unsigned line, @@ -1714,6 +1742,7 @@ static void dump_items(FILE *f, const ConfigItem *items) { { config_parse_condition_path, "CONDITION" }, { config_parse_condition_kernel, "CONDITION" }, { config_parse_condition_null, "CONDITION" }, + { config_parse_condition_virt, "CONDITION" }, }; assert(f); @@ -1838,6 +1867,7 @@ static int load_from_path(Unit *u, const char *path) { { "ConditionPathExists", config_parse_condition_path, u, "Unit" }, { "ConditionDirectoryNotEmpty", config_parse_condition_path, u, "Unit" }, { "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" }, + { "ConditionVirtualization",config_parse_condition_virt, u, "Unit" }, { "ConditionNull", config_parse_condition_null, u, "Unit" }, { "PIDFile", config_parse_path, &u->service.pid_file, "Service" }, |