diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/rpc.lockd/lockd.c | 107 | ||||
-rw-r--r-- | usr.sbin/rpc.statd/file.c | 30 |
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); |