diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/fs.d/nfs/statd/Makefile | 14 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/nfs/statd/sm_svc.c | 136 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/nfs/svc/status.xml | 12 | ||||
-rw-r--r-- | usr/src/lib/libshare/nfs/libshare_nfs.c | 5 | ||||
-rw-r--r-- | usr/src/man/man4/nfs.4 | 9 |
5 files changed, 152 insertions, 24 deletions
diff --git a/usr/src/cmd/fs.d/nfs/statd/Makefile b/usr/src/cmd/fs.d/nfs/statd/Makefile index 8a74b8860b..ad7559a035 100644 --- a/usr/src/cmd/fs.d/nfs/statd/Makefile +++ b/usr/src/cmd/fs.d/nfs/statd/Makefile @@ -28,6 +28,8 @@ # Copyright 1990-2003 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2016 by Delphix. All rights reserved. +# FSTYPE= nfs TYPEPROG= statd @@ -37,15 +39,18 @@ include ../../Makefile.fstype CPPFLAGS += -D_REENTRANT -DSUN_THREADS CERRWARN += -_gcc=-Wno-unused-variable +CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-uninitialized LOCAL= sm_svc.o sm_proc.o sm_statd.o -OBJS= $(LOCAL) selfcheck.o daemon.o +OBJS= $(LOCAL) selfcheck.o daemon.o smfcfg.o -SRCS= $(LOCAL:%.o=%.c) ../lib/selfcheck.c ../lib/daemon.c +SRCS= $(LOCAL:%.o=%.c) ../lib/selfcheck.c ../lib/daemon.c \ + ../lib/smfcfg.c -LDLIBS += -lsocket -lrpcsvc -lnsl +LDLIBS += -lsocket -lrpcsvc -lnsl -lscf +CPPFLAGS += -I../lib $(TYPEPROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) @@ -58,6 +63,9 @@ selfcheck.o: ../lib/selfcheck.c daemon.o: ../lib/daemon.c $(COMPILE.c) ../lib/daemon.c +smfcfg.o: ../lib/smfcfg.c + $(COMPILE.c) ../lib/smfcfg.c + lint: lint_SRCS clean: diff --git a/usr/src/cmd/fs.d/nfs/statd/sm_svc.c b/usr/src/cmd/fs.d/nfs/statd/sm_svc.c index 37ef788f50..8f19764116 100644 --- a/usr/src/cmd/fs.d/nfs/statd/sm_svc.c +++ b/usr/src/cmd/fs.d/nfs/statd/sm_svc.c @@ -20,8 +20,9 @@ */ /* - * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -37,10 +38,6 @@ * contributors. */ -/* - * Copyright (c) 2012 by Delphix. All rights reserved. - */ - #include <stdio.h> #include <stdio_ext.h> #include <stdlib.h> @@ -49,9 +46,11 @@ #include <string.h> #include <syslog.h> #include <netconfig.h> +#include <netdir.h> #include <unistd.h> #include <netdb.h> #include <rpc/rpc.h> +#include <rpc/svc.h> #include <netinet/in.h> #include <sys/param.h> #include <sys/resource.h> @@ -69,6 +68,7 @@ #include <limits.h> #include <rpcsvc/daemon_utils.h> #include <priv_utils.h> +#include "smfcfg.h" #include "sm_statd.h" @@ -99,6 +99,7 @@ static char statd_home[MAXPATHLEN]; int debug; int regfiles_only = 0; /* 1 => use symlinks in statmon, 0 => don't */ +int statd_port = 0; char hostname[MAXHOSTNAMELEN]; /* @@ -457,6 +458,78 @@ thr_statd_merges(void) (void) mutex_unlock(&merges_lock); } +/* + * This function is called for each configured network type to + * bind and register our RPC service programs. + * + * On TCP or UDP, we may want to bind SM_PROG on a specific port + * (when statd_port is specified) in which case we'll use the + * variant of svc_tp_create() that lets us pass a bind address. + */ +static void +sm_svc_tp_create(struct netconfig *nconf) +{ + char port_str[8]; + struct nd_hostserv hs; + struct nd_addrlist *al = NULL; + SVCXPRT *xprt = NULL; + + /* + * If statd_port is set and this is an inet transport, + * bind this service on the specified port. The TLI way + * to create such a bind address is netdir_getbyname() + * with the special "host" HOST_SELF_BIND. This builds + * an all-zeros IP address with the specified port. + */ + if (statd_port != 0 && + (strcmp(nconf->nc_protofmly, NC_INET) == 0 || + strcmp(nconf->nc_protofmly, NC_INET6) == 0)) { + int err; + + snprintf(port_str, sizeof (port_str), "%u", + (unsigned short)statd_port); + + hs.h_host = HOST_SELF_BIND; + hs.h_serv = port_str; + err = netdir_getbyname((struct netconfig *)nconf, &hs, &al); + if (err == 0 && al != NULL) { + xprt = svc_tp_create_addr(sm_prog_1, SM_PROG, SM_VERS, + nconf, al->n_addrs); + netdir_free(al, ND_ADDRLIST); + } + if (xprt == NULL) { + syslog(LOG_ERR, "statd: unable to create " + "(SM_PROG, SM_VERS) on transport %s (port %d)", + nconf->nc_netid, statd_port); + } + /* fall-back to default bind */ + } + if (xprt == NULL) { + /* + * Had statd_port=0, or non-inet transport, + * or the bind to a specific port failed. + * Do a default bind. + */ + xprt = svc_tp_create(sm_prog_1, SM_PROG, SM_VERS, nconf); + } + if (xprt == NULL) { + syslog(LOG_ERR, "statd: unable to create " + "(SM_PROG, SM_VERS) for transport %s", + nconf->nc_netid); + return; + } + + /* + * Also register the NSM_ADDR program on this + * transport handle (same dispatch function). + */ + if (!svc_reg(xprt, NSM_ADDR_PROGRAM, NSM_ADDR_V1, sm_prog_1, nconf)) { + syslog(LOG_ERR, "statd: failed to register " + "(NSM_ADDR_PROGRAM, NSM_ADDR_V1) for " + "netconfig %s", nconf->nc_netid); + } +} + int main(int argc, char *argv[]) { @@ -468,7 +541,10 @@ main(int argc, char *argv[]) int mode; int sz; int pipe_fd = -1; + int ret; int connmaxrec = RPC_MAXDATASIZE; + struct netconfig *nconf; + NCONF_HANDLE *nc; addrix = 0; pathix = 0; @@ -477,7 +553,14 @@ main(int argc, char *argv[]) if (init_hostname() < 0) exit(1); - while ((c = getopt(argc, argv, "Dd:a:G:p:rU:")) != EOF) + ret = nfs_smf_get_iprop("statd_port", &statd_port, + DEFAULT_INSTANCE, SCF_TYPE_INTEGER, STATD); + if (ret != SA_OK) { + syslog(LOG_ERR, "Reading of statd_port from SMF " + "failed, using default value"); + } + + while ((c = getopt(argc, argv, "Dd:a:G:p:P:rU:")) != EOF) switch (c) { case 'd': (void) sscanf(optarg, "%d", &debug); @@ -539,7 +622,15 @@ main(int argc, char *argv[]) pathix++; } else { (void) fprintf(stderr, - "statd: -p pathname is too long.\n"); + "statd: -p pathname is too long.\n"); + } + break; + case 'P': + (void) sscanf(optarg, "%d", &statd_port); + if (statd_port < 1 || statd_port > UINT16_MAX) { + (void) fprintf(stderr, + "statd: -P port invalid.\n"); + statd_port = 0; } break; case 'r': @@ -547,7 +638,7 @@ main(int argc, char *argv[]) break; default: (void) fprintf(stderr, - "statd [-d level] [-D]\n"); + "statd [-d level] [-D]\n"); return (1); } @@ -636,16 +727,29 @@ main(int argc, char *argv[]) syslog(LOG_INFO, "unable to set maximum RPC record size"); } - if (!svc_create(sm_prog_1, SM_PROG, SM_VERS, "netpath")) { - syslog(LOG_ERR, "statd: unable to create (SM_PROG, SM_VERS) " - "for netpath."); - exit(1); + /* + * Enumerate network transports and create service listeners + * as appropriate for each. + */ + if ((nc = setnetconfig()) == NULL) { + syslog(LOG_ERR, "setnetconfig failed: %m"); + return (-1); } + while ((nconf = getnetconfig(nc)) != NULL) { + + /* + * Skip things like tpi_raw, invisible... + */ + if ((nconf->nc_flag & NC_VISIBLE) == 0) + continue; + if (nconf->nc_semantics != NC_TPI_CLTS && + nconf->nc_semantics != NC_TPI_COTS && + nconf->nc_semantics != NC_TPI_COTS_ORD) + continue; - if (!svc_create(sm_prog_1, NSM_ADDR_PROGRAM, NSM_ADDR_V1, "netpath")) { - syslog(LOG_ERR, "statd: unable to create (NSM_ADDR_PROGRAM, " - "NSM_ADDR_V1) for netpath."); + sm_svc_tp_create(nconf); } + (void) endnetconfig(nc); /* * Make sure /var/statmon and any alternate (-p) statmon @@ -825,7 +929,7 @@ one_statmon_owner(const char *dir) /*ARGSUSED3*/ static int nftw_owner(const char *path, const struct stat *statp, int info, - struct FTW *ftw) + struct FTW *ftw) { if (!(info == FTW_F || info == FTW_D)) return (0); diff --git a/usr/src/cmd/fs.d/nfs/svc/status.xml b/usr/src/cmd/fs.d/nfs/svc/status.xml index 8412fd8bac..dce8cba446 100644 --- a/usr/src/cmd/fs.d/nfs/svc/status.xml +++ b/usr/src/cmd/fs.d/nfs/svc/status.xml @@ -33,6 +33,8 @@ $SRC/head/rpcsvc/daemon_utils.h and libnsl:open_daemon_lock(). --> +<!-- Copyright (c) 2016 by Delphix. All rights reserved. --> + <service_bundle type='manifest' name='SUNWnfscr:nfs-status'> <service @@ -40,10 +42,6 @@ type='service' version='1'> - <create_default_instance enabled='false' /> - - <single_instance /> - <dependency name='network' grouping='require_any' restart_on='error' @@ -89,6 +87,12 @@ <propval name='auto_enable' type='boolean' value='true' /> </property_group> + <instance name='default' enabled='false'> + <property_group name='nfs-props' type='com.oracle.nfs,props'> + <propval name='statd_port' type='integer' value='0'/> + </property_group> + </instance> + <stability value='Stable' /> <template> diff --git a/usr/src/lib/libshare/nfs/libshare_nfs.c b/usr/src/lib/libshare/nfs/libshare_nfs.c index 5d09ba6a85..8f1bf6cddf 100644 --- a/usr/src/lib/libshare/nfs/libshare_nfs.c +++ b/usr/src/lib/libshare/nfs/libshare_nfs.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. + * Copyright (c) 2014, 2016 by Delphix. All rights reserved. */ /* @@ -2566,6 +2567,10 @@ struct proto_option_defs { {"mountd_port", "mountd_port", PROTO_OPT_MOUNTD_PORT, OPT_TYPE_NUMBER, 0, SVC_MOUNTD, 1, UINT16_MAX}, +#define PROTO_OPT_STATD_PORT 18 + {"statd_port", + "statd_port", PROTO_OPT_STATD_PORT, + OPT_TYPE_NUMBER, 0, SVC_STATD, 1, UINT16_MAX}, {NULL} }; diff --git a/usr/src/man/man4/nfs.4 b/usr/src/man/man4/nfs.4 index 3ff050fcf1..56b1fae33c 100644 --- a/usr/src/man/man4/nfs.4 +++ b/usr/src/man/man4/nfs.4 @@ -19,7 +19,7 @@ .\" Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2016 Nexenta Systems, Inc. .\" -.Dd December 17, 2016 +.Dd December 18, 2016 .Dt NFS 4 .Os .Sh NAME @@ -194,6 +194,13 @@ should listen. The default value is .Li 0 , which means it should use a default binding. +.It Sy statd_port Ns = Ns Ar num +The IP port number on which +.Nm statd +should listen. +The default value is +.Li 0 , +which means it should use a default binding. .El .Ss Setting nfsmapid_domain As described above, the setting for |