summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/rpc.lockd/lockd.c107
-rw-r--r--usr.sbin/rpc.statd/file.c30
2 files changed, 92 insertions, 45 deletions
diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c
index f2fedce..c111b58 100644
--- a/usr.sbin/rpc.lockd/lockd.c
+++ b/usr.sbin/rpc.lockd/lockd.c
@@ -80,6 +80,7 @@ int _rpcsvcdirty = 0;
int grace_expired;
int nsm_state;
int kernel_lockd;
+int kernel_lockd_client;
pid_t client_pid;
struct mon mon_host;
char **hosts, *svcport_str = NULL;
@@ -175,6 +176,7 @@ main(int argc, char **argv)
}
kernel_lockd = FALSE;
+ kernel_lockd_client = FALSE;
if (modfind("nfslockd") < 0) {
if (kldload("nfslockd") < 0) {
fprintf(stderr, "Can't find or load kernel support for rpc.lockd - using non-kernel implementation\n");
@@ -184,6 +186,10 @@ main(int argc, char **argv)
} else {
kernel_lockd = TRUE;
}
+ if (kernel_lockd) {
+ if (getosreldate() >= 800040)
+ kernel_lockd_client = TRUE;
+ }
(void)rpcb_unset(NLM_PROG, NLM_SM, NULL);
(void)rpcb_unset(NLM_PROG, NLM_VERS, NULL);
@@ -245,41 +251,42 @@ main(int argc, char **argv)
}
if (kernel_lockd) {
- /*
- * For the kernel lockd case, we run a cut-down RPC
- * service on a local-domain socket. The kernel's RPC
- * server will pass what it can't handle (mainly
- * client replies) down to us. This can go away
- * entirely if/when we move the client side of NFS
- * locking into the kernel.
- */
- struct sockaddr_un sun;
- int fd, oldmask;
- SVCXPRT *xprt;
-
- memset(&sun, 0, sizeof sun);
- sun.sun_family = AF_LOCAL;
- unlink(_PATH_RPCLOCKDSOCK);
- strcpy(sun.sun_path, _PATH_RPCLOCKDSOCK);
- sun.sun_len = SUN_LEN(&sun);
- fd = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (!fd) {
- err(1, "Can't create local lockd socket");
- }
- oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
- if (bind(fd, (struct sockaddr *) &sun, sun.sun_len) < 0) {
- err(1, "Can't bind local lockd socket");
- }
- umask(oldmask);
- if (listen(fd, SOMAXCONN) < 0) {
- err(1, "Can't listen on local lockd socket");
- }
- xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
- if (!xprt) {
- err(1, "Can't create transport for local lockd socket");
- }
- if (!svc_reg(xprt, NLM_PROG, NLM_VERS4, nlm_prog_4, NULL)) {
- err(1, "Can't register service for local lockd socket");
+ if (!kernel_lockd_client) {
+ /*
+ * For the case where we have a kernel lockd but it
+ * doesn't provide client locking, we run a cut-down
+ * RPC service on a local-domain socket. The kernel's
+ * RPC server will pass what it can't handle (mainly
+ * client replies) down to us.
+ */
+ struct sockaddr_un sun;
+ int fd, oldmask;
+ SVCXPRT *xprt;
+
+ memset(&sun, 0, sizeof sun);
+ sun.sun_family = AF_LOCAL;
+ unlink(_PATH_RPCLOCKDSOCK);
+ strcpy(sun.sun_path, _PATH_RPCLOCKDSOCK);
+ sun.sun_len = SUN_LEN(&sun);
+ fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (!fd) {
+ err(1, "Can't create local lockd socket");
+ }
+ oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
+ if (bind(fd, (struct sockaddr *) &sun, sun.sun_len) < 0) {
+ err(1, "Can't bind local lockd socket");
+ }
+ umask(oldmask);
+ if (listen(fd, SOMAXCONN) < 0) {
+ err(1, "Can't listen on local lockd socket");
+ }
+ xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+ if (!xprt) {
+ err(1, "Can't create transport for local lockd socket");
+ }
+ if (!svc_reg(xprt, NLM_PROG, NLM_VERS4, nlm_prog_4, NULL)) {
+ err(1, "Can't register service for local lockd socket");
+ }
}
/*
@@ -342,17 +349,27 @@ main(int argc, char **argv)
}
if (kernel_lockd) {
- init_nsm();
- client_pid = client_request();
-
- /*
- * Create a child process to enter the kernel and then
- * wait for RPCs on our local domain socket.
- */
- if (!fork())
+ if (!kernel_lockd_client) {
+ init_nsm();
+ client_pid = client_request();
+
+ /*
+ * Create a child process to enter the kernel and then
+ * wait for RPCs on our local domain socket.
+ */
+ if (!fork())
+ nlm_syscall(debug_level, grace_period,
+ naddrs, addrs);
+ else
+ svc_run();
+ } else {
+ /*
+ * The kernel lockd implementation provides
+ * both client and server so we don't need to
+ * do anything else.
+ */
nlm_syscall(debug_level, grace_period, naddrs, addrs);
- else
- svc_run();
+ }
} else {
grace_expired = 0;
alarm(grace_period);
diff --git a/usr.sbin/rpc.statd/file.c b/usr.sbin/rpc.statd/file.c
index efcaaaf..0625e30 100644
--- a/usr.sbin/rpc.statd/file.c
+++ b/usr.sbin/rpc.statd/file.c
@@ -36,6 +36,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -78,8 +79,11 @@ HostInfo *find_host(char *hostname, int create)
HostInfo *hp;
HostInfo *spare_slot = NULL;
HostInfo *result = NULL;
+ struct addrinfo *ai1, *ai2;
int i;
+ if (getaddrinfo(hostname, NULL, NULL, &ai1) != 0)
+ ai1 = NULL;
for (i = 0, hp = status_info->hosts; i < status_info->noOfHosts; i++, hp++)
{
if (!strncasecmp(hostname, hp->hostname, SM_MAXSTRLEN))
@@ -87,9 +91,35 @@ HostInfo *find_host(char *hostname, int create)
result = hp;
break;
}
+ if (hp->hostname[0] &&
+ getaddrinfo(hp->hostname, NULL, NULL, &ai2) != 0)
+ ai2 = NULL;
+ if (ai1 && ai2)
+ {
+ struct addrinfo *p1, *p2;
+ for (p1 = ai1; !result && p1; p1 = p1->ai_next)
+ {
+ for (p2 = ai2; !result && p2; p2 = p2->ai_next)
+ {
+ if (p1->ai_family == p2->ai_family
+ && p1->ai_addrlen == p2->ai_addrlen
+ && !memcmp(p1->ai_addr, p2->ai_addr, p1->ai_addrlen))
+ {
+ result = hp;
+ break;
+ }
+ }
+ }
+ if (result)
+ break;
+ }
+ if (ai2)
+ freeaddrinfo(ai2);
if (!spare_slot && !hp->monList && !hp->notifyReqd)
spare_slot = hp;
}
+ if (ai1)
+ freeaddrinfo(ai1);
/* Return if entry found, or if not asked to create one. */
if (result || !create) return (result);
OpenPOWER on IntegriCloud