Add ability to test if given file contains specified value. File and expected value are given as one argument separated by colon (":"), i.e.
ConditionFileContains=/sys/module/sn/parameters/enabled:1 --- As above example suggests we use it to conditionally start service based on kernel module parameter value. This can be (ab)used for other/regular files too. RFC Thanks! --- man/systemd.unit.xml | 8 ++++++++ src/core/condition.c | 34 +++++++++++++++++++++++++++++++++ src/core/condition.h | 1 + src/core/load-fragment-gperf.gperf.m4 | 1 + 4 files changed, 44 insertions(+) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 4f0bd64..d26bd23 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -841,6 +841,7 @@ <term><varname>ConditionDirectoryNotEmpty=</varname></term> <term><varname>ConditionFileNotEmpty=</varname></term> <term><varname>ConditionFileIsExecutable=</varname></term> + <term><varname>ConditionFileContains=</varname></term> <term><varname>ConditionKernelCommandLine=</varname></term> <term><varname>ConditionVirtualization=</varname></term> <term><varname>ConditionSecurity=</varname></term> @@ -932,6 +933,13 @@ exists, is a regular file and marked executable.</para> + <para><varname>ConditionFileContains=</varname> + may be used to check whether a given + file contains specified value. The + argument consists of file path to be + tested, separator (":"), and the + expected value.</para> + <para>Similar, <varname>ConditionKernelCommandLine=</varname> may be used to check whether a diff --git a/src/core/condition.c b/src/core/condition.c index 427aa08..7c62d11 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -124,6 +124,36 @@ static bool test_kernel_command_line(const char *parameter) { return found; } +static bool test_file_contains(const char *parameter) { + int r; + char *p; + _cleanup_free_ char *path = NULL; + _cleanup_free_ char *line = NULL; + + assert(parameter); + + path = strdup(parameter); + if (!path) { + log_oom(); + return false; + } + + p = strchr(path, ':'); + if (!p) + return false; + + *(p++) = '\0'; + + r = read_one_line_file(path, &line); + + if (r < 0) { + log_warning("Failed to read %s, ignoring: %s", path, strerror(-r)); + return false; + } + + return !!streq(line, p); +} + static bool test_virtualization(const char *parameter) { int b; Virtualization v; @@ -307,6 +337,9 @@ bool condition_test(Condition *c) { return (S_ISREG(st.st_mode) && (st.st_mode & 0111)) == !c->negate; } + case CONDITION_FILE_CONTAINS: + return test_file_contains(c->parameter) == !c->negate; + case CONDITION_KERNEL_COMMAND_LINE: return test_kernel_command_line(c->parameter) == !c->negate; @@ -392,6 +425,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty", [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty", [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable", + [CONDITION_FILE_CONTAINS] = "ConditionFileContains", [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine", [CONDITION_VIRTUALIZATION] = "ConditionVirtualization", [CONDITION_SECURITY] = "ConditionSecurity", diff --git a/src/core/condition.h b/src/core/condition.h index 50ed955..2bf26bd 100644 --- a/src/core/condition.h +++ b/src/core/condition.h @@ -35,6 +35,7 @@ typedef enum ConditionType { CONDITION_DIRECTORY_NOT_EMPTY, CONDITION_FILE_NOT_EMPTY, CONDITION_FILE_IS_EXECUTABLE, + CONDITION_FILE_CONTAINS, CONDITION_KERNEL_COMMAND_LINE, CONDITION_VIRTUALIZATION, CONDITION_SECURITY, diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 2325d6a..310e1c5 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -134,6 +134,7 @@ Unit.ConditionPathIsReadWrite, config_parse_unit_condition_path, CONDITION_P Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, 0 Unit.ConditionFileNotEmpty, config_parse_unit_condition_path, CONDITION_FILE_NOT_EMPTY, 0 Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE, 0 +Unit.ConditionFileContains, config_parse_unit_condition_string, CONDITION_FILE_CONTAINS, 0 Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0 Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0 Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, 0 -- 1.7.10.4 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel