summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.exec.xml2
-rw-r--r--src/service.c40
-rw-r--r--src/service.h1
-rw-r--r--src/unit.c26
-rw-r--r--src/unit.h3
5 files changed, 60 insertions, 12 deletions
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 9f71492bc1..ffc257383d 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 62027f3a2e..4ee7900e08 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 55b9513f48..e28f74b898 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 057431c808..87b7edf145 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 1c8cf63870..79f15103ba 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);