summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/fs.d/nfs/statd/Makefile14
-rw-r--r--usr/src/cmd/fs.d/nfs/statd/sm_svc.c136
-rw-r--r--usr/src/cmd/fs.d/nfs/svc/status.xml12
-rw-r--r--usr/src/lib/libshare/nfs/libshare_nfs.c5
-rw-r--r--usr/src/man/man4/nfs.49
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