chiark / gitweb /
unit: add ConditionNull= condition
authorLennart Poettering <lennart@poettering.net>
Wed, 10 Nov 2010 21:28:19 +0000 (22:28 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 10 Nov 2010 21:39:18 +0000 (22:39 +0100)
man/systemd.unit.xml
src/condition.c
src/condition.h
src/load-fragment.c

index 4e1d9f30700bf8ae2805087f035003ea654fa1a7..39862cf7c89162e510f1bb35eb820c1aa47f5851 100644 (file)
                         <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
                                 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>
index 1e69b610ff3e1b2cebffd18b56e6b84605442f3b..4bbd4dbafaecfe1f53b11133db75255dfd297e76 100644 (file)
@@ -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);
index 4e0d63cd515236f1e3fc526d3293ccea1b77e46f..b9d3f34aefb07642f5f92e1ac57a5241abd3589e 100644 (file)
@@ -29,6 +29,7 @@
 typedef enum ConditionType {
         CONDITION_PATH_EXISTS,
         CONDITION_KERNEL_COMMAND_LINE,
+        CONDITION_NULL,
         _CONDITION_TYPE_MAX,
         _CONDITION_TYPE_INVALID = -1
 } ConditionType;
index 4f94c6409e59e89ff602b9d942294ef697b507da..424e6c37bb9d8d6e82572d986713a407ae04eec5 100644 (file)
@@ -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" },