summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service.c39
-rw-r--r--socket.c11
-rw-r--r--socket.h3
3 files changed, 53 insertions, 0 deletions
diff --git a/service.c b/service.c
index ae7fc36a5c..2c3c0b233b 100644
--- a/service.c
+++ b/service.c
@@ -198,6 +198,34 @@ static int service_load_pid_file(Service *s) {
return 0;
}
+static int service_notify_sockets(Service *s) {
+ Iterator i;
+ char *t;
+
+ assert(s);
+
+ SET_FOREACH(t, UNIT(s)->meta.names, i) {
+ char *k;
+ Unit *p;
+
+ /* Look for all socket objects that go by any of our
+ * units and collect their fds */
+
+ if (!(k = unit_name_change_suffix(t, ".socket")))
+ return -ENOMEM;
+
+ p = manager_get_unit(UNIT(s)->meta.manager, k);
+ free(k);
+
+ if (!p)
+ continue;
+
+ socket_notify_service_dead(SOCKET(p));
+ }
+
+ return 0;
+}
+
static void service_set_state(Service *s, ServiceState state) {
ServiceState old_state;
assert(s);
@@ -252,6 +280,17 @@ static void service_set_state(Service *s, ServiceState state) {
state != SERVICE_STOP_POST)
s->control_command = NULL;
+ 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_MAINTAINANCE ||
+ state == SERVICE_AUTO_RESTART)
+ service_notify_sockets(s);
+
log_debug("%s changing %s → %s", unit_id(UNIT(s)), state_string_table[old_state], state_string_table[state]);
unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]);
diff --git a/socket.c b/socket.c
index 1954259b50..86104aa85a 100644
--- a/socket.c
+++ b/socket.c
@@ -779,6 +779,17 @@ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
return 0;
}
+void socket_notify_service_dead(Socket *s) {
+ assert(s);
+
+ /* The service is dead. Dang. */
+
+ if (s->state == SOCKET_RUNNING) {
+ log_debug("%s got notified about service death.", unit_id(UNIT(s)));
+ socket_enter_listening(s);
+ }
+}
+
const UnitVTable socket_vtable = {
.suffix = ".socket",
diff --git a/socket.h b/socket.h
index 2c8a69f661..5495e3c5b9 100644
--- a/socket.h
+++ b/socket.h
@@ -82,6 +82,9 @@ 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);
+
extern const UnitVTable socket_vtable;
#endif