[systemd-devel] [RFC PATCH] condition: add ConditionFileContains=
Karol Lewandowski
k.lewandowsk at samsung.com
Thu Jul 11 10:18:35 PDT 2013
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
More information about the systemd-devel
mailing list