mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
unit: distuingish mandatory from triggering conditions
This commit is contained in:
parent
08672cb507
commit
267632f0ab
2
TODO
2
TODO
@ -14,8 +14,6 @@ F15:
|
||||
|
||||
* hook emergency.target into local-fs.target in some way as OnFailure with isolate
|
||||
|
||||
* introduce simple way to do mandatory conditions (make current conditions mandatory, and introduce =| as non-mandatory conditions)
|
||||
|
||||
* mount /dev/.run and /var/run as bind mounts
|
||||
|
||||
* Make use of UnknownInterface, UnknownObject
|
||||
|
@ -622,8 +622,8 @@
|
||||
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
|
||||
value to check if being executed in
|
||||
any virtual environment or one of the
|
||||
<varname>qemu</varname>,
|
||||
<varname>kvm</varname>,
|
||||
<varname>vmware</varname>,
|
||||
@ -642,9 +642,20 @@
|
||||
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
|
||||
applied).</para></listitem>
|
||||
all of them apply (i.e. a logical AND
|
||||
is applied). Condition checks can be
|
||||
prefixed with a pipe symbol (|) in
|
||||
which case a condition becomes a
|
||||
triggering condition. If at least one
|
||||
triggering condition is defined for a
|
||||
unit then the unit will be executed if
|
||||
at least one of the triggering
|
||||
conditions apply and all of the
|
||||
non-triggering conditions. If you
|
||||
prefix an argument with the pipe
|
||||
symbol and an exclamation mark the
|
||||
pipe symbol must be passed first, the
|
||||
exclamation second.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
|
@ -27,11 +27,12 @@
|
||||
#include "util.h"
|
||||
#include "condition.h"
|
||||
|
||||
Condition* condition_new(ConditionType type, const char *parameter, bool negate) {
|
||||
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
|
||||
Condition *c;
|
||||
|
||||
c = new0(Condition, 1);
|
||||
c->type = type;
|
||||
c->trigger = trigger;
|
||||
c->negate = negate;
|
||||
|
||||
if (parameter)
|
||||
@ -153,17 +154,28 @@ bool condition_test(Condition *c) {
|
||||
|
||||
bool condition_test_list(Condition *first) {
|
||||
Condition *c;
|
||||
int triggered = -1;
|
||||
|
||||
/* If the condition list is empty, then it is true */
|
||||
if (!first)
|
||||
return true;
|
||||
|
||||
/* Otherwise, if any of the conditions apply we return true */
|
||||
LIST_FOREACH(conditions, c, first)
|
||||
if (condition_test(c))
|
||||
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) {
|
||||
bool b;
|
||||
|
||||
b = condition_test(c);
|
||||
|
||||
if (!c->trigger && !b)
|
||||
return false;
|
||||
|
||||
if (c->trigger && triggered <= 0)
|
||||
triggered = b;
|
||||
}
|
||||
|
||||
return triggered != 0;
|
||||
}
|
||||
|
||||
void condition_dump(Condition *c, FILE *f, const char *prefix) {
|
||||
@ -174,9 +186,10 @@ void condition_dump(Condition *c, FILE *f, const char *prefix) {
|
||||
prefix = "";
|
||||
|
||||
fprintf(f,
|
||||
"%s%s: %s%s\n",
|
||||
"%s%s: %s%s%s\n",
|
||||
prefix,
|
||||
condition_type_to_string(c->type),
|
||||
c->trigger ? "|" : "",
|
||||
c->negate ? "!" : "",
|
||||
c->parameter);
|
||||
}
|
||||
|
@ -39,12 +39,14 @@ typedef enum ConditionType {
|
||||
typedef struct Condition {
|
||||
ConditionType type;
|
||||
char *parameter;
|
||||
bool negate;
|
||||
|
||||
bool trigger:1;
|
||||
bool negate:1;
|
||||
|
||||
LIST_FIELDS(struct Condition, conditions);
|
||||
} Condition;
|
||||
|
||||
Condition* condition_new(ConditionType type, const char *parameter, bool negate);
|
||||
Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate);
|
||||
void condition_free(Condition *c);
|
||||
void condition_free_list(Condition *c);
|
||||
|
||||
|
@ -1397,7 +1397,7 @@ static int config_parse_condition_path(
|
||||
void *userdata) {
|
||||
|
||||
Unit *u = data;
|
||||
bool negate;
|
||||
bool trigger, negate;
|
||||
Condition *c;
|
||||
|
||||
assert(filename);
|
||||
@ -1405,6 +1405,9 @@ static int config_parse_condition_path(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if ((trigger = rvalue[0] == '|'))
|
||||
rvalue++;
|
||||
|
||||
if ((negate = rvalue[0] == '!'))
|
||||
rvalue++;
|
||||
|
||||
@ -1414,7 +1417,7 @@ static int config_parse_condition_path(
|
||||
}
|
||||
|
||||
if (!(c = condition_new(streq(lvalue, "ConditionPathExists") ? CONDITION_PATH_EXISTS : CONDITION_DIRECTORY_NOT_EMPTY,
|
||||
rvalue, negate)))
|
||||
rvalue, trigger, negate)))
|
||||
return -ENOMEM;
|
||||
|
||||
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
|
||||
@ -1431,7 +1434,7 @@ static int config_parse_condition_kernel(
|
||||
void *userdata) {
|
||||
|
||||
Unit *u = data;
|
||||
bool negate;
|
||||
bool trigger, negate;
|
||||
Condition *c;
|
||||
|
||||
assert(filename);
|
||||
@ -1439,10 +1442,13 @@ static int config_parse_condition_kernel(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if ((trigger = rvalue[0] == '|'))
|
||||
rvalue++;
|
||||
|
||||
if ((negate = rvalue[0] == '!'))
|
||||
rvalue++;
|
||||
|
||||
if (!(c = condition_new(CONDITION_KERNEL_COMMAND_LINE, rvalue, negate)))
|
||||
if (!(c = condition_new(CONDITION_KERNEL_COMMAND_LINE, rvalue, trigger, negate)))
|
||||
return -ENOMEM;
|
||||
|
||||
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
|
||||
@ -1459,7 +1465,7 @@ static int config_parse_condition_virt(
|
||||
void *userdata) {
|
||||
|
||||
Unit *u = data;
|
||||
bool negate;
|
||||
bool trigger, negate;
|
||||
Condition *c;
|
||||
|
||||
assert(filename);
|
||||
@ -1467,10 +1473,13 @@ static int config_parse_condition_virt(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if ((trigger = rvalue[0] == '|'))
|
||||
rvalue++;
|
||||
|
||||
if ((negate = rvalue[0] == '!'))
|
||||
rvalue++;
|
||||
|
||||
if (!(c = condition_new(CONDITION_VIRTUALIZATION, rvalue, negate)))
|
||||
if (!(c = condition_new(CONDITION_VIRTUALIZATION, rvalue, trigger, negate)))
|
||||
return -ENOMEM;
|
||||
|
||||
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
|
||||
@ -1488,7 +1497,7 @@ static int config_parse_condition_null(
|
||||
|
||||
Unit *u = data;
|
||||
Condition *c;
|
||||
bool negate;
|
||||
bool trigger, negate;
|
||||
int b;
|
||||
|
||||
assert(filename);
|
||||
@ -1496,6 +1505,9 @@ static int config_parse_condition_null(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if ((trigger = rvalue[0] == '|'))
|
||||
rvalue++;
|
||||
|
||||
if ((negate = rvalue[0] == '!'))
|
||||
rvalue++;
|
||||
|
||||
@ -1507,7 +1519,7 @@ static int config_parse_condition_null(
|
||||
if (!b)
|
||||
negate = !negate;
|
||||
|
||||
if (!(c = condition_new(CONDITION_NULL, NULL, negate)))
|
||||
if (!(c = condition_new(CONDITION_NULL, NULL, trigger, negate)))
|
||||
return -ENOMEM;
|
||||
|
||||
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
|
||||
|
@ -11,8 +11,8 @@ DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
After=systemd-readahead-collect.service systemd-readahead-replay.service
|
||||
Before=sysinit.target shutdown.target
|
||||
ConditionPathExists=/etc/sysctl.conf
|
||||
ConditionDirectoryNotEmpty=/etc/sysctl.d
|
||||
ConditionPathExists=|/etc/sysctl.conf
|
||||
ConditionDirectoryNotEmpty=|/etc/sysctl.d
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
Loading…
Reference in New Issue
Block a user