sys-apps/systemd: backport patch to fix dracut boot
authorMike Gilbert <floppym@gentoo.org>
Thu, 9 May 2019 13:41:30 +0000 (09:41 -0400)
committerMike Gilbert <floppym@gentoo.org>
Thu, 9 May 2019 13:41:30 +0000 (09:41 -0400)
Closes: https://bugs.gentoo.org/685002
Package-Manager: Portage-2.3.66_p2, Repoman-2.3.12_p111
Signed-off-by: Mike Gilbert <floppym@gentoo.org>
sys-apps/systemd/files/242-socket-util-flush-accept.patch [new file with mode: 0644]
sys-apps/systemd/systemd-242-r1.ebuild [moved from sys-apps/systemd/systemd-242.ebuild with 99% similarity]

diff --git a/sys-apps/systemd/files/242-socket-util-flush-accept.patch b/sys-apps/systemd/files/242-socket-util-flush-accept.patch
new file mode 100644 (file)
index 0000000..4849c4c
--- /dev/null
@@ -0,0 +1,46 @@
+From f3d75364fbebf2ddb6393e54db5e10b6f6234e14 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 18 Apr 2019 15:13:54 +0200
+Subject: [PATCH] socket-util: make sure flush_accept() doesn't hang on
+ unexpected EOPNOTSUPP
+
+So apparently there are two reasons why accept() can return EOPNOTSUPP:
+because the socket is not a listening stream socket (or similar), or
+because the incoming TCP connection for some reason wasn't acceptable to
+the host. THe latter should be a transient error, as suggested on
+accept(2). The former however should be considered fatal for
+flush_accept(). Let's fix this by explicitly checking whether the socket
+is a listening socket beforehand.
+---
+ src/basic/socket-util.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
+index 904bafb76f9..e787d53d8f4 100644
+--- a/src/basic/socket-util.c
++++ b/src/basic/socket-util.c
+@@ -1225,9 +1225,22 @@ int flush_accept(int fd) {
+                 .fd = fd,
+                 .events = POLLIN,
+         };
+-        int r;
++        int r, b;
++        socklen_t l = sizeof(b);
++
++        /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately
++         * closing them.  */
++
++        if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0)
++                return -errno;
+-        /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
++        assert(l == sizeof(b));
++        if (!b) /* Let's check if this is a socket accepting connections before calling accept(). That's
++                 * because accept4() can return EOPNOTSUPP in the fd we are called on is not a listening
++                 * socket, or in case the incoming TCP connection transiently triggered that (see accept(2)
++                 * man page for details). The latter case is a transient error we should continue looping
++                 * on. The former case however is fatal. */
++                return -ENOTTY;
+         for (;;) {
+                 int cfd;
similarity index 99%
rename from sys-apps/systemd/systemd-242.ebuild
rename to sys-apps/systemd/systemd-242-r1.ebuild
index d09494587fc5714e575a69342390b27a17f941a0..a26267273852034d5dafd570587934bd6666d3f2 100644 (file)
@@ -171,6 +171,7 @@ src_prepare() {
        # Add local patches here
        PATCHES+=(
                "${FILESDIR}"/242-gcc-9.patch
+               "${FILESDIR}"/242-socket-util-flush-accept.patch
        )
 
        if ! use vanilla; then