Blob Blame History Raw
From b57bafa73c2e035c216de8fb7933d751d456a93b Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Mon, 5 Mar 2012 22:47:54 +0100
Subject: [PATCH] socket: fail the socket if the service keeps dying on start

If the service reaches the start limit, mark the sockets that activate
it as failed (with the result code 'service-broken').
This way the sockets won't act as tarpits for clients connecting to
them.
(cherry picked from commit c2f3480897b51dd9b2137f1eeddb4c851e9c6e3b)

Conflicts:

	src/service.c
	src/socket.c
	src/socket.h
---
 src/service.c |    7 ++++---
 src/socket.c  |    9 ++++++---
 src/socket.h  |    2 +-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/src/service.c b/src/service.c
index f99ee60..950e495 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1375,7 +1375,7 @@ static int service_search_main_pid(Service *s) {
         return 0;
 }
 
-static void service_notify_sockets_dead(Service *s) {
+static void service_notify_sockets_dead(Service *s, bool broken) {
         Iterator i;
         Unit *u;
 
@@ -1388,7 +1388,7 @@ static void service_notify_sockets_dead(Service *s) {
 
         SET_FOREACH(u, s->meta.dependencies[UNIT_TRIGGERED_BY], i)
                 if (u->meta.type == UNIT_SOCKET)
-                        socket_notify_service_dead(SOCKET(u));
+                        socket_notify_service_dead(SOCKET(u), broken);
 
         return;
 }
@@ -1450,7 +1450,7 @@ static void service_set_state(Service *s, ServiceState state) {
             state == SERVICE_FINAL_SIGKILL ||
             state == SERVICE_FAILED ||
             state == SERVICE_AUTO_RESTART)
-                service_notify_sockets_dead(s);
+                service_notify_sockets_dead(s, false);
 
         if (state != SERVICE_START_PRE &&
             state != SERVICE_START &&
@@ -2275,6 +2275,7 @@ static int service_start(Unit *u) {
         /* Make sure we don't enter a busy loop of some kind. */
         if (!ratelimit_test(&s->ratelimit)) {
                 log_warning("%s start request repeated too quickly, refusing to start.", u->meta.id);
+                service_notify_sockets_dead(s, true);
                 return -ECANCELED;
         }
 
diff --git a/src/socket.c b/src/socket.c
index 8bce18c..4b85528 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -2016,7 +2016,7 @@ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
         return 0;
 }
 
-void socket_notify_service_dead(Socket *s) {
+void socket_notify_service_dead(Socket *s, bool broken) {
         assert(s);
 
         /* The service is dead. Dang!
@@ -2025,8 +2025,11 @@ void socket_notify_service_dead(Socket *s) {
          * services. */
 
         if (s->state == SOCKET_RUNNING) {
-                log_debug("%s got notified about service death.", s->meta.id);
-                socket_enter_listening(s);
+                log_debug("%s got notified about service death (broken: %s)", s->meta.id, yes_no(broken));
+                if (broken)
+                        socket_enter_stop_pre(s, false);
+                else
+                        socket_enter_listening(s);
         }
 }
 
diff --git a/src/socket.h b/src/socket.h
index 4fc2cbe..31b9552 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -137,7 +137,7 @@ struct Socket {
 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);
+void socket_notify_service_dead(Socket *s, bool broken);
 
 /* Called from the mount code figure out if a mount is a dependency of
  * any of the sockets of this socket */