[systemd/f16] Fix occasionally failing socket units with Accept=yes (#783344)

Michal Schmidt michich at fedoraproject.org
Fri Jan 20 23:14:20 UTC 2012


commit 5a09d6df41ac208718f0c246dd0d4821f19c5bf1
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Sat Jan 21 00:12:11 2012 +0100

    Fix occasionally failing socket units with Accept=yes (#783344)

 ...-socket-don-t-fail-the-socket-on-ENOTCONN.patch |  108 ++++++++++++++++++++
 systemd.spec                                       |    6 +-
 2 files changed, 113 insertions(+), 1 deletions(-)
---
diff --git a/0133-socket-don-t-fail-the-socket-on-ENOTCONN.patch b/0133-socket-don-t-fail-the-socket-on-ENOTCONN.patch
new file mode 100644
index 0000000..696568b
--- /dev/null
+++ b/0133-socket-don-t-fail-the-socket-on-ENOTCONN.patch
@@ -0,0 +1,108 @@
+From b148a875bed6c32a5ffee9a23655ac0fc8227fd5 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 20 Jan 2012 23:44:22 +0100
+Subject: [PATCH] socket: don't fail the socket on ENOTCONN
+
+Albert Strasheim reported a socket unit with Accept=yes was failing
+sometimes.
+getpeername() returns ENOTCONN if the connection was killed by TCP RST.
+The socket unit must not fail when it happens.
+
+Reproducer available at:
+https://bugzilla.redhat.com/show_bug.cgi?id=783344
+(cherry picked from commit 1a710b430b7e5fa036ee5c03e14e60f725df5baf)
+
+Conflicts:
+
+	src/socket.c
+---
+ src/socket.c |   36 ++++++++++++++++++++++++++----------
+ 1 files changed, 26 insertions(+), 10 deletions(-)
+
+diff --git a/src/socket.c b/src/socket.c
+index 7034436..00f0ebd 100644
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -1368,7 +1368,8 @@ static void socket_enter_running(Socket *s, int cfd) {
+                         /* Flush all sockets by closing and reopening them */
+                         socket_close_fds(s);
+ 
+-                        if ((r = socket_watch_fds(s)) < 0) {
++                        r = socket_watch_fds(s);
++                        if (r < 0) {
+                                 log_warning("%s failed to watch sockets: %s", s->meta.id, strerror(-r));
+                                 socket_enter_stop_pre(s, false);
+                         }
+@@ -1390,9 +1391,11 @@ static void socket_enter_running(Socket *s, int cfd) {
+                                 break;
+                         }
+ 
+-                if (!pending)
+-                        if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL)) < 0)
++                if (!pending) {
++                        r = manager_add_job(s->meta.manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
++                        if (r < 0)
+                                 goto fail;
++                }
+ 
+                 socket_set_state(s, SOCKET_RUNNING);
+         } else {
+@@ -1405,13 +1408,23 @@ static void socket_enter_running(Socket *s, int cfd) {
+                         return;
+                 }
+ 
+-                if ((r = socket_instantiate_service(s)) < 0)
++                r = socket_instantiate_service(s);
++                if (r < 0)
+                         goto fail;
+ 
+-                if ((r = instance_from_socket(cfd, s->n_accepted, &instance)) < 0)
+-                        goto fail;
++                r = instance_from_socket(cfd, s->n_accepted, &instance);
++                if (r < 0) {
++                        if (r != -ENOTCONN)
++                                goto fail;
++
++                        /* ENOTCONN is legitimate if TCP RST was received.
++                         * This connection is over, but the socket unit lives on. */
++                        close_nointr_nofail(cfd);
++                        return;
++                }
+ 
+-                if (!(prefix = unit_name_to_prefix(s->meta.id))) {
++                prefix = unit_name_to_prefix(s->meta.id);
++                if (!prefix) {
+                         free(instance);
+                         r = -ENOMEM;
+                         goto fail;
+@@ -1426,7 +1439,8 @@ static void socket_enter_running(Socket *s, int cfd) {
+                         goto fail;
+                 }
+ 
+-                if ((r = unit_add_name(UNIT_DEREF(s->service), name)) < 0) {
++                r = unit_add_name(UNIT_DEREF(s->service), name);
++                if (r < 0) {
+                         free(name);
+                         goto fail;
+                 }
+@@ -1440,13 +1454,15 @@ static void socket_enter_running(Socket *s, int cfd) {
+                 unit_choose_id(UNIT(service), name);
+                 free(name);
+ 
+-                if ((r = service_set_socket_fd(service, cfd, s)) < 0)
++                r = service_set_socket_fd(service, cfd, s);
++                if (r < 0)
+                         goto fail;
+ 
+                 cfd = -1;
+                 s->n_connections ++;
+ 
+-                if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL)) < 0)
++                r = manager_add_job(s->meta.manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
++                if (r < 0)
+                         goto fail;
+ 
+                 /* Notify clients about changed counters */
+-- 
+1.7.7.5
+
diff --git a/systemd.spec b/systemd.spec
index 6f7f502..0be44b4 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -2,7 +2,7 @@ Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Version:        37
-Release:        9%{?dist}
+Release:        10%{?dist}
 License:        GPLv2+
 Group:          System Environment/Base
 Summary:        A System and Service Manager
@@ -180,6 +180,7 @@ Patch0129:      0129-pam-fix-build.patch
 Patch0130:      0130-mount-fix-quota.patch
 Patch0131:      0131-logind-downgrade-login-message-to-debug.patch
 Patch0132:      0132-service-add-missing-pid-file-unwatch-in-the-destruct.patch
+Patch0133:      0133-socket-don-t-fail-the-socket-on-ENOTCONN.patch
 
 # For sysvinit tools
 Obsoletes:      SysVinit < 2.86-24, sysvinit < 2.86-24
@@ -501,6 +502,9 @@ fi
 %{_bindir}/systemd-sysv-convert
 
 %changelog
+* Sat Jan 21 2012 Michal Schmidt <mschmidt at redhat.com> - 37-10
+- Fix occasionally failing socket units with Accept=yes (#783344).
+
 * Fri Jan 20 2012 Michal Schmidt <mschmidt at redhat.com> - 37-9
 - Fix a crash related to pid file watch and daemon-reload (#783118).
 - Added Conflicts with known broken spamassassin.


More information about the scm-commits mailing list