summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/service.c31
-rw-r--r--src/core/socket.c39
-rw-r--r--src/core/socket.h3
3 files changed, 38 insertions, 35 deletions
diff --git a/src/core/service.c b/src/core/service.c
index 08b929e4fe..246a86e23f 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1489,24 +1489,6 @@ static int service_search_main_pid(Service *s) {
return 0;
}
-static void service_notify_sockets_dead(Service *s, bool failed_permanent) {
- Iterator i;
- Unit *u;
-
- assert(s);
-
- /* Notifies all our sockets when we die */
-
- if (s->socket_fd >= 0)
- return;
-
- SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i)
- if (u->type == UNIT_SOCKET)
- socket_notify_service_dead(SOCKET(u), failed_permanent);
-
- return;
-}
-
static void service_set_state(Service *s, ServiceState state) {
ServiceState old_state;
const UnitActiveState *table;
@@ -1558,19 +1540,6 @@ static void service_set_state(Service *s, ServiceState state) {
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
}
- if (state == SERVICE_FAILED)
- service_notify_sockets_dead(s, s->result == SERVICE_FAILURE_START_LIMIT);
-
- if (state == SERVICE_DEAD ||
- state == SERVICE_STOP ||
- state == SERVICE_STOP_SIGTERM ||
- state == SERVICE_STOP_SIGKILL ||
- state == SERVICE_STOP_POST ||
- state == SERVICE_FINAL_SIGTERM ||
- state == SERVICE_FINAL_SIGKILL ||
- state == SERVICE_AUTO_RESTART)
- service_notify_sockets_dead(s, false);
-
if (state != SERVICE_START_PRE &&
state != SERVICE_START &&
state != SERVICE_START_POST &&
diff --git a/src/core/socket.c b/src/core/socket.c
index cf88bae9da..2130e48686 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2277,7 +2277,7 @@ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
return 0;
}
-void socket_notify_service_dead(Socket *s, bool failed_permanent) {
+static void socket_notify_service_dead(Socket *s, bool failed_permanent) {
assert(s);
/* The service is dead. Dang!
@@ -2322,6 +2322,41 @@ static void socket_reset_failed(Unit *u) {
s->result = SOCKET_SUCCESS;
}
+static void socket_trigger_notify(Unit *u, Unit *other) {
+ Socket *s = SOCKET(u);
+ Service *se = SERVICE(other);
+
+ assert(u);
+ assert(other);
+
+ /* Don't propagate state changes from the service if we are
+ already down or accepting connections */
+ if ((s->state != SOCKET_RUNNING &&
+ s->state != SOCKET_LISTENING) ||
+ s->accept)
+ return;
+
+ if (other->load_state != UNIT_LOADED ||
+ other->type != UNIT_SERVICE)
+ return;
+
+ if (se->state == SERVICE_FAILED)
+ socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT);
+
+ if (se->state == SERVICE_DEAD ||
+ se->state == SERVICE_STOP ||
+ se->state == SERVICE_STOP_SIGTERM ||
+ se->state == SERVICE_STOP_SIGKILL ||
+ se->state == SERVICE_STOP_POST ||
+ se->state == SERVICE_FINAL_SIGTERM ||
+ se->state == SERVICE_FINAL_SIGKILL ||
+ se->state == SERVICE_AUTO_RESTART)
+ socket_notify_service_dead(s, false);
+
+ if (se->state == SERVICE_RUNNING)
+ socket_set_state(s, SOCKET_RUNNING);
+}
+
static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) {
return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
}
@@ -2402,6 +2437,8 @@ const UnitVTable socket_vtable = {
.sigchld_event = socket_sigchld_event,
.timer_event = socket_timer_event,
+ .trigger_notify = socket_trigger_notify,
+
.reset_failed = socket_reset_failed,
.bus_interface = "org.freedesktop.systemd1.Socket",
diff --git a/src/core/socket.h b/src/core/socket.h
index 8f9dfdbfb0..57333226f5 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -156,9 +156,6 @@ struct Socket {
/* Called from the service code when collecting fds */
int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds);
-/* Called from the service when it shut down */
-void socket_notify_service_dead(Socket *s, bool failed_permanent);
-
/* Called from the mount code figure out if a mount is a dependency of
* any of the sockets of this socket */
int socket_add_one_mount_link(Socket *s, Mount *m);