From: Lennart Poettering Date: Wed, 15 Jun 2011 13:34:19 +0000 (+0200) Subject: service: check whether sysv scripts where changed X-Git-Tag: v30~173 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f4b19f4bc4b6e747ca19f53ef33a167ecf9ac0b;p=systemd service: check whether sysv scripts where changed --- diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 9f71492b..ffc25738 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -646,7 +646,7 @@ removed. If the list of capabilities is prefixed with ~ all but the listed capabilities will be included, the - effect of this assignment + effect of the assignment inverted. Note that this option does not actually set or unset any capabilities in the effective, diff --git a/src/service.c b/src/service.c index 62027f3a..4ee7900e 100644 --- a/src/service.c +++ b/src/service.c @@ -470,6 +470,7 @@ static int service_load_sysv_path(Service *s, const char *path) { LSB_DESCRIPTION } state = NORMAL; char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL, *description; + struct stat st; assert(s); assert(path); @@ -481,12 +482,26 @@ static int service_load_sysv_path(Service *s, const char *path) { goto finish; } + zero(st); + if (fstat(fileno(f), &st) < 0) { + r = -errno; + goto finish; + } + free(s->sysv_path); if (!(s->sysv_path = strdup(path))) { r = -ENOMEM; goto finish; } + s->sysv_mtime = timespec_load(&st.st_mtim); + + if (null_or_empty(&st)) { + u->meta.load_state = UNIT_MASKED; + r = 0; + goto finish; + } + while (!feof(f)) { char l[LINE_MAX], *t; @@ -3212,6 +3227,29 @@ static void service_reset_failed(Unit *u) { s->failure = false; } +static bool service_need_daemon_reload(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + +#ifdef HAVE_SYSV_COMPAT + if (s->sysv_path) { + struct stat st; + + zero(st); + if (stat(s->sysv_path, &st) < 0) + /* What, cannot access this anymore? */ + return true; + + if (s->sysv_mtime > 0 && + timespec_load(&st.st_mtim) != s->sysv_mtime) + return true; + } +#endif + + return false; +} + static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { Service *s = SERVICE(u); int r = 0; @@ -3361,6 +3399,8 @@ const UnitVTable service_vtable = { .reset_failed = service_reset_failed, + .need_daemon_reload = service_need_daemon_reload, + .cgroup_notify_empty = service_cgroup_notify_event, .notify_message = service_notify_message, diff --git a/src/service.h b/src/service.h index 55b9513f..e28f74b8 100644 --- a/src/service.h +++ b/src/service.h @@ -144,6 +144,7 @@ struct Service { char *sysv_path; char *sysv_runlevels; + usec_t sysv_mtime; #endif char *bus_name; diff --git a/src/unit.c b/src/unit.c index 057431c8..87b7edf1 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2305,21 +2305,25 @@ void unit_status_printf(Unit *u, const char *format, ...) { } bool unit_need_daemon_reload(Unit *u) { - struct stat st; - assert(u); - if (!u->meta.fragment_path) - return false; + if (u->meta.fragment_path) { + struct stat st; - zero(st); - if (stat(u->meta.fragment_path, &st) < 0) - /* What, cannot access this anymore? */ - return true; + zero(st); + if (stat(u->meta.fragment_path, &st) < 0) + /* What, cannot access this anymore? */ + return true; - return - u->meta.fragment_mtime && - timespec_load(&st.st_mtim) != u->meta.fragment_mtime; + if (u->meta.fragment_mtime > 0 && + timespec_load(&st.st_mtim) != u->meta.fragment_mtime) + return true; + } + + if (UNIT_VTABLE(u)->need_daemon_reload) + return UNIT_VTABLE(u)->need_daemon_reload(u); + + return false; } void unit_reset_failed(Unit *u) { diff --git a/src/unit.h b/src/unit.h index 1c8cf638..79f15103 100644 --- a/src/unit.h +++ b/src/unit.h @@ -317,6 +317,9 @@ struct UnitVTable { void (*sigchld_event)(Unit *u, pid_t pid, int code, int status); void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w); + /* Check whether unit needs a daemon reload */ + bool (*need_daemon_reload)(Unit *u); + /* Reset failed state if we are in failed state */ void (*reset_failed)(Unit *u);