1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-07 17:17:44 +03:00

Introspect and monitor dropin configuration

This commit is contained in:
Oleksii Shevchuk 2013-04-01 13:32:35 +03:00 committed by Zbigniew Jędrzejewski-Szmek
parent 050fbdb878
commit ae7a7182da
6 changed files with 77 additions and 20 deletions

View File

@ -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) },

View File

@ -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" \

View File

@ -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;
}

View File

@ -25,4 +25,5 @@
/* Read service data supplementary drop-in directories */
char **unit_find_dropin_paths(Unit *u);
int unit_load_dropin(Unit *u);

View File

@ -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) {

View File

@ -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;