[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