diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-01-27 06:19:48 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-01-27 06:19:48 +0100 |
commit | ceee3d82853a198884795e5d815b895468212b24 (patch) | |
tree | 2e40ab3dff86ae1ebf49d76db1716a8677b095ff | |
parent | 2a987ee8c94ac29545e3c94d47b5d493daea0b5e (diff) |
notify socket unit when service unit dies
-rw-r--r-- | service.c | 39 | ||||
-rw-r--r-- | socket.c | 11 | ||||
-rw-r--r-- | socket.h | 3 |
3 files changed, 53 insertions, 0 deletions
@@ -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]); @@ -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", @@ -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 |