From 4897093455a2bf08f3db3a1132cc2f6f5484d77c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 08:03:02 +0200 Subject: Adding upstream version 1:2.6.4. Signed-off-by: Daniel Baumann --- utils/nfsd/Makefile.am | 55 ++++ utils/nfsd/Makefile.in | 855 +++++++++++++++++++++++++++++++++++++++++++++++++ utils/nfsd/nfsd.c | 441 +++++++++++++++++++++++++ utils/nfsd/nfsd.man | 203 ++++++++++++ utils/nfsd/nfssvc.c | 438 +++++++++++++++++++++++++ utils/nfsd/nfssvc.h | 32 ++ 6 files changed, 2024 insertions(+) create mode 100644 utils/nfsd/Makefile.am create mode 100644 utils/nfsd/Makefile.in create mode 100644 utils/nfsd/nfsd.c create mode 100644 utils/nfsd/nfsd.man create mode 100644 utils/nfsd/nfssvc.c create mode 100644 utils/nfsd/nfssvc.h (limited to 'utils/nfsd') diff --git a/utils/nfsd/Makefile.am b/utils/nfsd/Makefile.am new file mode 100644 index 0000000..8acc9a0 --- /dev/null +++ b/utils/nfsd/Makefile.am @@ -0,0 +1,55 @@ +## Process this file with automake to produce Makefile.in + +man8_MANS = nfsd.man +EXTRA_DIST = $(man8_MANS) + +RPCPREFIX = rpc. +KPREFIX = @kprefix@ +sbin_PROGRAMS = nfsd + +noinst_HEADERS = nfssvc.h +nfsd_SOURCES = nfsd.c nfssvc.c +nfsd_LDADD = ../../support/nfs/libnfs.la $(LIBTIRPC) + +MAINTAINERCLEANFILES = Makefile.in + +####################################################################### +# The following allows the current practice of having +# daemons renamed during the install to include RPCPREFIX +# and the KPREFIX +# This could all be done much easier with program_transform_name +# ( program_transform_name = s/^/$(RPCPREFIX)$(KPREFIX)/ ) +# but that also renames the man pages, which the current +# practice does not do. +install-exec-hook: + (cd $(DESTDIR)$(sbindir) && \ + for p in $(sbin_PROGRAMS); do \ + mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\ + done) +uninstall-hook: + (cd $(DESTDIR)$(sbindir) && \ + for p in $(sbin_PROGRAMS); do \ + rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\ + done) + + +# XXX This makes some assumptions about what automake does. +# XXX But there is no install-man-hook or install-man-local. +install-man: install-man8 install-man-links +uninstall-man: uninstall-man8 uninstall-man-links + +install-man-links: + (cd $(DESTDIR)$(man8dir) && \ + for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ + inst=`echo $$m | sed -e 's/man$$/8/'`; \ + rm -f $(RPCPREFIX)$$inst ; \ + $(LN_S) $$inst $(RPCPREFIX)$$inst ; \ + done) + +uninstall-man-links: + (cd $(DESTDIR)$(man8dir) && \ + for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ + inst=`echo $$m | sed -e 's/man$$/8/'`; \ + rm -f $(RPCPREFIX)$$inst ; \ + done) + diff --git a/utils/nfsd/Makefile.in b/utils/nfsd/Makefile.in new file mode 100644 index 0000000..853bf55 --- /dev/null +++ b/utils/nfsd/Makefile.in @@ -0,0 +1,855 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +sbin_PROGRAMS = nfsd$(EXEEXT) +subdir = utils/nfsd +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/aclocal/bsdsignals.m4 \ + $(top_srcdir)/aclocal/getrandom.m4 \ + $(top_srcdir)/aclocal/ipv6.m4 \ + $(top_srcdir)/aclocal/kerberos5.m4 \ + $(top_srcdir)/aclocal/keyutils.m4 \ + $(top_srcdir)/aclocal/libblkid.m4 \ + $(top_srcdir)/aclocal/libcap.m4 \ + $(top_srcdir)/aclocal/libevent.m4 \ + $(top_srcdir)/aclocal/libpthread.m4 \ + $(top_srcdir)/aclocal/libsqlite3.m4 \ + $(top_srcdir)/aclocal/libtirpc.m4 \ + $(top_srcdir)/aclocal/libxml2.m4 \ + $(top_srcdir)/aclocal/nfs-utils.m4 \ + $(top_srcdir)/aclocal/rpcsec_vers.m4 \ + $(top_srcdir)/aclocal/tcp-wrappers.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/support/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" +PROGRAMS = $(sbin_PROGRAMS) +am_nfsd_OBJECTS = nfsd.$(OBJEXT) nfssvc.$(OBJEXT) +nfsd_OBJECTS = $(am_nfsd_OBJECTS) +am__DEPENDENCIES_1 = +nfsd_DEPENDENCIES = ../../support/nfs/libnfs.la $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/nfsd.Po ./$(DEPDIR)/nfssvc.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nfsd_SOURCES) +DIST_SOURCES = $(nfsd_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man8_MANS) +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_CFLAGS = @AM_CFLAGS@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GREP = @GREP@ +GSSAPI_CFLAGS = @GSSAPI_CFLAGS@ +GSSAPI_LIBS = @GSSAPI_LIBS@ +GSSD = @GSSD@ +GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@ +GSSGLUE_LIBS = @GSSGLUE_LIBS@ +GSSKRB_CFLAGS = @GSSKRB_CFLAGS@ +GSSKRB_LIBS = @GSSKRB_LIBS@ +HAVE_GETRANDOM = @HAVE_GETRANDOM@ +HAVE_LIBWRAP = @HAVE_LIBWRAP@ +HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@ +IDMAPD = @IDMAPD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +K5VERS = @K5VERS@ +KRBCFLAGS = @KRBCFLAGS@ +KRBDIR = @KRBDIR@ +KRBLDFLAGS = @KRBLDFLAGS@ +KRBLIBS = @KRBLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBBLKID = @LIBBLKID@ +LIBBSD = @LIBBSD@ +LIBCAP = @LIBCAP@ +LIBCRYPT = @LIBCRYPT@ +LIBEVENT = @LIBEVENT@ +LIBKEYUTILS = @LIBKEYUTILS@ +LIBMOUNT = @LIBMOUNT@ +LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@ +LIBMOUNT_LIBS = @LIBMOUNT_LIBS@ +LIBNSL = @LIBNSL@ +LIBOBJS = @LIBOBJS@ +LIBPTHREAD = @LIBPTHREAD@ +LIBS = @LIBS@ +LIBSOCKET = @LIBSOCKET@ +LIBSQLITE = @LIBSQLITE@ +LIBTIRPC = @LIBTIRPC@ +LIBTOOL = @LIBTOOL@ +LIBWRAP = @LIBWRAP@ +LIBXML2 = @LIBXML2@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_PLUGINS = @PATH_PLUGINS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +RELEASE = @RELEASE@ +RPCGEN_PATH = @RPCGEN_PATH@ +RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@ +RPCSECGSS_LIBS = @RPCSECGSS_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SVCGSSD = @SVCGSSD@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ +VERSION = @VERSION@ +XML2_CFLAGS = @XML2_CFLAGS@ +XML2_LIBS = @XML2_LIBS@ +_rpc_pipefsmount = @_rpc_pipefsmount@ +_statedir = @_statedir@ +_sysconfdir = @_sysconfdir@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ +enable_mountconfig = @enable_mountconfig@ +enable_nfsv4 = @enable_nfsv4@ +enable_nfsv41 = @enable_nfsv41@ +enable_svcgss = @enable_svcgss@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kprefix = @kprefix@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +mountfile = @mountfile@ +nfsconfig = @nfsconfig@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +rpc_pipefsmount = @rpc_pipefsmount@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +startstatd = @startstatd@ +statdpath = @statdpath@ +statduser = @statduser@ +statedir = @statedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +unitdir = @unitdir@ +man8_MANS = nfsd.man +EXTRA_DIST = $(man8_MANS) +RPCPREFIX = rpc. +KPREFIX = @kprefix@ +noinst_HEADERS = nfssvc.h +nfsd_SOURCES = nfsd.c nfssvc.c +nfsd_LDADD = ../../support/nfs/libnfs.la $(LIBTIRPC) +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu utils/nfsd/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu utils/nfsd/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +nfsd$(EXEEXT): $(nfsd_OBJECTS) $(nfsd_DEPENDENCIES) $(EXTRA_nfsd_DEPENDENCIES) + @rm -f nfsd$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(nfsd_OBJECTS) $(nfsd_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfssvc.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man8: $(man8_MANS) + @$(NORMAL_INSTALL) + @list1='$(man8_MANS)'; \ + list2=''; \ + test -n "$(man8dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.8[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/nfsd.Po + -rm -f ./$(DEPDIR)/nfssvc.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-sbinPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/nfsd.Po + -rm -f ./$(DEPDIR)/nfssvc.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man uninstall-sbinPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: install-am install-exec-am install-strip uninstall-am + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ + install-info install-info-am install-man install-man8 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-hook \ + uninstall-man uninstall-man8 uninstall-sbinPROGRAMS + +.PRECIOUS: Makefile + + +####################################################################### +# The following allows the current practice of having +# daemons renamed during the install to include RPCPREFIX +# and the KPREFIX +# This could all be done much easier with program_transform_name +# ( program_transform_name = s/^/$(RPCPREFIX)$(KPREFIX)/ ) +# but that also renames the man pages, which the current +# practice does not do. +install-exec-hook: + (cd $(DESTDIR)$(sbindir) && \ + for p in $(sbin_PROGRAMS); do \ + mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\ + done) +uninstall-hook: + (cd $(DESTDIR)$(sbindir) && \ + for p in $(sbin_PROGRAMS); do \ + rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\ + done) + +# XXX This makes some assumptions about what automake does. +# XXX But there is no install-man-hook or install-man-local. +install-man: install-man8 install-man-links +uninstall-man: uninstall-man8 uninstall-man-links + +install-man-links: + (cd $(DESTDIR)$(man8dir) && \ + for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ + inst=`echo $$m | sed -e 's/man$$/8/'`; \ + rm -f $(RPCPREFIX)$$inst ; \ + $(LN_S) $$inst $(RPCPREFIX)$$inst ; \ + done) + +uninstall-man-links: + (cd $(DESTDIR)$(man8dir) && \ + for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ + inst=`echo $$m | sed -e 's/man$$/8/'`; \ + rm -f $(RPCPREFIX)$$inst ; \ + done) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c new file mode 100644 index 0000000..249df00 --- /dev/null +++ b/utils/nfsd/nfsd.c @@ -0,0 +1,441 @@ +/* + * nfsd + * + * This is the user level part of nfsd. This is very primitive, because + * all the work is now done in the kernel module. + * + * Copyright (C) 1995, 1996 Olaf Kirch + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conffile.h" +#include "nfslib.h" +#include "nfssvc.h" +#include "xlog.h" +#include "xcommon.h" + +#ifndef NFSD_NPROC +#define NFSD_NPROC 8 +#endif + +static void usage(const char *); + +static struct option longopts[] = +{ + { "host", 1, 0, 'H' }, + { "scope", 1, 0, 'S'}, + { "help", 0, 0, 'h' }, + { "no-nfs-version", 1, 0, 'N' }, + { "nfs-version", 1, 0, 'V' }, + { "tcp", 0, 0, 't' }, + { "no-tcp", 0, 0, 'T' }, + { "udp", 0, 0, 'u' }, + { "no-udp", 0, 0, 'U' }, + { "port", 1, 0, 'P' }, + { "port", 1, 0, 'p' }, + { "debug", 0, 0, 'd' }, + { "syslog", 0, 0, 's' }, + { "rdma", 2, 0, 'R' }, + { "grace-time", 1, 0, 'G'}, + { "lease-time", 1, 0, 'L'}, + { NULL, 0, 0, 0 } +}; + +inline static void +read_nfsd_conf(void) +{ + conf_init_file(NFS_CONFFILE); + xlog_set_debug("nfsd"); +} + +int +main(int argc, char **argv) +{ + int count = NFSD_NPROC, c, i, error = 0, portnum, fd, found_one; + char *p, *progname, *port, *rdma_port = NULL; + char **haddr = NULL; + char *scope = NULL; + int hcounter = 0; + struct conf_list *hosts; + int socket_up = 0; + unsigned int minorvers = NFSCTL_MINDEFAULT; + unsigned int minorversset = NFSCTL_MINDEFAULT; + unsigned int minormask = 0; + unsigned int versbits = NFSCTL_VERDEFAULT; + unsigned int protobits = NFSCTL_PROTODEFAULT; + int grace = -1; + int lease = -1; + int force4dot0 = 0; + + progname = basename(argv[0]); + haddr = xmalloc(sizeof(char *)); + haddr[0] = NULL; + + xlog_syslog(0); + xlog_stderr(1); + + /* Read in config setting */ + read_nfsd_conf(); + + nfssvc_get_minormask(&minormask); + + count = conf_get_num("nfsd", "threads", count); + grace = conf_get_num("nfsd", "grace-time", grace); + lease = conf_get_num("nfsd", "lease-time", lease); + port = conf_get_str("nfsd", "port"); + if (!port) + port = "nfs"; + if (conf_get_bool("nfsd", "rdma", false)) { + rdma_port = conf_get_str("nfsd", "rdma-port"); + if (!rdma_port) + rdma_port = "nfsrdma"; + } + /* backward compatibility - nfs.conf used to set rdma port directly */ + if (!rdma_port) + rdma_port = conf_get_str("nfsd", "rdma"); + if (conf_get_bool("nfsd", "udp", NFSCTL_UDPISSET(protobits))) + NFSCTL_UDPSET(protobits); + else + NFSCTL_UDPUNSET(protobits); + if (conf_get_bool("nfsd", "tcp", NFSCTL_TCPISSET(protobits))) + NFSCTL_TCPSET(protobits); + else + NFSCTL_TCPUNSET(protobits); + for (i = 2; i <= 4; i++) { + char tag[20]; + sprintf(tag, "vers%d", i); + if (conf_get_bool("nfsd", tag, NFSCTL_VERISSET(versbits, i))) { + NFSCTL_VERSET(versbits, i); + if (i == 4) + minorvers = minorversset = minormask; + } else { + NFSCTL_VERUNSET(versbits, i); + if (i == 4) { + minorvers = 0; + minorversset = minormask; + } + } + } + + /* We assume the kernel will default all minor versions to 'on', + * and allow the config file to disable some. + */ + for (i = NFS4_MINMINOR; i <= NFS4_MAXMINOR; i++) { + char tag[20]; + sprintf(tag, "vers4.%d", i); + /* The default for minor version support is to let the + * kernel decide. We could ask the kernel what that choice + * will be, but that is needlessly complex. + * Instead, perform a config-file lookup using each of the + * two possible default. If the result is different from the + * default, then impose that value, else don't make a change + * (i.e. don't set the bit in minorversset). + */ + if (!conf_get_bool("nfsd", tag, 1)) { + NFSCTL_MINORSET(minorversset, i); + NFSCTL_MINORUNSET(minorvers, i); + if (i == 0) + force4dot0 = 1; + } + if (conf_get_bool("nfsd", tag, 0)) { + NFSCTL_MINORSET(minorversset, i); + NFSCTL_MINORSET(minorvers, i); + if (i == 0) + force4dot0 = 1; + } + } + + hosts = conf_get_list("nfsd", "host"); + if (hosts && hosts->cnt) { + struct conf_list_node *n; + haddr = realloc(haddr, sizeof(char*) * hosts->cnt); + TAILQ_FOREACH(n, &(hosts->fields), link) { + haddr[hcounter] = n->field; + hcounter++; + } + } + scope = conf_get_str("nfsd", "scope"); + + while ((c = getopt_long(argc, argv, "dH:S:hN:V:p:P:stTuUrG:L:", longopts, NULL)) != EOF) { + switch(c) { + case 'd': + xlog_config(D_ALL, 1); + break; + case 'H': + if (hosts) { + hosts = NULL; + hcounter = 0; + } + if (hcounter) { + haddr = realloc(haddr, sizeof(char*) * hcounter+1); + if(!haddr) { + fprintf(stderr, "%s: unable to allocate " + "memory.\n", progname); + exit(1); + } + } + haddr[hcounter] = optarg; + hcounter++; + break; + case 'S': + scope = optarg; + break; + case 'P': /* XXX for nfs-server compatibility */ + case 'p': + /* only the last -p option has any effect */ + port = optarg; + break; + case 'r': + rdma_port = "nfsrdma"; + break; + case 'R': /* --rdma */ + if (optarg) + rdma_port = optarg; + else + rdma_port = "nfsrdma"; + break; + + case 'N': + switch((c = strtol(optarg, &p, 0))) { + case 4: + if (*p == '.') { + int i = atoi(p+1); + if (i < 0 || i > NFS4_MAXMINOR) { + fprintf(stderr, "%s: unsupported minor version\n", optarg); + exit(1); + } + NFSCTL_MINORSET(minorversset, i); + NFSCTL_MINORUNSET(minorvers, i); + if (i == 0) + force4dot0 = 1; + if (minorvers != 0) + break; + } else { + minorvers = 0; + minorversset = minormask; + } + /* FALLTHRU */ + case 3: + NFSCTL_VERUNSET(versbits, c); + break; + default: + fprintf(stderr, "%s: Unsupported version\n", optarg); + exit(1); + } + break; + case 'V': + switch((c = strtol(optarg, &p, 0))) { + case 4: + if (*p == '.') { + int i = atoi(p+1); + if (i < 0 || i > NFS4_MAXMINOR) { + fprintf(stderr, "%s: unsupported minor version\n", optarg); + exit(1); + } + NFSCTL_MINORSET(minorversset, i); + NFSCTL_MINORSET(minorvers, i); + if (i == 0) + force4dot0 = 1; + } else + minorvers = minorversset = minormask; + /* FALLTHRU */ + case 3: + NFSCTL_VERSET(versbits, c); + break; + default: + fprintf(stderr, "%s: Unsupported version\n", optarg); + exit(1); + } + break; + case 's': + xlog_syslog(1); + xlog_stderr(0); + break; + case 't': + NFSCTL_TCPSET(protobits); + break; + case 'T': + NFSCTL_TCPUNSET(protobits); + break; + case 'u': + NFSCTL_UDPSET(protobits); + break; + case 'U': + NFSCTL_UDPUNSET(protobits); + break; + case 'G': + grace = strtol(optarg, &p, 0); + if (*p || grace <= 0) { + fprintf(stderr, "%s: Unrecognized grace time.\n", optarg); + exit(1); + } + break; + case 'L': + lease = strtol(optarg, &p, 0); + if (*p || lease <= 0) { + fprintf(stderr, "%s: Unrecognized lease time.\n", optarg); + exit(1); + } + break; + default: + fprintf(stderr, "Invalid argument: '%c'\n", c); + /* FALLTHRU */ + case 'h': + usage(progname); + } + } + + if (optind < argc) { + if ((count = atoi(argv[optind])) < 0) { + /* insane # of servers */ + fprintf(stderr, + "%s: invalid server count (%d), using 1\n", + argv[0], count); + count = 1; + } else if (count == 0) { + /* + * don't bother setting anything else if the threads + * are coming down anyway. + */ + socket_up = 1; + goto set_threads; + } + } + + xlog_open(progname); + + portnum = strtol(port, &p, 0); + if (!*p && (portnum <= 0 || portnum > 65535)) { + /* getaddrinfo will catch other errors, but not + * out-of-range numbers. + */ + xlog(L_ERROR, "invalid port number: %s", port); + exit(1); + } + + /* make sure that at least one version is enabled */ + found_one = 0; + for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { + if (NFSCTL_VERISSET(versbits, c)) + found_one = 1; + } + if (!found_one) { + xlog(L_ERROR, "no version specified"); + exit(1); + } + + if (NFSCTL_VERISSET(versbits, 4) && + !NFSCTL_TCPISSET(protobits)) { + xlog(L_ERROR, "version 4 requires the TCP protocol"); + exit(1); + } + + if (chdir(NFS_STATEDIR)) { + xlog(L_ERROR, "chdir(%s) failed: %m", NFS_STATEDIR); + exit(1); + } + + /* make sure nfsdfs is mounted if it's available */ + nfssvc_mount_nfsdfs(progname); + + /* can only change number of threads if nfsd is already up */ + if (nfssvc_inuse()) { + socket_up = 1; + goto set_threads; + } + + /* + * Must set versions before the fd's so that the right versions get + * registered with rpcbind. Note that on older kernels w/o the right + * interfaces, these are a no-op. + * Timeouts must also be set before ports are created else we get + * EBUSY. + */ + nfssvc_setvers(versbits, minorvers, minorversset, force4dot0); + if (grace > 0) + nfssvc_set_time("grace", grace); + if (lease > 0) + nfssvc_set_time("lease", lease); + + if (scope) { + if (unshare(CLONE_NEWUTS) < 0 || + sethostname(scope, strlen(scope)) < 0) { + xlog(L_ERROR, "Unable to set server scope: %m"); + error = -1; + goto out; + } + } + i = 0; + do { + error = nfssvc_set_sockets(protobits, haddr[i], port); + if (!error) + socket_up = 1; + } while (++i < hcounter); + + if (rdma_port) { + error = nfssvc_set_rdmaport(rdma_port); + if (!error) + socket_up = 1; + } +set_threads: + /* don't start any threads if unable to hand off any sockets */ + if (!socket_up) { + xlog(L_ERROR, "unable to set any sockets for nfsd"); + goto out; + } + error = 0; + + /* + * KLUDGE ALERT: + * Some kernels let nfsd kernel threads inherit open files + * from the program that spawns them (i.e. us). So close + * everything before spawning kernel threads. --Chip + */ + fd = open("/dev/null", O_RDWR); + if (fd == -1) + xlog(L_ERROR, "Unable to open /dev/null: %m"); + else { + /* switch xlog output to syslog since stderr is being closed */ + xlog_syslog(1); + xlog_stderr(0); + (void) dup2(fd, 0); + (void) dup2(fd, 1); + (void) dup2(fd, 2); + } + closeall(3); + + if ((error = nfssvc_threads(count)) < 0) + xlog(L_ERROR, "error starting threads: errno %d (%m)", errno); +out: + free(haddr); + return (error != 0); +} + +static void +usage(const char *prog) +{ + fprintf(stderr, "Usage:\n" + "%s [-d|--debug] [-H hostname] [-p|-P|--port port]\n" + " [-N|--no-nfs-version version] [-V|--nfs-version version]\n" + " [-s|--syslog] [-t|--tcp] [-T|--no-tcp] [-u|--udp] [-U|--no-udp]\n" + " [-r|--rdma=] [-G|--grace-time secs] [-L|--leasetime secs] nrservs\n", + prog); + exit(2); +} diff --git a/utils/nfsd/nfsd.man b/utils/nfsd/nfsd.man new file mode 100644 index 0000000..6f4fc1d --- /dev/null +++ b/utils/nfsd/nfsd.man @@ -0,0 +1,203 @@ +.\" +.\" nfsd(8) +.\" +.\" Copyright (C) 1999 Olaf Kirch +.TH rpc.nfsd 8 "20 Feb 2014" +.SH NAME +rpc.nfsd \- NFS server process +.SH SYNOPSIS +.BI "/usr/sbin/rpc.nfsd [" options "]" " "nproc +.SH DESCRIPTION +The +.B rpc.nfsd +program implements the user level part of the NFS service. The +main functionality is handled by the +.B nfsd +kernel module. The user space program merely specifies what sort of sockets +the kernel service should listen on, what NFS versions it should support, and +how many kernel threads it should use. +.P +The +.B rpc.mountd +server provides an ancillary service needed to satisfy mount requests +by NFS clients. +.SH OPTIONS +.TP +.B \-d " or " \-\-debug +enable logging of debugging messages +.TP +.B \-H " or " \-\-host hostname +specify a particular hostname (or address) that NFS requests will +be accepted on. By default, +.B rpc.nfsd +will accept NFS requests on all known network addresses. +Note that +.B lockd +(which performs file locking services for NFS) may still accept +request on all known network addresses. This may change in future +releases of the Linux Kernel. This option can be used multiple times +to listen to more than one interface. +.TP +.B \-S " or " \-\-scope scope +NFSv4.1 and later require the server to report a "scope" which is used +by the clients to detect if two connections are to the same server. +By default Linux NFSD uses the host name as the scope. +.sp +It is particularly important for high-availablity configurations to ensure +that all potential server nodes report the same server scope. +.TP +.B \-p " or " \-\-port port +specify a different port to listen on for NFS requests. By default, +.B rpc.nfsd +will listen on port 2049. +.TP +.B \-r " or " \-\-rdma +specify that NFS requests on the standard RDMA port ("nfsrdma", port +20049) should be honored. +.TP +.BI \-\-rdma= port +Listen for RDMA requests on an alternate port - may be a number or a +name listed in +.BR /etc/services . +.TP +.B \-N " or " \-\-no-nfs-version vers +This option can be used to request that +.B rpc.nfsd +does not offer certain versions of NFS. The current version of +.B rpc.nfsd +can support major NFS versions 3,4 and the minor versions 4.0, 4.1 and 4.2. +.TP +.B \-s " or " \-\-syslog +By default, +.B rpc.nfsd +logs error messages (and debug messages, if enabled) to stderr. This option makes +.B rpc.nfsd +log these messages to syslog instead. Note that errors encountered during +option processing will still be logged to stderr regardless of this option. +.TP +.B \-t " or " \-\-tcp +Instruct the kernel nfs server to open and listen on a TCP socket. This is the default. +.TP +.B \-T " or " \-\-no-tcp +Instruct the kernel nfs server not to open and listen on a TCP socket. +.TP +.B \-u " or " \-\-udp +Instruct the kernel nfs server to open and listen on a UDP socket. +.TP +.B \-U " or " \-\-no-udp +Instruct the kernel nfs server not to open and listen on a UDP socket. This is the default. +.TP +.B \-V " or " \-\-nfs-version vers +This option can be used to request that +.B rpc.nfsd +offer certain versions of NFS. The current version of +.B rpc.nfsd +can support major NFS versions 3,4 and the minor versions 4.0, 4.1 and 4.2. +.TP +.B \-L " or " \-\-lease-time seconds +Set the lease-time used for NFSv4. This corresponds to how often +clients need to confirm their state with the server. Valid range is +from 10 to 3600 seconds. +.TP +.B \-G " or " \-\-grace-time seconds +Set the grace-time used for NFSv4 and NLM (for NFSv2 and NFSv3). +New file open requests (NFSv4) and new file locks (NLM) will not be +allowed until after this time has passed to allow clients to recover state. +.TP +.I nproc +specify the number of NFS server threads. By default, eight +threads are started. However, for optimum performance several threads +should be used. The actual figure depends on the number of and the work +load created by the NFS clients, but a useful starting point is +eight threads. Effects of modifying that number can be checked using +the +.BR nfsstat (8) +program. +.P +Note that if the NFS server is already running, then the options for +specifying host, port, and protocol will be ignored. The number of +processes given will be the only option considered, and the number of +active +.B nfsd +processes will be increased or decreased to match this number. +In particular +.B rpc.nfsd 0 +will stop all threads and thus close any open connections. + +.SH CONFIGURATION FILE +Many of the options that can be set on the command line can also be +controlled through values set in the +.B [nfsd] +section of the +.I /etc/nfs.conf +configuration file. Values recognized include: +.TP +.B threads +The number of threads to start. +.TP +.B host +A host name, or comma separated list of host names, that +.I rpc.nfsd +will listen on. Use of the +.B --host +option replaces all host names listed here. +.TP +.B scope +Set the server scope. +.TP +.B grace-time +The grace time, for both NFSv4 and NLM, in seconds. +.TP +.B lease-time +The lease time for NFSv4, in seconds. +.TP +.B port +Set the port for TCP/UDP to bind to. +.TP +.B rdma +Enable RDMA port (with "on" or "yes" etc) on the standard port +("nfsrdma", port 20049). +.TP +.B rdma-port +Set an alternate RDMA port. +.TP +.B UDP +Enable (with "on" or "yes" etc) or disable ("off", "no") UDP support. +.TP +.B TCP +Enable or disable TCP support. +.TP +.B vers3 +.TP +.B vers4 +Enable or disable +.B all +NFSv4 versions. All versions are normally enabled +by default. +.TP +.B vers4.1 +.TP +.B vers4.2 +Setting these to "off" or similar will disable the selected minor +versions. Setting to "on" will enable them. The default values +are determined by the kernel, and usually minor versions default to +being enabled once the implementation is sufficiently complete. + +.SH NOTES +If the program is built with TI-RPC support, it will enable any protocol and +address family combinations that are marked visible in the +.B netconfig +database. + +.SH SEE ALSO +.BR nfsd (7), +.BR rpc.mountd (8), +.BR exports (5), +.BR exportfs (8), +.BR nfs.conf (5), +.BR rpc.rquotad (8), +.BR nfsstat (8), +.BR netconfig(5). +.SH AUTHOR +Olaf Kirch, Bill Hawes, H. J. Lu, G. Allan Morris III, +and a host of others. diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c new file mode 100644 index 0000000..46452d9 --- /dev/null +++ b/utils/nfsd/nfssvc.c @@ -0,0 +1,438 @@ +/* + * utils/nfsd/nfssvc.c + * + * Run an NFS daemon. + * + * Copyright (C) 1995, 1996 Olaf Kirch + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nfslib.h" +#include "xlog.h" +#include "nfssvc.h" +#include "version.h" + +#ifndef NFSD_FS_DIR +#define NFSD_FS_DIR "/proc/fs/nfsd" +#endif + +#define NFSD_PORTS_FILE NFSD_FS_DIR "/portlist" +#define NFSD_VERS_FILE NFSD_FS_DIR "/versions" +#define NFSD_THREAD_FILE NFSD_FS_DIR "/threads" + +/* + * declaring a common static scratch buffer here keeps us from having to + * continually thrash the stack. The value of 128 bytes here is really just a + * SWAG and can be increased if necessary. It ought to be enough for the + * routines below however. + */ +char buf[128]; + +/* + * Using the "new" interfaces for nfsd requires that /proc/fs/nfsd is + * actually mounted. Make an attempt to mount it here if it doesn't appear + * to be. + */ +void +nfssvc_mount_nfsdfs(char *progname) +{ + int err; + struct stat statbuf; + + err = stat(NFSD_THREAD_FILE, &statbuf); + if (err == 0) + return; + + if (errno != ENOENT) { + xlog(L_ERROR, "Unable to stat %s: errno %d (%m)", + NFSD_THREAD_FILE, errno); + return; + } + + /* + * this call can return an error if modprobe is set up to automatically + * mount nfsdfs when nfsd.ko is plugged in. So, ignore the return + * code from it and just check for the "threads" file afterward. + */ + err = system("/bin/mount -t nfsd nfsd " NFSD_FS_DIR " >/dev/null 2>&1"); + + err = stat(NFSD_THREAD_FILE, &statbuf); + if (err == 0) + return; + + xlog(L_WARNING, "Unable to access " NFSD_FS_DIR " errno %d (%m)." + "\nPlease try, as root, 'mount -t nfsd nfsd " NFSD_FS_DIR + "' and then restart %s to correct the problem", errno, progname); + + return; +} + +/* + * Are there already sockets configured? If not, then it is safe to try to + * open some and pass them through. + * + * Note: If the user explicitly asked for 'udp', then we should probably check + * if that is open, and should open it if not. However we don't yet. All + * sockets have to be opened when the first daemon is started. + */ +int +nfssvc_inuse(void) +{ + int fd, n; + + fd = open(NFSD_PORTS_FILE, O_RDONLY); + + /* problem opening file, assume that nothing is configured */ + if (fd < 0) + return 0; + + n = read(fd, buf, sizeof(buf)); + close(fd); + + xlog(D_GENERAL, "knfsd is currently %s", (n > 0) ? "up" : "down"); + + return (n > 0); +} + +static int +nfssvc_setfds(const struct addrinfo *hints, const char *node, const char *port) +{ + int fd, on = 1, fac = L_ERROR; + int sockfd = -1, rc = 0, bounded = 0; + struct addrinfo *addrhead = NULL, *addr; + char *proto, *family; + + /* + * if file can't be opened, fail. + */ + fd = open(NFSD_PORTS_FILE, O_WRONLY); + if (fd < 0) + return 0; + + rc = getaddrinfo(node, port, hints, &addrhead); + if (rc == EAI_NONAME && !strcmp(port, "nfs")) { + snprintf(buf, sizeof(buf), "%d", NFS_PORT); + rc = getaddrinfo(node, buf, hints, &addrhead); + } + + if (rc != 0) { + xlog(L_ERROR, "unable to resolve %s:%s: %s", + node ? node : "ANYADDR", port, + rc == EAI_SYSTEM ? strerror(errno) : + gai_strerror(rc)); + goto error; + } + + addr = addrhead; + while(addr) { + /* skip non-TCP / non-UDP sockets */ + switch(addr->ai_protocol) { + case IPPROTO_UDP: + proto = "UDP"; + break; + case IPPROTO_TCP: + proto = "TCP"; + break; + default: + addr = addr->ai_next; + continue; + } + + switch(addr->ai_addr->sa_family) { + case AF_INET: + family = "AF_INET"; + break; +#ifdef IPV6_SUPPORTED + case AF_INET6: + family = "AF_INET6"; + break; +#endif /* IPV6_SUPPORTED */ + default: + addr = addr->ai_next; + continue; + } + + /* open socket and prepare to hand it off to kernel */ + sockfd = socket(addr->ai_family, addr->ai_socktype, + addr->ai_protocol); + if (sockfd < 0) { + if (errno != EAFNOSUPPORT) { + xlog(L_ERROR, "unable to create %s %s socket: " + "errno %d (%m)", family, proto, errno); + rc = errno; + goto error; + } + addr = addr->ai_next; + continue; + } + + xlog(D_GENERAL, "Created %s %s socket.", family, proto); + +#ifdef IPV6_SUPPORTED + if (addr->ai_family == AF_INET6 && + setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on))) { + xlog(L_ERROR, "unable to set IPV6_V6ONLY: " + "errno %d (%m)\n", errno); + rc = errno; + goto error; + } +#endif /* IPV6_SUPPORTED */ + if (addr->ai_protocol == IPPROTO_TCP && + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { + xlog(L_ERROR, "unable to set SO_REUSEADDR on %s " + "socket: errno %d (%m)", family, errno); + rc = errno; + goto error; + } + if (bind(sockfd, addr->ai_addr, addr->ai_addrlen)) { + xlog(L_ERROR, "unable to bind %s %s socket: " + "errno %d (%m)", family, proto, errno); + rc = errno; + goto error; + } + if (addr->ai_protocol == IPPROTO_TCP && listen(sockfd, 64)) { + xlog(L_ERROR, "unable to create listening socket: " + "errno %d (%m)", errno); + rc = errno; + goto error; + } + + if (fd < 0) + fd = open(NFSD_PORTS_FILE, O_WRONLY); + + if (fd < 0) { + xlog(L_ERROR, "couldn't open ports file: errno " + "%d (%m)", errno); + goto error; + } + + snprintf(buf, sizeof(buf), "%d\n", sockfd); + if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) { + /* + * this error may be common on older kernels that don't + * support IPv6, so turn into a debug message. + */ + if (errno == EAFNOSUPPORT) + fac = D_ALL; + xlog(fac, "writing fd to kernel failed: errno %d (%m)", + errno); + rc = errno; + goto error; + } + bounded++; + + close(fd); + close(sockfd); + sockfd = fd = -1; + addr = addr->ai_next; + } +error: + if (fd >= 0) + close(fd); + if (sockfd >= 0) + close(sockfd); + nfs_freeaddrinfo(addrhead); + return (bounded ? 0 : rc); +} + +int +nfssvc_set_sockets(const unsigned int protobits, + const char *host, const char *port) +{ + struct addrinfo hints = { .ai_flags = AI_PASSIVE }; + +#ifdef IPV6_SUPPORTED + hints.ai_family = AF_UNSPEC; +#else /* IPV6_SUPPORTED */ + hints.ai_family = AF_INET; +#endif /* IPV6_SUPPORTED */ + + if (!NFSCTL_ANYPROTO(protobits)) + return EPROTOTYPE; + else if (!NFSCTL_UDPISSET(protobits)) + hints.ai_protocol = IPPROTO_TCP; + else if (!NFSCTL_TCPISSET(protobits)) + hints.ai_protocol = IPPROTO_UDP; + + return nfssvc_setfds(&hints, host, port); +} + +int +nfssvc_set_rdmaport(const char *port) +{ + struct servent *sv = getservbyname(port, "tcp"); + int nport; + char buf[20]; + int ret; + int fd; + + if (sv) + nport = ntohs(sv->s_port); + else { + char *ep; + nport = strtol(port, &ep, 10); + if (!*port || *ep) { + xlog(L_ERROR, "unable to interpret port name %s", + port); + return 1; + } + } + + fd = open(NFSD_PORTS_FILE, O_WRONLY); + if (fd < 0) + return 1; + snprintf(buf, sizeof(buf), "rdma %d", nport); + ret = 0; + if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) { + ret= errno; + xlog(L_ERROR, "Unable to request RDMA services: %m"); + } + close(fd); + return ret; +} + +void +nfssvc_set_time(const char *type, const int seconds) +{ + char pathbuf[40]; + char nbuf[10]; + int fd; + + snprintf(pathbuf, sizeof(pathbuf), NFSD_FS_DIR "/nfsv4%stime", type); + snprintf(nbuf, sizeof(nbuf), "%d", seconds); + fd = open(pathbuf, O_WRONLY); + if (fd >= 0) { + if (write(fd, nbuf, strlen(nbuf)) != (ssize_t)strlen(nbuf)) + xlog(L_ERROR, "Unable to set nfsv4%stime: %m", type); + close(fd); + } + if (strcmp(type, "grace") == 0) { + /* set same value for lockd */ + fd = open("/proc/sys/fs/nfs/nlm_grace_period", O_WRONLY); + if (fd >= 0) { + if (write(fd, nbuf, strlen(nbuf)) != (ssize_t)strlen(nbuf)) + xlog(L_ERROR, "Unable to write nlm_grace_period : %m"); + close(fd); + } + } +} + +void +nfssvc_get_minormask(unsigned int *mask) +{ + int fd; + char *ptr = buf; + ssize_t size; + + fd = open(NFSD_VERS_FILE, O_RDONLY); + if (fd < 0) + return; + + size = read(fd, buf, sizeof(buf)); + if (size < 0) { + xlog(L_ERROR, "Getting versions failed: errno %d (%m)", errno); + goto out; + } + ptr[size] = '\0'; + for (;;) { + unsigned vers, minor = 0; + char *token = strtok(ptr, " "); + + if (!token) + break; + ptr = NULL; + if (*token != '+' && *token != '-') + continue; + if (sscanf(++token, "%u.%u", &vers, &minor) > 0 && + vers == 4 && minor <= NFS4_MAXMINOR) + NFSCTL_MINORSET(*mask, minor); + } +out: + close(fd); + return; +} + +static int +nfssvc_print_vers(char *ptr, unsigned size, unsigned vers, unsigned minorvers, + int isset, int force4dot0) +{ + char sign = isset ? '+' : '-'; + if (minorvers == 0) + if (linux_version_code() < MAKE_VERSION(4, 11, 0) || !force4dot0) + return snprintf(ptr, size, "%c%u ", sign, vers); + return snprintf(ptr, size, "%c%u.%u ", sign, vers, minorvers); +} + +void +nfssvc_setvers(unsigned int ctlbits, unsigned int minorvers, unsigned int minorversset, + int force4dot0) +{ + int fd, n, off; + + off = 0; + fd = open(NFSD_VERS_FILE, O_WRONLY); + if (fd < 0) + return; + + for (n = NFSD_MINVERS; n <= ((NFSD_MAXVERS < 3) ? NFSD_MAXVERS : 3); n++) + off += nfssvc_print_vers(&buf[off], sizeof(buf) - off, + n, 0, NFSCTL_VERISSET(ctlbits, n), 0); + + for (n = 0; n <= NFS4_MAXMINOR; n++) { + if (!NFSCTL_MINORISSET(minorversset, n)) + continue; + off += nfssvc_print_vers(&buf[off], sizeof(buf) - off, + 4, n, NFSCTL_MINORISSET(minorvers, n), + (n == 0) ? force4dot0 : 0); + } + if (!off--) + goto out; + buf[off] = '\0'; + xlog(D_GENERAL, "Writing version string to kernel: %s", buf); + snprintf(&buf[off], sizeof(buf) - off, "\n"); + if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) + xlog(L_ERROR, "Setting version failed: errno %d (%m)", errno); +out: + close(fd); + + return; +} + +int +nfssvc_threads(const int nrservs) +{ + ssize_t n; + int fd; + + fd = open(NFSD_THREAD_FILE, O_WRONLY); + if (fd < 0) + fd = open("/proc/fs/nfs/threads", O_WRONLY); + if (fd >= 0) { + /* 2.5+ kernel with nfsd filesystem mounted. + * Just write the number of threads. + */ + snprintf(buf, sizeof(buf), "%d\n", nrservs); + n = write(fd, buf, strlen(buf)); + close(fd); + if (n != (ssize_t)strlen(buf)) + return -1; + else + return 0; + } + return -1; +} diff --git a/utils/nfsd/nfssvc.h b/utils/nfsd/nfssvc.h new file mode 100644 index 0000000..4d53af1 --- /dev/null +++ b/utils/nfsd/nfssvc.h @@ -0,0 +1,32 @@ +/* + * utils/nfsd/nfssvc.h -- nfs service control routines for rpc.nfsd + * + * Copyright (C) 2009 Red Hat, Inc . + * Copyright (C) 2009 Jeff Layton + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 0211-1301 USA + * + */ + +void nfssvc_mount_nfsdfs(char *progname); +int nfssvc_inuse(void); +int nfssvc_set_sockets(const unsigned int protobits, + const char *host, const char *port); +void nfssvc_set_time(const char *type, const int seconds); +int nfssvc_set_rdmaport(const char *port); +void nfssvc_setvers(unsigned int ctlbits, unsigned int minorvers4, + unsigned int minorvers4set, int force4dot0); +int nfssvc_threads(int nrservs); +void nfssvc_get_minormask(unsigned int *mask); -- cgit v1.2.3