732 lines
22 KiB
Diff
732 lines
22 KiB
Diff
|
Delivered-To: cr@cristianrodriguez.net
|
||
|
Received: by 10.180.126.41 with SMTP id mv9cs133382wib;
|
||
|
Thu, 22 Dec 2011 17:05:49 -0800 (PST)
|
||
|
Received: by 10.213.15.203 with SMTP id l11mr2621843eba.5.1324602347791;
|
||
|
Thu, 22 Dec 2011 17:05:47 -0800 (PST)
|
||
|
Return-Path: <teg@jklm.no>
|
||
|
Received: from mx2.suse.de (cantor2.suse.de. [195.135.220.15])
|
||
|
by mx.google.com with ESMTPS id q2si6918918eef.172.2011.12.22.17.05.47
|
||
|
(version=TLSv1/SSLv3 cipher=OTHER);
|
||
|
Thu, 22 Dec 2011 17:05:47 -0800 (PST)
|
||
|
Received-SPF: softfail (google.com: domain of transitioning teg@jklm.no does not designate 195.135.220.15 as permitted sender) client-ip=195.135.220.15;
|
||
|
Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning teg@jklm.no does not designate 195.135.220.15 as permitted sender) smtp.mail=teg@jklm.no
|
||
|
Received: from mail-lpp01m010-f48.google.com (mail-lpp01m010-f48.google.com [209.85.215.48])
|
||
|
(using TLSv1 with cipher RC4-SHA (128/128 bits))
|
||
|
(No client certificate requested)
|
||
|
by mx2.suse.de (Postfix) with ESMTP id 3ACC28738D
|
||
|
for <crrodriguez@opensuse.org>; Fri, 23 Dec 2011 02:05:46 +0100 (CET)
|
||
|
Received: by laam7 with SMTP id m7so4957545laa.35
|
||
|
for <crrodriguez@opensuse.org>; Thu, 22 Dec 2011 17:05:45 -0800 (PST)
|
||
|
Received: by 10.152.110.6 with SMTP id hw6mr10613571lab.37.1324602344510;
|
||
|
Thu, 22 Dec 2011 17:05:44 -0800 (PST)
|
||
|
Received: from localhost.localdomain (cm-84.212.224.43.getinternet.no. [84.212.224.43])
|
||
|
by mx.google.com with ESMTPS id 5sm9033897lah.0.2011.12.22.17.05.42
|
||
|
(version=TLSv1/SSLv3 cipher=OTHER);
|
||
|
Thu, 22 Dec 2011 17:05:43 -0800 (PST)
|
||
|
From: Tom Gundersen <teg@jklm.no>
|
||
|
To: linux-nfs@vger.kernel.org
|
||
|
Cc: Tom Gundersen <teg@jklm.no>, Steve Dickson <steved@redhat.com>,
|
||
|
systemd-devel@lists.freedesktop.org,
|
||
|
=?UTF-8?q?Cristian=20Rodr=C3=ADguez?= <crrodriguez@opensuse.org>
|
||
|
Subject: [PATCH] rpcbind: add support for systemd socket activation
|
||
|
Date: Fri, 23 Dec 2011 02:05:27 +0100
|
||
|
Message-Id: <1324602327-1789-1-git-send-email-teg@jklm.no>
|
||
|
X-Mailer: git-send-email 1.7.8
|
||
|
In-Reply-To: <4EEFCBF0.1070407@opensuse.org>
|
||
|
References: <4EEFCBF0.1070407@opensuse.org>
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
Making rpcbind sockect activated will greatly simplify
|
||
|
its integration in systemd systems. In essence, other services
|
||
|
may now assume that rpcbind is always available, even during very
|
||
|
early boot. This means that we no longer need to worry about any
|
||
|
ordering dependencies.
|
||
|
|
||
|
This is based on a patch originally posted by Lennart Poettering:
|
||
|
<http://permalink.gmane.org/gmane.linux.nfs/33774>.
|
||
|
|
||
|
That patch was not merged due to the lack of a shared library and
|
||
|
as systemd was seen to be too Fedora specific.
|
||
|
|
||
|
Systemd now provides a shared library, and it is shipped by defalt in
|
||
|
OpenSUSE in addition to Fedora, and it is available in Debain, Gentoo,
|
||
|
Arch, and others.
|
||
|
|
||
|
This version of the patch has three changes from the original:
|
||
|
|
||
|
* It uses the shared library.
|
||
|
* It comes with unit files.
|
||
|
* It is rebased on top of master.
|
||
|
|
||
|
Please review the patch with "git show -b" or otherwise ignoring the
|
||
|
whitespace changes, or it will be extremely difficult to read.
|
||
|
|
||
|
Comments welcome.
|
||
|
|
||
|
v2: correctly enable systemd code at compile time
|
||
|
handle the case where not all the required sockets were supplied
|
||
|
listen on udp/tcp port 111 in addition to /var/run/rpcbind.sock
|
||
|
do not daemonize
|
||
|
|
||
|
Original-patch-by: Lennart Poettering <lennart@poettering.net>
|
||
|
Cc: Steve Dickson <steved@redhat.com>
|
||
|
Cc: systemd-devel@lists.freedesktop.org
|
||
|
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
|
||
|
Signed-off-by: Tom Gundersen <teg@jklm.no>
|
||
|
---
|
||
|
|
||
|
Thanks to Cristian for testing. The testcase I had been using was entirely flawed,
|
||
|
the code did in fact not work at all. Sorry about that!
|
||
|
|
||
|
This time around it should work :-)
|
||
|
|
||
|
Makefile.am | 15 ++
|
||
|
configure.in | 11 +
|
||
|
src/rpcbind.c | 467 +++++++++++++++++++++++++-------------------
|
||
|
systemd/.gitignore | 1 +
|
||
|
systemd/rpcbind.service.in | 9 +
|
||
|
systemd/rpcbind.socket | 12 ++
|
||
|
6 files changed, 316 insertions(+), 199 deletions(-)
|
||
|
create mode 100644 systemd/.gitignore
|
||
|
create mode 100644 systemd/rpcbind.service.in
|
||
|
create mode 100644 systemd/rpcbind.socket
|
||
|
|
||
|
diff --git a/Makefile.am b/Makefile.am
|
||
|
index 9fa608e..194b467 100644
|
||
|
--- a/Makefile.am
|
||
|
+++ b/Makefile.am
|
||
|
@@ -38,6 +38,21 @@ rpcbind_SOURCES = \
|
||
|
src/warmstart.c
|
||
|
rpcbind_LDADD = $(TIRPC_LIBS)
|
||
|
|
||
|
+if SYSTEMD
|
||
|
+AM_CPPFLAGS += $(SYSTEMD_CFLAGS) -DSYSTEMD
|
||
|
+
|
||
|
+rpcbind_LDADD += $(SYSTEMD_LIBS)
|
||
|
+
|
||
|
+systemd/rpcbind.service: systemd/rpcbind.service.in Makefile
|
||
|
+ sed -e 's,@bindir\@,$(bindir),g' \
|
||
|
+ < $< > $@ || rm $@
|
||
|
+
|
||
|
+systemdsystemunit_DATA = \
|
||
|
+ systemd/rpcbind.service \
|
||
|
+ systemd/rpcbind.socket
|
||
|
+
|
||
|
+endif
|
||
|
+
|
||
|
rpcinfo_SOURCES = src/rpcinfo.c
|
||
|
rpcinfo_LDADD = $(TIRPC_LIBS)
|
||
|
|
||
|
diff --git a/configure.in b/configure.in
|
||
|
index 2b67720..397d52d 100644
|
||
|
--- a/configure.in
|
||
|
+++ b/configure.in
|
||
|
@@ -29,6 +29,17 @@ AC_SUBST([rpcuser], [$with_rpcuser])
|
||
|
|
||
|
PKG_CHECK_MODULES([TIRPC], [libtirpc])
|
||
|
|
||
|
+PKG_PROG_PKG_CONFIG
|
||
|
+AC_ARG_WITH([systemdsystemunitdir],
|
||
|
+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
|
||
|
+ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
|
||
|
+ if test "x$with_systemdsystemunitdir" != xno; then
|
||
|
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
|
||
|
+ PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon])
|
||
|
+ fi
|
||
|
+AM_CONDITIONAL(SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
|
||
|
+
|
||
|
+
|
||
|
AS_IF([test x$enable_libwrap = xyes], [
|
||
|
AC_CHECK_LIB([wrap], [hosts_access], ,
|
||
|
AC_MSG_ERROR([libwrap support requested but unable to find libwrap]))
|
||
|
diff --git a/src/rpcbind.c b/src/rpcbind.c
|
||
|
index 24e069b..a87ce05 100644
|
||
|
--- a/src/rpcbind.c
|
||
|
+++ b/src/rpcbind.c
|
||
|
@@ -56,6 +56,9 @@
|
||
|
#include <netinet/in.h>
|
||
|
#endif
|
||
|
#include <arpa/inet.h>
|
||
|
+#ifdef SYSTEMD
|
||
|
+#include <systemd/sd-daemon.h>
|
||
|
+#endif
|
||
|
#include <fcntl.h>
|
||
|
#include <netdb.h>
|
||
|
#include <stdio.h>
|
||
|
@@ -281,6 +284,7 @@ init_transport(struct netconfig *nconf)
|
||
|
u_int32_t host_addr[4]; /* IPv4 or IPv6 */
|
||
|
struct sockaddr_un sun;
|
||
|
mode_t oldmask;
|
||
|
+ int n = 0;
|
||
|
res = NULL;
|
||
|
|
||
|
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
|
||
|
@@ -300,141 +304,285 @@ init_transport(struct netconfig *nconf)
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
- /*
|
||
|
- * XXX - using RPC library internal functions. For NC_TPI_CLTS
|
||
|
- * we call this later, for each socket we like to bind.
|
||
|
- */
|
||
|
- if (nconf->nc_semantics != NC_TPI_CLTS) {
|
||
|
- if ((fd = __rpc_nconf2fd(nconf)) < 0) {
|
||
|
- syslog(LOG_ERR, "cannot create socket for %s",
|
||
|
- nconf->nc_netid);
|
||
|
- return (1);
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
if (!__rpc_nconf2sockinfo(nconf, &si)) {
|
||
|
syslog(LOG_ERR, "cannot get information for %s",
|
||
|
nconf->nc_netid);
|
||
|
return (1);
|
||
|
}
|
||
|
|
||
|
- if ((strcmp(nconf->nc_netid, "local") == 0) ||
|
||
|
- (strcmp(nconf->nc_netid, "unix") == 0)) {
|
||
|
- memset(&sun, 0, sizeof sun);
|
||
|
- sun.sun_family = AF_LOCAL;
|
||
|
- unlink(_PATH_RPCBINDSOCK);
|
||
|
- strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
|
||
|
- addrlen = SUN_LEN(&sun);
|
||
|
- sa = (struct sockaddr *)&sun;
|
||
|
- } else {
|
||
|
- /* Get rpcbind's address on this transport */
|
||
|
-
|
||
|
- memset(&hints, 0, sizeof hints);
|
||
|
- hints.ai_flags = AI_PASSIVE;
|
||
|
- hints.ai_family = si.si_af;
|
||
|
- hints.ai_socktype = si.si_socktype;
|
||
|
- hints.ai_protocol = si.si_proto;
|
||
|
+#ifdef SYSTEMD
|
||
|
+ n = sd_listen_fds(0);
|
||
|
+ if (n < 0) {
|
||
|
+ syslog(LOG_ERR, "failed to acquire systemd scokets: %s", strerror(-n));
|
||
|
+ return 1;
|
||
|
}
|
||
|
- if (nconf->nc_semantics == NC_TPI_CLTS) {
|
||
|
- /*
|
||
|
- * If no hosts were specified, just bind to INADDR_ANY. Otherwise
|
||
|
- * make sure 127.0.0.1 is added to the list.
|
||
|
- */
|
||
|
- nhostsbak = nhosts;
|
||
|
- nhostsbak++;
|
||
|
- hosts = realloc(hosts, nhostsbak * sizeof(char *));
|
||
|
- if (nhostsbak == 1)
|
||
|
- hosts[0] = "*";
|
||
|
- else {
|
||
|
- if (hints.ai_family == AF_INET) {
|
||
|
- hosts[nhostsbak - 1] = "127.0.0.1";
|
||
|
- } else if (hints.ai_family == AF_INET6) {
|
||
|
- hosts[nhostsbak - 1] = "::1";
|
||
|
- } else
|
||
|
- return 1;
|
||
|
+
|
||
|
+ /* Try to find if one of the systemd sockets we were given match
|
||
|
+ * our netconfig structure. */
|
||
|
+
|
||
|
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
|
||
|
+ struct __rpc_sockinfo si_other;
|
||
|
+ union {
|
||
|
+ struct sockaddr sa;
|
||
|
+ struct sockaddr_un un;
|
||
|
+ struct sockaddr_in in4;
|
||
|
+ struct sockaddr_in6 in6;
|
||
|
+ struct sockaddr_storage storage;
|
||
|
+ } sa;
|
||
|
+ socklen_t addrlen = sizeof(sa);
|
||
|
+
|
||
|
+ if (!__rpc_fd2sockinfo(fd, &si_other)) {
|
||
|
+ syslog(LOG_ERR, "cannot get information for fd %i", fd);
|
||
|
+ return 1;
|
||
|
}
|
||
|
|
||
|
- /*
|
||
|
- * Bind to specific IPs if asked to
|
||
|
- */
|
||
|
- checkbind = 0;
|
||
|
- while (nhostsbak > 0) {
|
||
|
- --nhostsbak;
|
||
|
- /*
|
||
|
- * XXX - using RPC library internal functions.
|
||
|
- */
|
||
|
+ if (si.si_af != si_other.si_af ||
|
||
|
+ si.si_socktype != si_other.si_socktype ||
|
||
|
+ si.si_proto != si_other.si_proto)
|
||
|
+ continue;
|
||
|
+
|
||
|
+ if (getsockname(fd, &sa.sa, &addrlen) < 0) {
|
||
|
+ syslog(LOG_ERR, "failed to query socket name: %s",
|
||
|
+ strerror(errno));
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Copy the address */
|
||
|
+ taddr.addr.maxlen = taddr.addr.len = addrlen;
|
||
|
+ taddr.addr.buf = malloc(addrlen);
|
||
|
+ if (taddr.addr.buf == NULL) {
|
||
|
+ syslog(LOG_ERR,
|
||
|
+ "cannot allocate memory for %s address",
|
||
|
+ nconf->nc_netid);
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+ memcpy(taddr.addr.buf, &sa, addrlen);
|
||
|
+
|
||
|
+ my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
|
||
|
+ RPC_MAXDATASIZE, RPC_MAXDATASIZE);
|
||
|
+ if (my_xprt == (SVCXPRT *)NULL) {
|
||
|
+ syslog(LOG_ERR, "%s: could not create service",
|
||
|
+ nconf->nc_netid);
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ /* if none of the systemd sockets matched, we set up the socket in
|
||
|
+ * the normal way:
|
||
|
+ */
|
||
|
+#endif
|
||
|
+
|
||
|
+ if(my_xprt == (SVCXPRT *)NULL) {
|
||
|
+
|
||
|
+ /*
|
||
|
+ * XXX - using RPC library internal functions. For NC_TPI_CLTS
|
||
|
+ * we call this later, for each socket we like to bind.
|
||
|
+ */
|
||
|
+ if (nconf->nc_semantics != NC_TPI_CLTS) {
|
||
|
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
|
||
|
syslog(LOG_ERR, "cannot create socket for %s",
|
||
|
nconf->nc_netid);
|
||
|
return (1);
|
||
|
}
|
||
|
- switch (hints.ai_family) {
|
||
|
- case AF_INET:
|
||
|
- if (inet_pton(AF_INET, hosts[nhostsbak],
|
||
|
- host_addr) == 1) {
|
||
|
- hints.ai_flags &= AI_NUMERICHOST;
|
||
|
- } else {
|
||
|
- /*
|
||
|
- * Skip if we have an AF_INET6 adress.
|
||
|
- */
|
||
|
- if (inet_pton(AF_INET6,
|
||
|
- hosts[nhostsbak], host_addr) == 1)
|
||
|
- continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((strcmp(nconf->nc_netid, "local") == 0) ||
|
||
|
+ (strcmp(nconf->nc_netid, "unix") == 0)) {
|
||
|
+ memset(&sun, 0, sizeof sun);
|
||
|
+ sun.sun_family = AF_LOCAL;
|
||
|
+ unlink(_PATH_RPCBINDSOCK);
|
||
|
+ strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
|
||
|
+ addrlen = SUN_LEN(&sun);
|
||
|
+ sa = (struct sockaddr *)&sun;
|
||
|
+ } else {
|
||
|
+ /* Get rpcbind's address on this transport */
|
||
|
+
|
||
|
+ memset(&hints, 0, sizeof hints);
|
||
|
+ hints.ai_flags = AI_PASSIVE;
|
||
|
+ hints.ai_family = si.si_af;
|
||
|
+ hints.ai_socktype = si.si_socktype;
|
||
|
+ hints.ai_protocol = si.si_proto;
|
||
|
+ }
|
||
|
+ if (nconf->nc_semantics == NC_TPI_CLTS) {
|
||
|
+ /*
|
||
|
+ * If no hosts were specified, just bind to INADDR_ANY. Otherwise
|
||
|
+ * make sure 127.0.0.1 is added to the list.
|
||
|
+ */
|
||
|
+ nhostsbak = nhosts;
|
||
|
+ nhostsbak++;
|
||
|
+ hosts = realloc(hosts, nhostsbak * sizeof(char *));
|
||
|
+ if (nhostsbak == 1)
|
||
|
+ hosts[0] = "*";
|
||
|
+ else {
|
||
|
+ if (hints.ai_family == AF_INET) {
|
||
|
+ hosts[nhostsbak - 1] = "127.0.0.1";
|
||
|
+ } else if (hints.ai_family == AF_INET6) {
|
||
|
+ hosts[nhostsbak - 1] = "::1";
|
||
|
+ } else
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Bind to specific IPs if asked to
|
||
|
+ */
|
||
|
+ checkbind = 0;
|
||
|
+ while (nhostsbak > 0) {
|
||
|
+ --nhostsbak;
|
||
|
+ /*
|
||
|
+ * XXX - using RPC library internal functions.
|
||
|
+ */
|
||
|
+ if ((fd = __rpc_nconf2fd(nconf)) < 0) {
|
||
|
+ syslog(LOG_ERR, "cannot create socket for %s",
|
||
|
+ nconf->nc_netid);
|
||
|
+ return (1);
|
||
|
+ }
|
||
|
+ switch (hints.ai_family) {
|
||
|
+ case AF_INET:
|
||
|
+ if (inet_pton(AF_INET, hosts[nhostsbak],
|
||
|
+ host_addr) == 1) {
|
||
|
+ hints.ai_flags &= AI_NUMERICHOST;
|
||
|
+ } else {
|
||
|
+ /*
|
||
|
+ * Skip if we have an AF_INET6 adress.
|
||
|
+ */
|
||
|
+ if (inet_pton(AF_INET6,
|
||
|
+ hosts[nhostsbak], host_addr) == 1)
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case AF_INET6:
|
||
|
+ if (inet_pton(AF_INET6, hosts[nhostsbak],
|
||
|
+ host_addr) == 1) {
|
||
|
+ hints.ai_flags &= AI_NUMERICHOST;
|
||
|
+ } else {
|
||
|
+ /*
|
||
|
+ * Skip if we have an AF_INET adress.
|
||
|
+ */
|
||
|
+ if (inet_pton(AF_INET, hosts[nhostsbak],
|
||
|
+ host_addr) == 1)
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ break;
|
||
|
}
|
||
|
- break;
|
||
|
- case AF_INET6:
|
||
|
- if (inet_pton(AF_INET6, hosts[nhostsbak],
|
||
|
- host_addr) == 1) {
|
||
|
- hints.ai_flags &= AI_NUMERICHOST;
|
||
|
- } else {
|
||
|
+
|
||
|
+ /*
|
||
|
+ * If no hosts were specified, just bind to INADDR_ANY
|
||
|
+ */
|
||
|
+ if (strcmp("*", hosts[nhostsbak]) == 0)
|
||
|
+ hosts[nhostsbak] = NULL;
|
||
|
+
|
||
|
+ if ((aicode = getaddrinfo(hosts[nhostsbak],
|
||
|
+ servname, &hints, &res)) != 0) {
|
||
|
+ if ((aicode = getaddrinfo(hosts[nhostsbak],
|
||
|
+ "portmapper", &hints, &res)) != 0) {
|
||
|
+ syslog(LOG_ERR,
|
||
|
+ "cannot get local address for %s: %s",
|
||
|
+ nconf->nc_netid, gai_strerror(aicode));
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ addrlen = res->ai_addrlen;
|
||
|
+ sa = (struct sockaddr *)res->ai_addr;
|
||
|
+ oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
|
||
|
+ if (bind(fd, sa, addrlen) != 0) {
|
||
|
+ syslog(LOG_ERR, "cannot bind %s on %s: %m",
|
||
|
+ (hosts[nhostsbak] == NULL) ? "*" :
|
||
|
+ hosts[nhostsbak], nconf->nc_netid);
|
||
|
+ if (res != NULL)
|
||
|
+ freeaddrinfo(res);
|
||
|
+ continue;
|
||
|
+ } else
|
||
|
+ checkbind++;
|
||
|
+ (void) umask(oldmask);
|
||
|
+
|
||
|
+ /* Copy the address */
|
||
|
+ taddr.addr.maxlen = taddr.addr.len = addrlen;
|
||
|
+ taddr.addr.buf = malloc(addrlen);
|
||
|
+ if (taddr.addr.buf == NULL) {
|
||
|
+ syslog(LOG_ERR,
|
||
|
+ "cannot allocate memory for %s address",
|
||
|
+ nconf->nc_netid);
|
||
|
+ if (res != NULL)
|
||
|
+ freeaddrinfo(res);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ memcpy(taddr.addr.buf, sa, addrlen);
|
||
|
+#ifdef RPCBIND_DEBUG
|
||
|
+ if (debugging) {
|
||
|
/*
|
||
|
- * Skip if we have an AF_INET adress.
|
||
|
+ * for debugging print out our universal
|
||
|
+ * address
|
||
|
*/
|
||
|
- if (inet_pton(AF_INET, hosts[nhostsbak],
|
||
|
- host_addr) == 1)
|
||
|
- continue;
|
||
|
+ char *uaddr;
|
||
|
+ struct netbuf nb;
|
||
|
+ int sa_size = 0;
|
||
|
+
|
||
|
+ nb.buf = sa;
|
||
|
+ switch( sa->sa_family){
|
||
|
+ case AF_INET:
|
||
|
+ sa_size = sizeof (struct sockaddr_in);
|
||
|
+ break;
|
||
|
+ case AF_INET6:
|
||
|
+ sa_size = sizeof (struct sockaddr_in6);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ nb.len = nb.maxlen = sa_size;
|
||
|
+ uaddr = taddr2uaddr(nconf, &nb);
|
||
|
+ (void) fprintf(stderr,
|
||
|
+ "rpcbind : my address is %s\n", uaddr);
|
||
|
+ (void) free(uaddr);
|
||
|
+ }
|
||
|
+#endif
|
||
|
+ my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
|
||
|
+ RPC_MAXDATASIZE, RPC_MAXDATASIZE);
|
||
|
+ if (my_xprt == (SVCXPRT *)NULL) {
|
||
|
+ syslog(LOG_ERR, "%s: could not create service",
|
||
|
+ nconf->nc_netid);
|
||
|
+ goto error;
|
||
|
}
|
||
|
- break;
|
||
|
- default:
|
||
|
- break;
|
||
|
}
|
||
|
-
|
||
|
- /*
|
||
|
- * If no hosts were specified, just bind to INADDR_ANY
|
||
|
- */
|
||
|
- if (strcmp("*", hosts[nhostsbak]) == 0)
|
||
|
- hosts[nhostsbak] = NULL;
|
||
|
-
|
||
|
- if ((aicode = getaddrinfo(hosts[nhostsbak],
|
||
|
- servname, &hints, &res)) != 0) {
|
||
|
- if ((aicode = getaddrinfo(hosts[nhostsbak],
|
||
|
- "portmapper", &hints, &res)) != 0) {
|
||
|
- syslog(LOG_ERR,
|
||
|
- "cannot get local address for %s: %s",
|
||
|
- nconf->nc_netid, gai_strerror(aicode));
|
||
|
- continue;
|
||
|
- }
|
||
|
+ if (!checkbind)
|
||
|
+ return 1;
|
||
|
+ } else { /* NC_TPI_COTS */
|
||
|
+ if ((strcmp(nconf->nc_netid, "local") != 0) &&
|
||
|
+ (strcmp(nconf->nc_netid, "unix") != 0)) {
|
||
|
+ if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
|
||
|
+ if ((aicode = getaddrinfo(NULL, "portmapper", &hints, &res))!= 0) {
|
||
|
+ printf("cannot get local address for %s: %s", nconf->nc_netid, gai_strerror(aicode));
|
||
|
+ syslog(LOG_ERR,
|
||
|
+ "cannot get local address for %s: %s",
|
||
|
+ nconf->nc_netid, gai_strerror(aicode));
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ addrlen = res->ai_addrlen;
|
||
|
+ sa = (struct sockaddr *)res->ai_addr;
|
||
|
}
|
||
|
- addrlen = res->ai_addrlen;
|
||
|
- sa = (struct sockaddr *)res->ai_addr;
|
||
|
oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
|
||
|
- if (bind(fd, sa, addrlen) != 0) {
|
||
|
- syslog(LOG_ERR, "cannot bind %s on %s: %m",
|
||
|
- (hosts[nhostsbak] == NULL) ? "*" :
|
||
|
- hosts[nhostsbak], nconf->nc_netid);
|
||
|
+ __rpc_fd2sockinfo(fd, &si);
|
||
|
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
|
||
|
+ sizeof(on)) != 0) {
|
||
|
+ syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
|
||
|
+ nconf->nc_netid);
|
||
|
if (res != NULL)
|
||
|
freeaddrinfo(res);
|
||
|
- continue;
|
||
|
- } else
|
||
|
- checkbind++;
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ if (bind(fd, sa, addrlen) < 0) {
|
||
|
+ syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
|
||
|
+ if (res != NULL)
|
||
|
+ freeaddrinfo(res);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
(void) umask(oldmask);
|
||
|
|
||
|
/* Copy the address */
|
||
|
- taddr.addr.maxlen = taddr.addr.len = addrlen;
|
||
|
+ taddr.addr.len = taddr.addr.maxlen = addrlen;
|
||
|
taddr.addr.buf = malloc(addrlen);
|
||
|
if (taddr.addr.buf == NULL) {
|
||
|
- syslog(LOG_ERR,
|
||
|
- "cannot allocate memory for %s address",
|
||
|
+ syslog(LOG_ERR, "cannot allocate memory for %s address",
|
||
|
nconf->nc_netid);
|
||
|
if (res != NULL)
|
||
|
freeaddrinfo(res);
|
||
|
@@ -443,116 +591,37 @@ init_transport(struct netconfig *nconf)
|
||
|
memcpy(taddr.addr.buf, sa, addrlen);
|
||
|
#ifdef RPCBIND_DEBUG
|
||
|
if (debugging) {
|
||
|
- /*
|
||
|
- * for debugging print out our universal
|
||
|
- * address
|
||
|
- */
|
||
|
+ /* for debugging print out our universal address */
|
||
|
char *uaddr;
|
||
|
struct netbuf nb;
|
||
|
- int sa_size = 0;
|
||
|
+ int sa_size2 = 0;
|
||
|
|
||
|
nb.buf = sa;
|
||
|
switch( sa->sa_family){
|
||
|
case AF_INET:
|
||
|
- sa_size = sizeof (struct sockaddr_in);
|
||
|
+ sa_size2 = sizeof (struct sockaddr_in);
|
||
|
break;
|
||
|
case AF_INET6:
|
||
|
- sa_size = sizeof (struct sockaddr_in6);
|
||
|
+ sa_size2 = sizeof (struct sockaddr_in6);
|
||
|
break;
|
||
|
}
|
||
|
- nb.len = nb.maxlen = sa_size;
|
||
|
+ nb.len = nb.maxlen = sa_size2;
|
||
|
uaddr = taddr2uaddr(nconf, &nb);
|
||
|
- (void) fprintf(stderr,
|
||
|
- "rpcbind : my address is %s\n", uaddr);
|
||
|
+ (void) fprintf(stderr, "rpcbind : my address is %s\n",
|
||
|
+ uaddr);
|
||
|
(void) free(uaddr);
|
||
|
}
|
||
|
#endif
|
||
|
- my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
|
||
|
- RPC_MAXDATASIZE, RPC_MAXDATASIZE);
|
||
|
+
|
||
|
+ listen(fd, SOMAXCONN);
|
||
|
+
|
||
|
+ my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
|
||
|
if (my_xprt == (SVCXPRT *)NULL) {
|
||
|
- syslog(LOG_ERR, "%s: could not create service",
|
||
|
- nconf->nc_netid);
|
||
|
+ syslog(LOG_ERR, "%s: could not create service",
|
||
|
+ nconf->nc_netid);
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
- if (!checkbind)
|
||
|
- return 1;
|
||
|
- } else { /* NC_TPI_COTS */
|
||
|
- if ((strcmp(nconf->nc_netid, "local") != 0) &&
|
||
|
- (strcmp(nconf->nc_netid, "unix") != 0)) {
|
||
|
- if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
|
||
|
- if ((aicode = getaddrinfo(NULL, "portmapper", &hints, &res))!= 0) {
|
||
|
- printf("cannot get local address for %s: %s", nconf->nc_netid, gai_strerror(aicode));
|
||
|
- syslog(LOG_ERR,
|
||
|
- "cannot get local address for %s: %s",
|
||
|
- nconf->nc_netid, gai_strerror(aicode));
|
||
|
- return 1;
|
||
|
- }
|
||
|
- }
|
||
|
- addrlen = res->ai_addrlen;
|
||
|
- sa = (struct sockaddr *)res->ai_addr;
|
||
|
- }
|
||
|
- oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
|
||
|
- __rpc_fd2sockinfo(fd, &si);
|
||
|
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
|
||
|
- sizeof(on)) != 0) {
|
||
|
- syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
|
||
|
- nconf->nc_netid);
|
||
|
- if (res != NULL)
|
||
|
- freeaddrinfo(res);
|
||
|
- return 1;
|
||
|
- }
|
||
|
- if (bind(fd, sa, addrlen) < 0) {
|
||
|
- syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
|
||
|
- if (res != NULL)
|
||
|
- freeaddrinfo(res);
|
||
|
- return 1;
|
||
|
- }
|
||
|
- (void) umask(oldmask);
|
||
|
-
|
||
|
- /* Copy the address */
|
||
|
- taddr.addr.len = taddr.addr.maxlen = addrlen;
|
||
|
- taddr.addr.buf = malloc(addrlen);
|
||
|
- if (taddr.addr.buf == NULL) {
|
||
|
- syslog(LOG_ERR, "cannot allocate memory for %s address",
|
||
|
- nconf->nc_netid);
|
||
|
- if (res != NULL)
|
||
|
- freeaddrinfo(res);
|
||
|
- return 1;
|
||
|
- }
|
||
|
- memcpy(taddr.addr.buf, sa, addrlen);
|
||
|
-#ifdef RPCBIND_DEBUG
|
||
|
- if (debugging) {
|
||
|
- /* for debugging print out our universal address */
|
||
|
- char *uaddr;
|
||
|
- struct netbuf nb;
|
||
|
- int sa_size2 = 0;
|
||
|
-
|
||
|
- nb.buf = sa;
|
||
|
- switch( sa->sa_family){
|
||
|
- case AF_INET:
|
||
|
- sa_size2 = sizeof (struct sockaddr_in);
|
||
|
- break;
|
||
|
- case AF_INET6:
|
||
|
- sa_size2 = sizeof (struct sockaddr_in6);
|
||
|
- break;
|
||
|
- }
|
||
|
- nb.len = nb.maxlen = sa_size2;
|
||
|
- uaddr = taddr2uaddr(nconf, &nb);
|
||
|
- (void) fprintf(stderr, "rpcbind : my address is %s\n",
|
||
|
- uaddr);
|
||
|
- (void) free(uaddr);
|
||
|
- }
|
||
|
-#endif
|
||
|
-
|
||
|
- listen(fd, SOMAXCONN);
|
||
|
-
|
||
|
- my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
|
||
|
- if (my_xprt == (SVCXPRT *)NULL) {
|
||
|
- syslog(LOG_ERR, "%s: could not create service",
|
||
|
- nconf->nc_netid);
|
||
|
- goto error;
|
||
|
- }
|
||
|
}
|
||
|
|
||
|
#ifdef PORTMAP
|
||
|
diff --git a/systemd/.gitignore b/systemd/.gitignore
|
||
|
new file mode 100644
|
||
|
index 0000000..b7b4561
|
||
|
--- /dev/null
|
||
|
+++ b/systemd/.gitignore
|
||
|
@@ -0,0 +1 @@
|
||
|
+rpcbind.service
|
||
|
diff --git a/systemd/rpcbind.service.in b/systemd/rpcbind.service.in
|
||
|
new file mode 100644
|
||
|
index 0000000..58ae5de
|
||
|
--- /dev/null
|
||
|
+++ b/systemd/rpcbind.service.in
|
||
|
@@ -0,0 +1,9 @@
|
||
|
+[Unit]
|
||
|
+Description=RPC Bind
|
||
|
+
|
||
|
+[Service]
|
||
|
+ExecStart=@bindir@/rpcbind -w -f
|
||
|
+
|
||
|
+[Install]
|
||
|
+WantedBy=multi-user.target
|
||
|
+Also=rpcbind.socket
|
||
|
diff --git a/systemd/rpcbind.socket b/systemd/rpcbind.socket
|
||
|
new file mode 100644
|
||
|
index 0000000..ad5fd62
|
||
|
--- /dev/null
|
||
|
+++ b/systemd/rpcbind.socket
|
||
|
@@ -0,0 +1,12 @@
|
||
|
+[Unit]
|
||
|
+Description=RPCbind Server Activation Socket
|
||
|
+Wants=rpcbind.target
|
||
|
+Before=rpcbind.target
|
||
|
+
|
||
|
+[Socket]
|
||
|
+ListenStream=/var/run/rpcbind.sock
|
||
|
+ListenStream=111
|
||
|
+ListenDatagram=111
|
||
|
+
|
||
|
+[Install]
|
||
|
+WantedBy=sockets.target
|
||
|
--
|
||
|
1.7.8
|
||
|
|