Commit 039655a4 authored by Lennart Poettering's avatar Lennart Poettering

unit: introduce ConditionVirtualization=

parent 07faed4f
......@@ -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>
......
......@@ -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;
......
......@@ -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
......
......@@ -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" },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment