From ceee3d82853a198884795e5d815b895468212b24 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 27 Jan 2010 06:19:48 +0100 Subject: [PATCH] notify socket unit when service unit dies --- service.c | 39 +++++++++++++++++++++++++++++++++++++++ socket.c | 11 +++++++++++ socket.h | 3 +++ 3 files changed, 53 insertions(+) diff --git a/service.c b/service.c index ae7fc36a..2c3c0b23 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 1954259b..86104aa8 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 2c8a69f6..5495e3c5 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 -- 2.39.5