[systemd-devel] [PATCH] [RFC] Introspect and monitor dropin configuration
Oleksii Shevchuk
alxchk at gmail.com
Sun Mar 31 06:52:54 PDT 2013
---
src/core/dbus-unit.c | 1 +
src/core/load-dropin.c | 60 ++++++++++++++++++++++++++++++++++----------------
src/core/load-dropin.h | 1 +
src/core/unit.c | 21 ++++++++++++++++++
src/core/unit.h | 2 ++
5 files changed, 66 insertions(+), 19 deletions(-)
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index dc7d1f1..f413386 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -1284,6 +1284,7 @@ const BusProperty bus_unit_properties[] = {
{ "SubState", bus_unit_append_sub_state, "s", 0 },
{ "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true },
{ "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true },
+ { "DropinPaths", bus_property_append_strv, "as", offsetof(Unit, dropin_paths), true },
{ "UnitFileState", bus_unit_append_file_state, "s", 0 },
{ "InactiveExitTimestamp",bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) },
{ "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) },
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index 95c9a38..8925f29 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -137,12 +137,44 @@ static int process_dir(Unit *u, const char *unit_path, const char *name, const c
return 0;
}
-int unit_load_dropin(Unit *u) {
+char ** unit_find_dropin_paths(Unit *u) {
Iterator i;
char *t;
_cleanup_strv_free_ char **strv = NULL;
+ char ** configs = NULL;
int r;
+ assert(u);
+
+ SET_FOREACH(t, u->names, i) {
+ char **p;
+
+ STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
+ /* This loads the drop-in config snippets */
+ r = process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
+ if (r < 0)
+ return NULL;
+ }
+ }
+
+ if (!strv_isempty(strv)) {
+ r = conf_files_list_strv(&configs, ".conf", NULL, (const char**) strv);
+ if (r < 0) {
+ log_error("Failed to get list of configuration files: %s", strerror(-r));
+ strv_free(configs);
+ return NULL;
+ }
+
+ }
+
+ return configs;
+}
+
+int unit_load_dropin(Unit *u) {
+ Iterator i;
+ char *t, **f;
+ _cleanup_strv_free_ char **strv = NULL;
+ int r;
assert(u);
@@ -159,30 +191,20 @@ int unit_load_dropin(Unit *u) {
r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL);
if (r < 0)
return r;
-
- /* This loads the drop-in config snippets */
- r = process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
- if (r < 0)
- return r;
}
}
- if (!strv_isempty(strv)) {
- _cleanup_strv_free_ char **files = NULL;
- char **f;
+ u->dropin_paths = unit_find_dropin_paths(u);
+ if (! u->dropin_paths)
+ return 0;
- r = conf_files_list_strv(&files, ".conf", NULL, (const char**) strv);
- if (r < 0) {
- log_error("Failed to get list of configuration files: %s", strerror(-r));
+ STRV_FOREACH(f, u->dropin_paths) {
+ r = config_parse(*f, NULL, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
+ if (r < 0)
return r;
- }
-
- STRV_FOREACH(f, files) {
- r = config_parse(*f, NULL, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
- if (r < 0)
- return r;
- }
}
+ u->dropin_mtime = now(CLOCK_REALTIME);
+
return 0;
}
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
index 1d2fafe..277bff3 100644
--- a/src/core/load-dropin.h
+++ b/src/core/load-dropin.h
@@ -25,4 +25,5 @@
/* Read service data supplementary drop-in directories */
+char ** unit_find_dropin_paths(Unit *u);
int unit_load_dropin(Unit *u);
diff --git a/src/core/unit.c b/src/core/unit.c
index 7111679..87605d6 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -408,6 +408,7 @@ void unit_free(Unit *u) {
strv_free(u->documentation);
free(u->fragment_path);
free(u->source_path);
+ strv_free(u->dropin_paths);
free(u->instance);
set_free_free(u->names);
@@ -696,6 +697,9 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
if (u->source_path)
fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
+ STRV_FOREACH(j, u->dropin_paths)
+ fprintf(f, "%s\tDropin Path: %s\n", prefix, *j);
+
if (u->job_timeout > 0)
fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout));
@@ -2553,6 +2557,8 @@ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg
}
bool unit_need_daemon_reload(Unit *u) {
+ _cleanup_strv_free_ char ** t = NULL;
+ char ** j;
struct stat st;
assert(u);
@@ -2578,6 +2584,21 @@ bool unit_need_daemon_reload(Unit *u) {
return true;
}
+ t = unit_find_dropin_paths(u);
+ if (! ((strv_length(t) == strv_length(u->dropin_paths)) &&
+ strv_overlap(u->dropin_paths, t)))
+ return true;
+
+ STRV_FOREACH(j, u->dropin_paths) {
+ zero(st);
+ if (stat(*j, &st) < 0)
+ return true;
+
+ if (u->dropin_mtime > 0 &&
+ timespec_load(&st.st_mtim) > u->dropin_mtime)
+ return true;
+ }
+
return false;
}
diff --git a/src/core/unit.h b/src/core/unit.h
index 3da6a50..ecdd8e3 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -138,8 +138,10 @@ struct Unit {
char *fragment_path; /* if loaded from a config file this is the primary path to it */
char *source_path; /* if converted, the source file */
+ char ** dropin_paths;
usec_t fragment_mtime;
usec_t source_mtime;
+ usec_t dropin_mtime;
/* If there is something to do with this unit, then this is the installed job for it */
Job *job;
--
1.8.1.2
More information about the systemd-devel
mailing list