Accepting request 115147 from network

- socket-activation: Fix rpcbind.service to use separate
  sockets (bnc#757909).

- socket-activation: don't unlink socket we didn't create (bnc#757667). (forwarded request 114480 from jeff_mahoney)

OBS-URL: https://build.opensuse.org/request/show/115147
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/rpcbind?expand=0&rev=25
This commit is contained in:
Stephan Kulow 2012-05-03 09:00:23 +00:00 committed by Git OBS Bridge
commit 00099b6985
4 changed files with 182 additions and 7 deletions

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Wed Apr 18 23:46:52 CEST 2012 - jeffm@suse.de
- socket-activation: Fix rpcbind.service to use separate
sockets (bnc#757909).
-------------------------------------------------------------------
Wed Apr 18 05:47:20 CEST 2012 - jeffm@suse.de
- socket-activation: don't unlink socket we didn't create (bnc#757667).
-------------------------------------------------------------------
Mon Dec 19 22:54:46 UTC 2011 - crrodriguez@opensuse.org

View File

@ -1,7 +1,7 @@
#
# spec file for package rpcbind
#
# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -16,13 +16,12 @@
#
Name: rpcbind
Version: 0.2.0_git201103171419
Release: 0
Summary: Transport independent RPC portmapper
License: BSD-3-Clause
Group: Productivity/Networking/System
Version: 0.2.0_git201103171419
Release: 1
Summary: Transport independent RPC portmapper
Url: http://git.infradead.org/users/steved/rpcbind.git
Source: %{name}-%{version}.tar.bz2
Source1: rpcbind.init
@ -31,15 +30,18 @@ Source3: rpcbind.xml
Source4: pmap_set.c
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: libtirpc-devel
BuildRequires: tcpd-devel
BuildRequires: libtool
BuildRequires: pkgconfig
BuildRequires: tcpd-devel
Provides: portmap = 6.0+git20070716
Obsoletes: portmap <= 6.0+git20070716
# hopefully soon we will have this autogenerated from rpm
Provides: sysvinit(portmap) sysvinit(rpcbind)
Provides: sysvinit(portmap)
Provides: sysvinit(rpcbind)
PreReq: %insserv_prereq %fillup_prereq /sbin/checkproc sysvinit(network) syslog
Patch0: 0001-systemd-add-support-for-system-bus-activation.patch
Patch1: socket-activation-don-t-unlink-socket-we-didn-t-create
Patch2: socket-activation-fix-rpcbind-service-to-use-separate-sockets
%define statefile /var/lib/portmap.state
%if 0%{?suse_version} > 1140
BuildRequires: systemd-devel
@ -65,6 +67,8 @@ Authors:
%setup -q
cp %{SOURCE4} .
%patch0 -p1
%patch1 -p1
%patch2 -p1
%build
autoreconf -fiv

View File

@ -0,0 +1,61 @@
From: Jeff Mahoney <jeffm@suse.com>
Subject: socket-activation: don't unlink socket we didn't create
References: bnc#757667
On an unpatched system, try this:
rpcinfo <works>
rcrpcbind restart
rpcinfo <fails>
This is due to rpcbind unlinking the socket file when it exits. It
doesn't own the socket file when socket activation is used - systemd
does. Systemd still has an open reference to it and when rpcbind is
restarted, it passes the open reference back to it and rpcbind is
perfectly happy to accept it. Unfortunately, everything that needs to
talk to rpcbind no longer can because the socket file each of those
users needs to open is no longer on the file system.
This patch adds a new global that's used to avoid unlinking the
rpcbind.sock socket file during shutdown.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
src/rpcbind.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -80,6 +81,7 @@
int debugging = 0; /* Tell me what's going on */
int doabort = 0; /* When debugging, do an abort on errors */
int dofork = 1; /* fork? */
+int sock_needs_unlink = 1; /* we created rpcbind.sock */
rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */
@@ -365,6 +396,14 @@ init_transport(struct netconfig *nconf)
nconf->nc_netid);
goto error;
}
+
+ /*
+ * We were passed the open UNIX socket
+ * and shouldn't remove it.
+ */
+ if (sa.sa.sa_family == AF_UNIX &&
+ strcmp(sa.un.sun_path, _PATH_RPCBINDSOCK))
+ sock_needs_unlink = 0;
}
/* if none of the systemd sockets matched, we set up the socket in
@@ -784,7 +823,8 @@ static void
terminate(int dummy /*__unused*/)
{
close(rpcbindlockfd);
- unlink(_PATH_RPCBINDSOCK);
+ if (sock_needs_unlink)
+ unlink(_PATH_RPCBINDSOCK);
unlink(RPCBINDDLOCK);
#ifdef WARMSTART
syslog(LOG_ERR,

View File

@ -0,0 +1,99 @@
From: Jeff Mahoney <jeffm@suse.com>
Subject: socket-activation: Fix rpcbind.service to use separate sockets
References: bnc#757909
systemd will, by default, pass a socket that provides both IPv4 and
IPv6 services. RPC netconfig requires that sockets be either IPv4
or IPv6.
This patch fixes the rpcbind.socket unit file and adds a warning
to rpcbind should the user encounter an issue.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
src/rpcbind.c | 32 +++++++++++++++++++++++++++++++-
systemd/rpcbind.socket | 9 +++++++--
2 files changed, 38 insertions(+), 3 deletions(-)
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -50,6 +50,7 @@
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <netinet/in.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#ifdef PORTMAP
@@ -262,6 +264,32 @@ main(int argc, char *argv[])
}
/*
+ * Normally systemd will open sockets in dual ipv4/ipv6 mode.
+ * That won't work with netconfig and we'll only match
+ * the ipv6 socket. Convert it to IPV6_V6ONLY and issue
+ * a warning for the user to fix their systemd config.
+ */
+static int
+handle_ipv6_socket(int fd)
+{
+ int opt;
+ socklen_t len = sizeof(opt);
+
+ if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, &len)) {
+ syslog(LOG_ERR, "failed to get ipv6 socket opts: %s",
+ strerror(errno));
+ return 1;
+ }
+
+ if (opt) /* socket is already in V6ONLY mode */
+ return 0;
+
+ syslog(LOG_ERR, "systemd has passed an IPv4/IPv6 dual-mode socket.");
+ syslog(LOG_ERR, "Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
+ return 1;
+}
+
+/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
* Returns 0 if succeeds, else fails
@@ -313,7 +341,7 @@ init_transport(struct netconfig *nconf)
#ifdef SYSTEMD
n = sd_listen_fds(0);
if (n < 0) {
- syslog(LOG_ERR, "failed to acquire systemd scokets: %s", strerror(-n));
+ syslog(LOG_ERR, "failed to acquire systemd sockets: %s", strerror(-n));
return 1;
}
@@ -347,6 +375,9 @@ init_transport(struct netconfig *nconf)
goto error;
}
+ if (sa.sa.sa_family == AF_INET6 && handle_ipv6_socket(fd))
+ goto error;
+
/* Copy the address */
taddr.addr.maxlen = taddr.addr.len = addrlen;
taddr.addr.buf = malloc(addrlen);
--- a/systemd/rpcbind.socket
+++ b/systemd/rpcbind.socket
@@ -5,8 +5,13 @@ Before=rpcbind.target
[Socket]
ListenStream=/var/run/rpcbind.sock
-ListenStream=111
-ListenDatagram=111
+
+# RPC netconfig can't handle ipv6/ipv4 dual sockets
+BindIPv6Only=ipv6-only
+ListenStream=0.0.0.0:111
+ListenDatagram=0.0.0.0:111
+ListenStream=[::]:111
+ListenDatagram=[::]:111
[Install]
WantedBy=sockets.target