From: Oleksii Shevchuk Date: Mon, 1 Apr 2013 10:32:35 +0000 (+0300) Subject: Introspect and monitor dropin configuration X-Git-Tag: v201~90 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=ae7a7182da31371555fceb2aed609e40a64b900a;ds=sidebyside Introspect and monitor dropin configuration --- diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index dc7d1f13f..f41338655 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 34980b046..e4c5666d8 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -88,6 +88,7 @@ " \n" \ " \n" \ " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c index 95c9a386c..942ad027e 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 1d2fafeee..fd551179e 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 711167994..75a49d5e2 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 3da6a50da..80a96e805 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;