chiark / gitweb /
unit: distuingish mandatory from triggering conditions
authorLennart Poettering <lennart@poettering.net>
Tue, 8 Mar 2011 02:04:47 +0000 (03:04 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 8 Mar 2011 02:04:47 +0000 (03:04 +0100)
TODO
man/systemd.unit.xml
src/condition.c
src/condition.h
src/load-fragment.c
units/systemd-sysctl.service.in

diff --git a/TODO b/TODO
index 0a2f7619f606f3bb07749af23d1a0b151fac6e3a..cad97746ef4afa559c70df0c90717b25c8efe9fc 100644 (file)
--- a/TODO
+++ b/TODO
@@ -14,8 +14,6 @@ F15:
 
 * hook emergency.target into local-fs.target in some way as OnFailure with isolate
 
 
 * 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
 * mount /dev/.run and /var/run as bind mounts
 
 * Make use of UnknownInterface, UnknownObject
index fa8821afe5a7c94b19578666511841f88dd4ec45..54903fb52fca93eb43e4ac0cb75e0c3df99c1284 100644 (file)
                                 environment and optionally test
                                 whether it is a specific
                                 implementation. Takes either boolean
                                 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>,
                                 <varname>qemu</varname>,
                                 <varname>kvm</varname>,
                                 <varname>vmware</varname>,
                                 will always fail, otherwise
                                 succeed. If multiple conditions are
                                 specified the unit will be executed if
                                 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>
 
                         </varlistentry>
                 </variablelist>
 
index 630350ed365ea818b4ac0806bfb3cb8940322746..1d6cf12ad4b71c46086d5791cd45d5bebd4d4de0 100644 (file)
 #include "util.h"
 #include "condition.h"
 
 #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;
         Condition *c;
 
         c = new0(Condition, 1);
         c->type = type;
+        c->trigger = trigger;
         c->negate = negate;
 
         if (parameter)
         c->negate = negate;
 
         if (parameter)
@@ -153,17 +154,28 @@ bool condition_test(Condition *c) {
 
 bool condition_test_list(Condition *first) {
         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;
 
 
         /* 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 false;
+        return triggered != 0;
 }
 
 void condition_dump(Condition *c, FILE *f, const char *prefix) {
 }
 
 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,
                 prefix = "";
 
         fprintf(f,
-                "%s%s: %s%s\n",
+                "%s%s: %s%s%s\n",
                 prefix,
                 condition_type_to_string(c->type),
                 prefix,
                 condition_type_to_string(c->type),
+                c->trigger ? "|" : "",
                 c->negate ? "!" : "",
                 c->parameter);
 }
                 c->negate ? "!" : "",
                 c->parameter);
 }
index f4903d76d98ce5a36e37b7114a7b0e89215c748e..0ce713bc16f14bf498ee799c48e8d5ecea238562 100644 (file)
@@ -39,12 +39,14 @@ typedef enum ConditionType {
 typedef struct Condition {
         ConditionType type;
         char *parameter;
 typedef struct Condition {
         ConditionType type;
         char *parameter;
-        bool negate;
+
+        bool trigger:1;
+        bool negate:1;
 
         LIST_FIELDS(struct Condition, conditions);
 } Condition;
 
 
         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);
 
 void condition_free(Condition *c);
 void condition_free_list(Condition *c);
 
index bd7529ff950461f59e184c02b822437a4e3cce38..334bc713be8f691bcb65ba7ebf93d2ef31e5aab5 100644 (file)
@@ -1397,7 +1397,7 @@ static int config_parse_condition_path(
                 void *userdata) {
 
         Unit *u = data;
                 void *userdata) {
 
         Unit *u = data;
-        bool negate;
+        bool trigger, negate;
         Condition *c;
 
         assert(filename);
         Condition *c;
 
         assert(filename);
@@ -1405,6 +1405,9 @@ static int config_parse_condition_path(
         assert(rvalue);
         assert(data);
 
         assert(rvalue);
         assert(data);
 
+        if ((trigger = rvalue[0] == '|'))
+                rvalue++;
+
         if ((negate = 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,
         }
 
         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);
                 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;
                 void *userdata) {
 
         Unit *u = data;
-        bool negate;
+        bool trigger, negate;
         Condition *c;
 
         assert(filename);
         Condition *c;
 
         assert(filename);
@@ -1439,10 +1442,13 @@ static int config_parse_condition_kernel(
         assert(rvalue);
         assert(data);
 
         assert(rvalue);
         assert(data);
 
+        if ((trigger = rvalue[0] == '|'))
+                rvalue++;
+
         if ((negate = 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);
                 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;
                 void *userdata) {
 
         Unit *u = data;
-        bool negate;
+        bool trigger, negate;
         Condition *c;
 
         assert(filename);
         Condition *c;
 
         assert(filename);
@@ -1467,10 +1473,13 @@ static int config_parse_condition_virt(
         assert(rvalue);
         assert(data);
 
         assert(rvalue);
         assert(data);
 
+        if ((trigger = rvalue[0] == '|'))
+                rvalue++;
+
         if ((negate = 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);
                 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;
 
         Unit *u = data;
         Condition *c;
-        bool negate;
+        bool trigger, negate;
         int b;
 
         assert(filename);
         int b;
 
         assert(filename);
@@ -1496,6 +1505,9 @@ static int config_parse_condition_null(
         assert(rvalue);
         assert(data);
 
         assert(rvalue);
         assert(data);
 
+        if ((trigger = rvalue[0] == '|'))
+                rvalue++;
+
         if ((negate = rvalue[0] == '!'))
                 rvalue++;
 
         if ((negate = rvalue[0] == '!'))
                 rvalue++;
 
@@ -1507,7 +1519,7 @@ static int config_parse_condition_null(
         if (!b)
                 negate = !negate;
 
         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);
                 return -ENOMEM;
 
         LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
index ada447885fe72f2cf94f4f9adc3f666b23157bee..ea78230d7c0d04a123ec792840dad65985db1484 100644 (file)
@@ -11,8 +11,8 @@ DefaultDependencies=no
 Conflicts=shutdown.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service
 Before=sysinit.target shutdown.target
 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
 
 [Service]
 Type=oneshot