summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.unit.xml27
-rw-r--r--src/condition.c15
-rw-r--r--src/condition.h1
-rw-r--r--src/load-fragment.c41
4 files changed, 69 insertions, 15 deletions
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 4e1d9f3070..39862cf7c8 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -574,6 +574,7 @@
<varlistentry>
<term><varname>ConditionPathExists=</varname></term>
<term><varname>ConditionKernelCommandLine=</varname></term>
+ <term><varname>ConditionNull=</varname></term>
<listitem><para>Before starting a unit
verify that the specified condition is
@@ -602,15 +603,23 @@
must either be a single word, or an
assignment (i.e. two words, seperated
by the equality sign). In the former
- case the kernel command line is search
- for the word appearing as is, or as
- left hand side of an assignment. In
- the latter case the exact assignment
- is looked for with right and left hand
- side matching. If multiple conditions
- are specified the unit will be
- executed iff at least one of them
- applies (i.e. a logical OR is
+ case the kernel command line is
+ searched for the word appearing as is,
+ or as left hand side of an
+ assignment. In the latter case the
+ exact assignment is looked for with
+ right and left hand side
+ matching. Finally,
+ <varname>ConditionNull=</varname> may
+ be used to add a constant condition
+ check value to the unit. It takes a
+ boolean argument. If set to
+ <varname>false</varname> the condition
+ will always fail, otherwise
+ succeed. If multiple conditions are
+ specified the unit will be executed
+ iff 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 1e69b610ff..4bbd4dbafa 100644
--- a/src/condition.c
+++ b/src/condition.c
@@ -34,10 +34,11 @@ Condition* condition_new(ConditionType type, const char *parameter, bool negate)
c->type = type;
c->negate = negate;
- if (!(c->parameter = strdup(parameter))) {
- free(c);
- return NULL;
- }
+ if (parameter)
+ if (!(c->parameter = strdup(parameter))) {
+ free(c);
+ return NULL;
+ }
return c;
}
@@ -108,6 +109,9 @@ bool condition_test(Condition *c) {
case CONDITION_KERNEL_COMMAND_LINE:
return !!test_kernel_command_line(c->parameter) == !c->negate;
+ case CONDITION_NULL:
+ return !c->negate;
+
default:
assert_not_reached("Invalid condition type.");
}
@@ -152,7 +156,8 @@ void condition_dump_list(Condition *first, FILE *f, const char *prefix) {
static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
[CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
- [CONDITION_PATH_EXISTS] = "ConditionPathExists"
+ [CONDITION_PATH_EXISTS] = "ConditionPathExists",
+ [CONDITION_NULL] = "ConditionNull"
};
DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType);
diff --git a/src/condition.h b/src/condition.h
index 4e0d63cd51..b9d3f34aef 100644
--- a/src/condition.h
+++ b/src/condition.h
@@ -29,6 +29,7 @@
typedef enum ConditionType {
CONDITION_PATH_EXISTS,
CONDITION_KERNEL_COMMAND_LINE,
+ CONDITION_NULL,
_CONDITION_TYPE_MAX,
_CONDITION_TYPE_INVALID = -1
} ConditionType;
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 4f94c6409e..424e6c37bb 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1444,7 +1444,7 @@ static int config_parse_condition_path(
rvalue++;
if (!path_is_absolute(rvalue)) {
- log_error("[%s:%u] Path in condition not absolute: %s", filename, line, rvalue);
+ log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue);
return 0;
}
@@ -1483,6 +1483,43 @@ static int config_parse_condition_kernel(
return 0;
}
+static int config_parse_condition_null(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Unit *u = data;
+ Condition *c;
+ bool negate;
+ int b;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if ((negate = rvalue[0] == '!'))
+ rvalue++;
+
+ if ((b = parse_boolean(rvalue)) < 0) {
+ log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+ if (!b)
+ negate = !negate;
+
+ if (!(c = condition_new(CONDITION_NULL, NULL, negate)))
+ return -ENOMEM;
+
+ LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
+ return 0;
+}
+
static DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
#define FOLLOW_MAX 8
@@ -1656,6 +1693,7 @@ static void dump_items(FILE *f, const ConfigItem *items) {
{ config_parse_ip_tos, "TOS" },
{ config_parse_condition_path, "CONDITION" },
{ config_parse_condition_kernel, "CONDITION" },
+ { config_parse_condition_null, "CONDITION" },
};
assert(f);
@@ -1778,6 +1816,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "JobTimeoutSec", config_parse_usec, &u->meta.job_timeout, "Unit" },
{ "ConditionPathExists", config_parse_condition_path, u, "Unit" },
{ "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" },
+ { "ConditionNull", config_parse_condition_null, u, "Unit" },
{ "PIDFile", config_parse_path, &u->service.pid_file, "Service" },
{ "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" },