diff --git a/rpcbind.changes b/rpcbind.changes index 01f0067..d90f398 100644 --- a/rpcbind.changes +++ b/rpcbind.changes @@ -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 diff --git a/rpcbind.spec b/rpcbind.spec index f477259..2150b36 100644 --- a/rpcbind.spec +++ b/rpcbind.spec @@ -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 diff --git a/socket-activation-don-t-unlink-socket-we-didn-t-create b/socket-activation-don-t-unlink-socket-we-didn-t-create new file mode 100644 index 0000000..de12991 --- /dev/null +++ b/socket-activation-don-t-unlink-socket-we-didn-t-create @@ -0,0 +1,61 @@ +From: Jeff Mahoney +Subject: socket-activation: don't unlink socket we didn't create +References: bnc#757667 + + On an unpatched system, try this: + rpcinfo + rcrpcbind restart + rpcinfo + + 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 +--- + + 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, diff --git a/socket-activation-fix-rpcbind-service-to-use-separate-sockets b/socket-activation-fix-rpcbind-service-to-use-separate-sockets new file mode 100644 index 0000000..a57b210 --- /dev/null +++ b/socket-activation-fix-rpcbind-service-to-use-separate-sockets @@ -0,0 +1,99 @@ +From: Jeff Mahoney +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 +--- + + 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 + #include + #include ++#include + #include + #include + #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 +