From: Lennart Poettering Date: Mon, 21 Feb 2011 21:07:55 +0000 (+0100) Subject: unit: introduce ConditionVirtualization= X-Git-Tag: v19~39 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=039655a40c77f88e4f9ccc00824f2f483f22f2c1;p=systemd unit: introduce ConditionVirtualization= --- diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 14ec4561..fa8821af 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -575,6 +575,7 @@ ConditionPathExists= ConditionDirectoryNotEmpty= ConditionKernelCommandLine= + ConditionVirtualization= ConditionNull= 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. ConditionVirtualization= + 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 + qemu, + kvm, + vmware, + microsoft, + oracle, + xen, + openvz to test + against a specific implementation. The + test may be negated by prepending an + exclamation mark. Finally, ConditionNull= may be used to add a constant condition check value to the unit. It takes a @@ -623,9 +641,9 @@ false 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). diff --git a/src/condition.c b/src/condition.c index 21da2eb9..3ab4d4e2 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 2f2689cc..f4903d76 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 eaeaadae..2e67eccc 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" },