chiark / gitweb /
notify socket unit when service unit dies
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Jan 2010 05:19:48 +0000 (06:19 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 27 Jan 2010 05:19:48 +0000 (06:19 +0100)
service.c
socket.c
socket.h

index ae7fc36a5c4bedd54ac35516443316139e139c0f..2c3c0b233be3203aee90f6190d7546254f9c0c92 100644 (file)
--- a/service.c
+++ b/service.c
@@ -198,6 +198,34 @@ static int service_load_pid_file(Service *s) {
         return 0;
 }
 
         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);
 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;
 
             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]);
         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]);
index 1954259b508308b8f8c6dd32eee0c03708e2412a..86104aa85a098b23088b86c683cda0ba06a0d1ce 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -779,6 +779,17 @@ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
         return 0;
 }
 
         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",
 
 const UnitVTable socket_vtable = {
         .suffix = ".socket",
 
index 2c8a69f6613cb524502c2ee240d869c21b61c365..5495e3c5b9a9ccbd3b6353dc9a3491e310ff91cb 100644 (file)
--- 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 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
 extern const UnitVTable socket_vtable;
 
 #endif