xref: /illumos-gate/usr/src/cmd/fs.d/nfs/nfs4cbd/nfs4cbd.c (revision 11606941)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*11606941Sjwahlig  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
327c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate /*
387c478bd9Sstevel@tonic-gate  * This module provides the user level support for the NFSv4
397c478bd9Sstevel@tonic-gate  * callback program.  It is modeled after nfsd.  When a nfsv4
407c478bd9Sstevel@tonic-gate  * mount occurs, the mount command forks and the child runs
417c478bd9Sstevel@tonic-gate  * start_nfs4_callback.  If this is the first mount, then the
427c478bd9Sstevel@tonic-gate  * process will hang around listening for incoming connection
437c478bd9Sstevel@tonic-gate  * requests from the nfsv4 server.
447c478bd9Sstevel@tonic-gate  *
457c478bd9Sstevel@tonic-gate  * For connection-less protocols, the krpc is started immediately.
467c478bd9Sstevel@tonic-gate  * For connection oriented protocols, the kernel module is informed
477c478bd9Sstevel@tonic-gate  * of netid and universal address that it can give this
487c478bd9Sstevel@tonic-gate  * information to the server during setclientid.
497c478bd9Sstevel@tonic-gate  */
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #include <sys/param.h>
527c478bd9Sstevel@tonic-gate #include <sys/types.h>
537c478bd9Sstevel@tonic-gate #include <syslog.h>
547c478bd9Sstevel@tonic-gate #include <tiuser.h>
557c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
567c478bd9Sstevel@tonic-gate #include <errno.h>
577c478bd9Sstevel@tonic-gate #include <thread.h>
587c478bd9Sstevel@tonic-gate #include <sys/resource.h>
597c478bd9Sstevel@tonic-gate #include <sys/file.h>
607c478bd9Sstevel@tonic-gate #include <nfs/nfs.h>
617c478bd9Sstevel@tonic-gate #include <nfs/nfssys.h>
627c478bd9Sstevel@tonic-gate #include <stdio.h>
637c478bd9Sstevel@tonic-gate #include <stdlib.h>
647c478bd9Sstevel@tonic-gate #include <netconfig.h>
657c478bd9Sstevel@tonic-gate #include <netdir.h>
667c478bd9Sstevel@tonic-gate #include <string.h>
677c478bd9Sstevel@tonic-gate #include <unistd.h>
687c478bd9Sstevel@tonic-gate #include <stropts.h>
697c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
707c478bd9Sstevel@tonic-gate #include <netinet/tcp.h>
717c478bd9Sstevel@tonic-gate #include "nfs_tbind.h"
727c478bd9Sstevel@tonic-gate #include "thrpool.h"
737c478bd9Sstevel@tonic-gate #include <rpcsvc/nfs4_prot.h>
747c478bd9Sstevel@tonic-gate #include <netdb.h>
757c478bd9Sstevel@tonic-gate #include <signal.h>
767c478bd9Sstevel@tonic-gate #include <strings.h>
777c478bd9Sstevel@tonic-gate #include <priv_utils.h>
787c478bd9Sstevel@tonic-gate #include <rpcsvc/daemon_utils.h>
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate static	int	nfs4svc(int, struct netbuf *, struct netconfig *, int,
817c478bd9Sstevel@tonic-gate 		struct netbuf *);
827c478bd9Sstevel@tonic-gate extern	int	_nfssys(int, void *);
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate static	char	*MyName;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /*
877c478bd9Sstevel@tonic-gate  * The following are all globals used by routines in nfs_tbind.c.
887c478bd9Sstevel@tonic-gate  */
897c478bd9Sstevel@tonic-gate size_t	end_listen_fds;		/* used by conn_close_oldest() */
907c478bd9Sstevel@tonic-gate size_t	num_fds = 0;		/* used by multiple routines */
917c478bd9Sstevel@tonic-gate int	listen_backlog = 32;	/* used by bind_to_{provider,proto}() */
927c478bd9Sstevel@tonic-gate int	num_servers;		/* used by cots_listen_event() */
937c478bd9Sstevel@tonic-gate int	(*Mysvc)(int, struct netbuf, struct netconfig *) = NULL;
947c478bd9Sstevel@tonic-gate 				/* used by cots_listen_event() */
957c478bd9Sstevel@tonic-gate int	max_conns_allowed = -1;	/* used by cots_listen_event() */
967c478bd9Sstevel@tonic-gate 
97*11606941Sjwahlig int
98*11606941Sjwahlig main(int argc, char *argv[])
997c478bd9Sstevel@tonic-gate {
1007c478bd9Sstevel@tonic-gate 	int pid;
1017c478bd9Sstevel@tonic-gate 	int i;
1027c478bd9Sstevel@tonic-gate 	struct protob *protobp;
1037c478bd9Sstevel@tonic-gate 	struct flock f;
1047c478bd9Sstevel@tonic-gate 	pid_t pi;
1057c478bd9Sstevel@tonic-gate 	struct svcpool_args cb_svcpool;
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	MyName = "nfs4cbd";
1087c478bd9Sstevel@tonic-gate 	Mysvc4 = nfs4svc;
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate #ifndef	DEBUG
1117c478bd9Sstevel@tonic-gate 	/*
1127c478bd9Sstevel@tonic-gate 	 * Close existing file descriptors, open "/dev/null" as
1137c478bd9Sstevel@tonic-gate 	 * standard input, output, and error, and detach from
1147c478bd9Sstevel@tonic-gate 	 * controlling terminal.
1157c478bd9Sstevel@tonic-gate 	 */
1167c478bd9Sstevel@tonic-gate 	closefrom(0);
1177c478bd9Sstevel@tonic-gate 	(void) open("/dev/null", O_RDONLY);
1187c478bd9Sstevel@tonic-gate 	(void) open("/dev/null", O_WRONLY);
1197c478bd9Sstevel@tonic-gate 	(void) dup(1);
1207c478bd9Sstevel@tonic-gate 	(void) setsid();
1217c478bd9Sstevel@tonic-gate #endif
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	/*
1247c478bd9Sstevel@tonic-gate 	 * create a child to continue our work
1257c478bd9Sstevel@tonic-gate 	 * Parent's exit will tell mount command we're ready to go
1267c478bd9Sstevel@tonic-gate 	 */
1277c478bd9Sstevel@tonic-gate 	if ((pi = fork()) > 0) {
1287c478bd9Sstevel@tonic-gate 		exit(0);
1297c478bd9Sstevel@tonic-gate 	}
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	if (pi == -1) {
1327c478bd9Sstevel@tonic-gate 		(void) syslog(LOG_ERR,
1337c478bd9Sstevel@tonic-gate 			"Could not start NFS4_CALLBACK service");
1347c478bd9Sstevel@tonic-gate 		exit(1);
1357c478bd9Sstevel@tonic-gate 	}
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	(void) _create_daemon_lock(NFS4CBD, DAEMON_UID, DAEMON_GID);
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	svcsetprio();
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET,
1427c478bd9Sstevel@tonic-gate 	    DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS, (char *)NULL) == -1) {
1437c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s must be run with sufficient"
1447c478bd9Sstevel@tonic-gate 			" privileges\n", argv[0]);
1457c478bd9Sstevel@tonic-gate 		exit(1);
1467c478bd9Sstevel@tonic-gate 	}
1477c478bd9Sstevel@tonic-gate 	/* Basic privileges we don't need, remove from E/P. */
1487c478bd9Sstevel@tonic-gate 	__fini_daemon_priv(PRIV_PROC_EXEC, PRIV_PROC_FORK, PRIV_FILE_LINK_ANY,
1497c478bd9Sstevel@tonic-gate 	    PRIV_PROC_SESSION, PRIV_PROC_INFO, (char *)NULL);
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	/*
1527c478bd9Sstevel@tonic-gate 	 * establish our lock on the lock file and write our pid to it.
1537c478bd9Sstevel@tonic-gate 	 * exit if some other process holds the lock, or if there's any
1547c478bd9Sstevel@tonic-gate 	 * error in writing/locking the file.
1557c478bd9Sstevel@tonic-gate 	 */
1567c478bd9Sstevel@tonic-gate 	pid = _enter_daemon_lock(NFS4CBD);
1577c478bd9Sstevel@tonic-gate 	switch (pid) {
1587c478bd9Sstevel@tonic-gate 	case 0:
1597c478bd9Sstevel@tonic-gate 		break;
1607c478bd9Sstevel@tonic-gate 	case -1:
1617c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, "error locking for %s: %s", NFS4CBD,
1627c478bd9Sstevel@tonic-gate 		    strerror(errno));
1637c478bd9Sstevel@tonic-gate 		exit(2);
1647c478bd9Sstevel@tonic-gate 	default:
1657c478bd9Sstevel@tonic-gate 		/* daemon was already running */
1667c478bd9Sstevel@tonic-gate 		exit(0);
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON);
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	cb_svcpool.id = NFS_CB_SVCPOOL_ID;
1727c478bd9Sstevel@tonic-gate 	cb_svcpool.maxthreads = 0;
1737c478bd9Sstevel@tonic-gate 	cb_svcpool.redline = 0;
1747c478bd9Sstevel@tonic-gate 	cb_svcpool.qsize = 0;
1757c478bd9Sstevel@tonic-gate 	cb_svcpool.timeout = 0;
1767c478bd9Sstevel@tonic-gate 	cb_svcpool.stksize = 0;
1777c478bd9Sstevel@tonic-gate 	cb_svcpool.max_same_xprt = 0;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	/* create a SVC_POOL for the nfsv4 callback deamon */
1807c478bd9Sstevel@tonic-gate 	if (_nfssys(SVCPOOL_CREATE, &cb_svcpool)) {
1817c478bd9Sstevel@tonic-gate 		(void) syslog(LOG_ERR, "can't setup NFS_CB SVCPOOL: Exiting");
1827c478bd9Sstevel@tonic-gate 		exit(1);
1837c478bd9Sstevel@tonic-gate 	}
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	/*
1867c478bd9Sstevel@tonic-gate 	 * Set up blocked thread to do LWP creation on behalf of the kernel.
1877c478bd9Sstevel@tonic-gate 	 */
1887c478bd9Sstevel@tonic-gate 	if (svcwait(NFS_CB_SVCPOOL_ID)) {
1897c478bd9Sstevel@tonic-gate 		(void) syslog(LOG_ERR,
1907c478bd9Sstevel@tonic-gate 		    "Can't set up NFS_CB LWP creator: Exiting");
1917c478bd9Sstevel@tonic-gate 		exit(1);
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	/*
1967c478bd9Sstevel@tonic-gate 	 * Build a protocol block list for registration.
1977c478bd9Sstevel@tonic-gate 	 */
1987c478bd9Sstevel@tonic-gate 	protobp = (struct protob *)malloc(sizeof (struct protob));
1997c478bd9Sstevel@tonic-gate 	protobp->serv = "NFS4_CALLBACK";
2007c478bd9Sstevel@tonic-gate 	protobp->versmin = NFS_CB;
2017c478bd9Sstevel@tonic-gate 	protobp->versmax = NFS_CB;
2027c478bd9Sstevel@tonic-gate 	protobp->program = NFS4_CALLBACK;
2037c478bd9Sstevel@tonic-gate 	protobp->next = NULL;
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	if (do_all(protobp, NULL) == -1) {
2067c478bd9Sstevel@tonic-gate 		exit(1);
2077c478bd9Sstevel@tonic-gate 	}
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 	free(protobp);
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	if (num_fds == 0) {
2127c478bd9Sstevel@tonic-gate 		(void) syslog(LOG_ERR,
2137c478bd9Sstevel@tonic-gate 		"Could not start NFS4_CALLBACK service for any protocol");
2147c478bd9Sstevel@tonic-gate 		exit(1);
2157c478bd9Sstevel@tonic-gate 	}
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	end_listen_fds = num_fds;
2187c478bd9Sstevel@tonic-gate 	/*
2197c478bd9Sstevel@tonic-gate 	 * Poll for non-data control events on the transport descriptors.
2207c478bd9Sstevel@tonic-gate 	 */
2217c478bd9Sstevel@tonic-gate 	poll_for_action();
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	/*
2247c478bd9Sstevel@tonic-gate 	 * If we get here, something failed in poll_for_action().
2257c478bd9Sstevel@tonic-gate 	 */
2267c478bd9Sstevel@tonic-gate 	return (1);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate char *
2307c478bd9Sstevel@tonic-gate get_uaddr(int fd, struct netconfig *nconf, struct netbuf *nb)
2317c478bd9Sstevel@tonic-gate {
2327c478bd9Sstevel@tonic-gate 	struct nfs_svc_args nsa;
2337c478bd9Sstevel@tonic-gate 	char *ua, *ua2, *mua = NULL;
2347c478bd9Sstevel@tonic-gate 	char me[MAXHOSTNAMELEN];
2357c478bd9Sstevel@tonic-gate 	struct nd_addrlist *nas;
2367c478bd9Sstevel@tonic-gate 	struct nd_hostserv hs;
2377c478bd9Sstevel@tonic-gate 	struct nd_mergearg ma;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	ua = taddr2uaddr(nconf, nb);
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	if (ua == NULL) {
2427c478bd9Sstevel@tonic-gate #ifdef	DEBUG
2437c478bd9Sstevel@tonic-gate 		fprintf(stderr, "taddr2uaddr failed for netid %s\n",
2447c478bd9Sstevel@tonic-gate 			nconf->nc_netid);
2457c478bd9Sstevel@tonic-gate #endif
2467c478bd9Sstevel@tonic-gate 		return (NULL);
2477c478bd9Sstevel@tonic-gate 	}
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 	gethostname(me, MAXHOSTNAMELEN);
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	hs.h_host = me;
2527c478bd9Sstevel@tonic-gate 	hs.h_serv = "nfs";
2537c478bd9Sstevel@tonic-gate 	if (netdir_getbyname(nconf, &hs, &nas)) {
2547c478bd9Sstevel@tonic-gate #ifdef DEBUG
2557c478bd9Sstevel@tonic-gate 		netdir_perror("netdir_getbyname");
2567c478bd9Sstevel@tonic-gate #endif
2577c478bd9Sstevel@tonic-gate 		return (NULL);
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	ua2 = taddr2uaddr(nconf, nas->n_addrs);
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 	if (ua2 == NULL) {
2637c478bd9Sstevel@tonic-gate #ifdef	DEBUG
2647c478bd9Sstevel@tonic-gate 		fprintf(stderr, "taddr2uaddr failed for netid %s.\n",
2657c478bd9Sstevel@tonic-gate 			nconf->nc_netid);
2667c478bd9Sstevel@tonic-gate #endif
2677c478bd9Sstevel@tonic-gate 		return (NULL);
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	ma.s_uaddr = ua;
2717c478bd9Sstevel@tonic-gate 	ma.c_uaddr = ua2;
2727c478bd9Sstevel@tonic-gate 	ma.m_uaddr = NULL;
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	if (netdir_options(nconf, ND_MERGEADDR, 0, (char *)&ma)) {
2757c478bd9Sstevel@tonic-gate #ifdef DEBUG
2767c478bd9Sstevel@tonic-gate 		netdir_perror("netdir_options");
2777c478bd9Sstevel@tonic-gate #endif
2787c478bd9Sstevel@tonic-gate 		return (NULL);
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	mua = ma.m_uaddr;
2827c478bd9Sstevel@tonic-gate 	return (mua);
2837c478bd9Sstevel@tonic-gate }
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate /*
2867c478bd9Sstevel@tonic-gate  * Establish NFS4 callback service thread.
2877c478bd9Sstevel@tonic-gate  */
2887c478bd9Sstevel@tonic-gate static int
2897c478bd9Sstevel@tonic-gate nfs4svc(int fd, struct netbuf *addrmask, struct netconfig *nconf,
2907c478bd9Sstevel@tonic-gate 	int cmd, struct netbuf *addr)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate 	struct nfs4_svc_args nsa;
2937c478bd9Sstevel@tonic-gate 	char *ua;
2947c478bd9Sstevel@tonic-gate 	int error;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	ua = get_uaddr(fd, nconf, addr);
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	if (ua == NULL) {
2997c478bd9Sstevel@tonic-gate 		syslog(LOG_NOTICE, "nfsv4 cannot determine local hostname "
3007c478bd9Sstevel@tonic-gate 			"binding for transport %s - delegations will not be "
3017c478bd9Sstevel@tonic-gate 			"available on this transport\n", nconf->nc_netid);
3027c478bd9Sstevel@tonic-gate 		return (0);
3037c478bd9Sstevel@tonic-gate 	}
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate #ifdef	DEBUG
3067c478bd9Sstevel@tonic-gate 	if (cmd & NFS4_KRPC_START)
3077c478bd9Sstevel@tonic-gate 		fprintf(stderr, "nfs4cbd: starting callback rpc on %s %s\n",
3087c478bd9Sstevel@tonic-gate 			nconf->nc_netid, ua);
3097c478bd9Sstevel@tonic-gate 	else
3107c478bd9Sstevel@tonic-gate 		fprintf(stderr, "nfs4cbd: listening on %s %s\n",
3117c478bd9Sstevel@tonic-gate 			nconf->nc_netid, ua);
3127c478bd9Sstevel@tonic-gate #endif
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate 	nsa.fd = fd;
3157c478bd9Sstevel@tonic-gate 	nsa.cmd = cmd;
3167c478bd9Sstevel@tonic-gate 	nsa.netid = nconf->nc_netid;
3177c478bd9Sstevel@tonic-gate 	if (addrmask)
3187c478bd9Sstevel@tonic-gate 		nsa.addrmask = *addrmask;
3197c478bd9Sstevel@tonic-gate 	else
3207c478bd9Sstevel@tonic-gate 		bzero(&nsa.addrmask, sizeof (struct netbuf));
3217c478bd9Sstevel@tonic-gate 	nsa.addr = ua;
3227c478bd9Sstevel@tonic-gate 	nsa.protofmly = nconf->nc_protofmly;
3237c478bd9Sstevel@tonic-gate 	nsa.proto = nconf->nc_proto;
3247c478bd9Sstevel@tonic-gate 	if ((error = _nfssys(NFS4_SVC, &nsa)) != 0)
3257c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, "nfssys NFS4_SVC failed\n");
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	return (error);
3287c478bd9Sstevel@tonic-gate }
329