summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/dbus-unit.c1
-rw-r--r--src/core/dbus-unit.h1
-rw-r--r--src/core/load-dropin.c60
-rw-r--r--src/core/load-dropin.h1
-rw-r--r--src/core/unit.c32
-rw-r--r--src/core/unit.h2
6 files changed, 77 insertions, 20 deletions
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index dc7d1f13f0..f413386553 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/dbus-unit.h b/src/core/dbus-unit.h
index 34980b046e..e4c5666d8f 100644
--- a/src/core/dbus-unit.h
+++ b/src/core/dbus-unit.h
@@ -88,6 +88,7 @@
" <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"SourcePath\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"DropinPaths\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"Documentation\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index 95c9a386ca..942ad027e9 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 1d2fafeee6..fd551179e2 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 711167994a..75a49d5e24 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,7 +2557,10 @@ 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 **path;
struct stat st;
+ unsigned loaded_cnt, current_cnt;
assert(u);
@@ -2578,7 +2585,30 @@ bool unit_need_daemon_reload(Unit *u) {
return true;
}
- return false;
+ t = unit_find_dropin_paths(u);
+ loaded_cnt = strv_length(t);
+ current_cnt = strv_length(u->dropin_paths);
+
+ if (loaded_cnt == current_cnt) {
+ if (loaded_cnt == 0)
+ return false;
+
+ if (strv_overlap(u->dropin_paths, t)) {
+ STRV_FOREACH(path, u->dropin_paths) {
+ zero(st);
+ if (stat(*path, &st) < 0)
+ return true;
+
+ if (u->dropin_mtime > 0 &&
+ timespec_load(&st.st_mtim) > u->dropin_mtime)
+ return true;
+ }
+
+ return false;
+ } else
+ return true;
+ } else
+ return true;
}
void unit_reset_failed(Unit *u) {
diff --git a/src/core/unit.h b/src/core/unit.h
index 3da6a50da9..80a96e8053 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;