From: Ben Hutchings Date: Wed, 14 Jul 2010 02:01:57 +0000 (+0100) Subject: Merge branch 'upstream' X-Git-Tag: debian/1%1.1.3-1~1 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=commitdiff_plain;h=ac06221bedbae2238e38fb8905e0234432ab7a14;hp=f1a21c54149d24f8f8f875c2883af449d921c50b Merge branch 'upstream' Conflicts: Makefile.in aclocal.m4 configure depcomp install-sh linux-nfs/Makefile.in support/Makefile.in support/export/Makefile.in support/include/Makefile.in support/include/config.h.in support/include/nfs/Makefile.in support/include/rpcsvc/Makefile.in support/include/sys/Makefile.in support/include/sys/fs/Makefile.in support/misc/Makefile.in support/nfs/Makefile.in tools/Makefile.in tools/locktest/Makefile.in tools/nlmtest/Makefile.in tools/rpcdebug/Makefile.in tools/rpcgen/Makefile.in utils/Makefile.in utils/exportfs/Makefile.in utils/gssd/Makefile.in utils/idmapd/Makefile.in utils/mount/Makefile.in utils/mountd/Makefile.in utils/nfsd/Makefile.in utils/nfsstat/Makefile.in utils/showmount/Makefile.in utils/statd/Makefile.in --- diff --git a/Makefile.in b/Makefile.in index 78fe62f..0727a94 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -188,6 +188,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -382,8 +383,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -408,8 +409,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -419,13 +420,12 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique @@ -496,6 +496,10 @@ dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) @@ -522,6 +526,8 @@ distcheck: dist GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ @@ -678,8 +684,8 @@ uninstall-am: .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ - dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ - distclean-generic distclean-libtool distclean-tags \ + dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \ + distclean distclean-generic distclean-libtool distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ diff --git a/aclocal.m4 b/aclocal.m4 index f8644c6..162a7f4 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.10 -*- Autoconf -*- +# generated automatically by aclocal 1.10.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. +# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This file 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. @@ -11,10 +11,13 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -m4_if(m4_PACKAGE_VERSION, [2.61],, -[m4_fatal([this file was generated for autoconf 2.61. -You have another version of autoconf. If you want to use that, -you should regenerate the build system entirely.], [63])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(AC_AUTOCONF_VERSION, [2.61],, +[m4_warning([this file was generated for autoconf 2.61. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- @@ -6652,16 +6655,14 @@ fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], -[if test -n "$PKG_CONFIG"; then - if test -n "$$1"; then - pkg_cv_[]$1="$$1" - else - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - fi -else - pkg_failed=untried +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried fi[]dnl ])# _PKG_CONFIG @@ -6705,9 +6706,9 @@ See the pkg-config man page for more details.]) if test $pkg_failed = yes; then _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` else - $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD @@ -6742,7 +6743,7 @@ else fi[]dnl ])# PKG_CHECK_MODULES -# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -6757,7 +6758,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.10' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.10], [], +m4_if([$1], [1.10.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -6773,8 +6774,10 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.10])dnl -_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) +[AM_AUTOMAKE_VERSION([1.10.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- @@ -7046,7 +7049,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue @@ -7094,13 +7097,13 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. +# 2005, 2006, 2008 Free Software Foundation, Inc. # # This file 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. -# serial 12 +# serial 13 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -7205,16 +7208,17 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC], # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. +_am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in - $1 | $1:* ) + $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done -echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # @@ -7549,7 +7553,7 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- -# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) diff --git a/configure b/configure index 2ab50b1..8570599 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.1.2. +# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.1.3. # # Report bugs to . # @@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='linux nfs-utils' PACKAGE_TARNAME='nfs-utils' -PACKAGE_VERSION='1.1.2' -PACKAGE_STRING='linux nfs-utils 1.1.2' +PACKAGE_VERSION='1.1.3' +PACKAGE_STRING='linux nfs-utils 1.1.3' PACKAGE_BUGREPORT='linux-nfs@vger.kernel.org' ac_default_prefix=/usr @@ -861,6 +861,9 @@ CONFIG_RPCGEN_TRUE CONFIG_RPCGEN_FALSE CONFIG_MOUNT_TRUE CONFIG_MOUNT_FALSE +enable_ipv6 +CONFIG_IPV6_TRUE +CONFIG_IPV6_FALSE CC CFLAGS LDFLAGS @@ -1449,7 +1452,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures linux nfs-utils 1.1.2 to adapt to many kinds of systems. +\`configure' configures linux nfs-utils 1.1.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1519,7 +1522,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of linux nfs-utils 1.1.2:";; + short | recursive ) echo "Configuration of linux nfs-utils 1.1.3:";; esac cat <<\_ACEOF @@ -1537,6 +1540,7 @@ Optional Features: libblkid --enable-mount Create mount.nfs and don't use the util-linux mount(8) functionality. [default=yes] + --enable-ipv6 enable support for IPv6 [default=no] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --disable-largefile omit support for large files @@ -1653,7 +1657,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -linux nfs-utils configure 1.1.2 +linux nfs-utils configure 1.1.3 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1667,7 +1671,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by linux nfs-utils $as_me 1.1.2, which was +It was created by linux nfs-utils $as_me 1.1.3, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2441,7 +2445,7 @@ fi # Define the identity of the package. PACKAGE='nfs-utils' - VERSION='1.1.2' + VERSION='1.1.3' cat >>confdefs.h <<_ACEOF @@ -2807,6 +2811,31 @@ else CONFIG_MOUNT_FALSE= fi +# Check whether --enable-ipv6 was given. +if test "${enable_ipv6+set}" = set; then + enableval=$enable_ipv6; enable_ipv6=$enableval +else + enable_ipv6=no +fi + + if test "$enable_ipv6" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define IPV6_SUPPORTED 1 +_ACEOF + + else + enable_ipv6= + fi + + if test "$enable_ipv6" = "yes"; then + CONFIG_IPV6_TRUE= + CONFIG_IPV6_FALSE='#' +else + CONFIG_IPV6_TRUE='#' + CONFIG_IPV6_FALSE= +fi + # Check whether user wants TCP wrappers support DEPDIR="${am__leading_dot}deps" @@ -6692,7 +6721,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6695 "configure"' > conftest.$ac_ext + echo '#line 6724 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -8733,11 +8762,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8736: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8765: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8740: \$? = $ac_status" >&5 + echo "$as_me:8769: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9023,11 +9052,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9026: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9055: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9030: \$? = $ac_status" >&5 + echo "$as_me:9059: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9127,11 +9156,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9130: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9159: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9134: \$? = $ac_status" >&5 + echo "$as_me:9163: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11478,7 +11507,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:14030: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14005: \$? = $ac_status" >&5 + echo "$as_me:14034: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14102,11 +14131,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14105: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14134: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14109: \$? = $ac_status" >&5 + echo "$as_me:14138: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -15666,11 +15695,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15669: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15698: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15673: \$? = $ac_status" >&5 + echo "$as_me:15702: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -15770,11 +15799,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15773: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15802: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15777: \$? = $ac_status" >&5 + echo "$as_me:15806: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17959,11 +17988,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17962: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17991: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:17966: \$? = $ac_status" >&5 + echo "$as_me:17995: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -18249,11 +18278,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18252: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18281: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:18256: \$? = $ac_status" >&5 + echo "$as_me:18285: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -18353,11 +18382,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18356: $lt_compile\"" >&5) + (eval echo "\"\$as_me:18385: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:18360: \$? = $ac_status" >&5 + echo "$as_me:18389: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21960,6 +21989,89 @@ fi fi +{ echo "$as_me:$LINENO: checking for getaddrinfo" >&5 +echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6; } +if test "${ac_cv_func_getaddrinfo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define getaddrinfo to an innocuous variant, in case declares getaddrinfo. + For example, HP-UX 11i declares gettimeofday. */ +#define getaddrinfo innocuous_getaddrinfo + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getaddrinfo (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef getaddrinfo + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getaddrinfo (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_getaddrinfo || defined __stub___getaddrinfo +choke me +#endif + +int +main () +{ +return getaddrinfo (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_getaddrinfo=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_getaddrinfo=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_getaddrinfo" >&5 +echo "${ECHO_T}$ac_cv_func_getaddrinfo" >&6; } + + { echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_crypt+set}" = set; then @@ -22588,11 +22700,10 @@ pkg_failed=no { echo "$as_me:$LINENO: checking for RPCSECGSS" >&5 echo $ECHO_N "checking for RPCSECGSS... $ECHO_C" >&6; } -if test -n "$PKG_CONFIG"; then - if test -n "$RPCSECGSS_CFLAGS"; then - pkg_cv_RPCSECGSS_CFLAGS="$RPCSECGSS_CFLAGS" - else - if test -n "$PKG_CONFIG" && \ +if test -n "$RPCSECGSS_CFLAGS"; then + pkg_cv_RPCSECGSS_CFLAGS="$RPCSECGSS_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"librpcsecgss >= 0.16\"") >&5 ($PKG_CONFIG --exists --print-errors "librpcsecgss >= 0.16") 2>&5 ac_status=$? @@ -22602,15 +22713,13 @@ if test -n "$PKG_CONFIG"; then else pkg_failed=yes fi - fi -else - pkg_failed=untried + else + pkg_failed=untried fi -if test -n "$PKG_CONFIG"; then - if test -n "$RPCSECGSS_LIBS"; then - pkg_cv_RPCSECGSS_LIBS="$RPCSECGSS_LIBS" - else - if test -n "$PKG_CONFIG" && \ +if test -n "$RPCSECGSS_LIBS"; then + pkg_cv_RPCSECGSS_LIBS="$RPCSECGSS_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"librpcsecgss >= 0.16\"") >&5 ($PKG_CONFIG --exists --print-errors "librpcsecgss >= 0.16") 2>&5 ac_status=$? @@ -22620,9 +22729,8 @@ if test -n "$PKG_CONFIG"; then else pkg_failed=yes fi - fi -else - pkg_failed=untried + else + pkg_failed=untried fi @@ -22635,9 +22743,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "librpcsecgss >= 0.16"` + RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "librpcsecgss >= 0.16" 2>&1` else - RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "librpcsecgss >= 0.16"` + RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --print-errors "librpcsecgss >= 0.16" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$RPCSECGSS_PKG_ERRORS" >&5 @@ -22667,11 +22775,10 @@ pkg_failed=no { echo "$as_me:$LINENO: checking for GSSGLUE" >&5 echo $ECHO_N "checking for GSSGLUE... $ECHO_C" >&6; } -if test -n "$PKG_CONFIG"; then - if test -n "$GSSGLUE_CFLAGS"; then - pkg_cv_GSSGLUE_CFLAGS="$GSSGLUE_CFLAGS" - else - if test -n "$PKG_CONFIG" && \ +if test -n "$GSSGLUE_CFLAGS"; then + pkg_cv_GSSGLUE_CFLAGS="$GSSGLUE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libgssglue >= 0.1\"") >&5 ($PKG_CONFIG --exists --print-errors "libgssglue >= 0.1") 2>&5 ac_status=$? @@ -22681,15 +22788,13 @@ if test -n "$PKG_CONFIG"; then else pkg_failed=yes fi - fi -else - pkg_failed=untried + else + pkg_failed=untried fi -if test -n "$PKG_CONFIG"; then - if test -n "$GSSGLUE_LIBS"; then - pkg_cv_GSSGLUE_LIBS="$GSSGLUE_LIBS" - else - if test -n "$PKG_CONFIG" && \ +if test -n "$GSSGLUE_LIBS"; then + pkg_cv_GSSGLUE_LIBS="$GSSGLUE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libgssglue >= 0.1\"") >&5 ($PKG_CONFIG --exists --print-errors "libgssglue >= 0.1") 2>&5 ac_status=$? @@ -22699,9 +22804,8 @@ if test -n "$PKG_CONFIG"; then else pkg_failed=yes fi - fi -else - pkg_failed=untried + else + pkg_failed=untried fi @@ -22714,9 +22818,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libgssglue >= 0.1"` + GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libgssglue >= 0.1" 2>&1` else - GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libgssglue >= 0.1"` + GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --print-errors "libgssglue >= 0.1" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GSSGLUE_PKG_ERRORS" >&5 @@ -24117,6 +24221,398 @@ fi fi +if test "$enable_ipv6" = yes; then + { echo "$as_me:$LINENO: checking for inet_ntop" >&5 +echo $ECHO_N "checking for inet_ntop... $ECHO_C" >&6; } +if test "${ac_cv_func_inet_ntop+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define inet_ntop to an innocuous variant, in case declares inet_ntop. + For example, HP-UX 11i declares gettimeofday. */ +#define inet_ntop innocuous_inet_ntop + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char inet_ntop (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef inet_ntop + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_ntop (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_inet_ntop || defined __stub___inet_ntop +choke me +#endif + +int +main () +{ +return inet_ntop (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_inet_ntop=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_inet_ntop=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_inet_ntop" >&5 +echo "${ECHO_T}$ac_cv_func_inet_ntop" >&6; } + + { echo "$as_me:$LINENO: checking for getnameinfo" >&5 +echo $ECHO_N "checking for getnameinfo... $ECHO_C" >&6; } +if test "${ac_cv_func_getnameinfo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define getnameinfo to an innocuous variant, in case declares getnameinfo. + For example, HP-UX 11i declares gettimeofday. */ +#define getnameinfo innocuous_getnameinfo + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getnameinfo (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef getnameinfo + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getnameinfo (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_getnameinfo || defined __stub___getnameinfo +choke me +#endif + +int +main () +{ +return getnameinfo (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_getnameinfo=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_getnameinfo=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_getnameinfo" >&5 +echo "${ECHO_T}$ac_cv_func_getnameinfo" >&6; } + + +{ echo "$as_me:$LINENO: checking for clnt_tli_create in -ltirpc" >&5 +echo $ECHO_N "checking for clnt_tli_create in -ltirpc... $ECHO_C" >&6; } +if test "${ac_cv_lib_tirpc_clnt_tli_create+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltirpc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clnt_tli_create (); +int +main () +{ +return clnt_tli_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_tirpc_clnt_tli_create=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_tirpc_clnt_tli_create=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_tirpc_clnt_tli_create" >&5 +echo "${ECHO_T}$ac_cv_lib_tirpc_clnt_tli_create" >&6; } +if test $ac_cv_lib_tirpc_clnt_tli_create = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBTIRPC 1 +_ACEOF + + LIBS="-ltirpc $LIBS" + +else + { { echo "$as_me:$LINENO: error: libtirpc needed for IPv6 support" >&5 +echo "$as_me: error: libtirpc needed for IPv6 support" >&2;} + { (exit 1); exit 1; }; } +fi + + +for ac_header in tirpc/netconfig.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ---------------------------------------- ## +## Report this to linux-nfs@vger.kernel.org ## +## ---------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + { { echo "$as_me:$LINENO: error: libtirpc-devel needed for IPv6 support" >&5 +echo "$as_me: error: libtirpc-devel needed for IPv6 support" >&2;} + { (exit 1); exit 1; }; } +fi + +done + +fi + + @@ -24145,7 +24641,7 @@ for ac_header in arpa/inet.h fcntl.h libintl.h limits.h \ stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \ sys/param.h sys/socket.h sys/time.h sys/vfs.h \ syslog.h unistd.h com_err.h et/com_err.h \ - ifaddrs.h + ifaddrs.h tirpc/netconfig.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -27758,6 +28254,17 @@ done + + + + + + + + + + + @@ -27771,6 +28278,10 @@ done for ac_func in alarm atexit dup2 fdatasync ftruncate getcwd \ gethostbyaddr gethostbyname gethostname getmntent \ + inet_ntop getnameinfo getrpcbyname \ + bindresvport_sa getnetconfig \ + clnt_create clnt_create_timed \ + clnt_tli_create clnt_vc_create clnt_dg_create xdr_rpcb \ gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \ realpath rmdir select socket strcasecmp strchr strdup \ strerror strrchr strtol strtoul sigprocmask @@ -30072,6 +30583,13 @@ echo "$as_me: error: conditional \"CONFIG_MOUNT\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${CONFIG_IPV6_TRUE}" && test -z "${CONFIG_IPV6_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"CONFIG_IPV6\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"CONFIG_IPV6\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -30400,7 +30918,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by linux nfs-utils $as_me 1.1.2, which was +This file was extended by linux nfs-utils $as_me 1.1.3, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -30453,7 +30971,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -linux nfs-utils config.status 1.1.2 +linux nfs-utils config.status 1.1.3 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -30748,12 +31266,12 @@ CONFIG_RPCGEN_TRUE!$CONFIG_RPCGEN_TRUE$ac_delim CONFIG_RPCGEN_FALSE!$CONFIG_RPCGEN_FALSE$ac_delim CONFIG_MOUNT_TRUE!$CONFIG_MOUNT_TRUE$ac_delim CONFIG_MOUNT_FALSE!$CONFIG_MOUNT_FALSE$ac_delim +enable_ipv6!$enable_ipv6$ac_delim +CONFIG_IPV6_TRUE!$CONFIG_IPV6_TRUE$ac_delim +CONFIG_IPV6_FALSE!$CONFIG_IPV6_FALSE$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim -CPPFLAGS!$CPPFLAGS$ac_delim -ac_ct_CC!$ac_ct_CC$ac_delim -EXEEXT!$EXEEXT$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -30795,6 +31313,9 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim DEPDIR!$DEPDIR$ac_delim am__include!$am__include$ac_delim @@ -30856,7 +31377,7 @@ ACLOCAL_AMFLAGS!$ACLOCAL_AMFLAGS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 59; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 62; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 @@ -31257,21 +31778,22 @@ echo "$as_me: $ac_file is unchanged" >&6;} fi rm -f "$tmp/out12" # Compute $ac_file's index in $config_headers. +_am_arg=$ac_file _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in - $ac_file | $ac_file:* ) + $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done -echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || -$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X$ac_file : 'X\(//\)[^/]' \| \ - X$ac_file : 'X\(//\)$' \| \ - X$ac_file : 'X\(/\)' \| . 2>/dev/null || -echo X$ac_file | +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -31308,7 +31830,7 @@ echo "$as_me: executing $ac_file commands" >&6;} # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ diff --git a/configure.ac b/configure.ac index 6ecbf55..6ae6c6d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. dnl -AC_INIT([linux nfs-utils],[1.1.2],[linux-nfs@vger.kernel.org],[nfs-utils]) +AC_INIT([linux nfs-utils],[1.1.3],[linux-nfs@vger.kernel.org],[nfs-utils]) AC_CANONICAL_BUILD([]) AC_CANONICAL_HOST([]) AC_CONFIG_MACRO_DIR(aclocal) @@ -127,6 +127,18 @@ AC_ARG_ENABLE(mount, enable_mount=$enableval, enable_mount=yes) AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"]) +AC_ARG_ENABLE(ipv6, + [AC_HELP_STRING([--enable-ipv6], + [enable support for IPv6 @<:@default=no@:>@])], + enable_ipv6=$enableval, + enable_ipv6=no) + if test "$enable_ipv6" = yes; then + AC_DEFINE(IPV6_SUPPORTED, 1, [Define this if you want IPv6 support compiled in]) + else + enable_ipv6= + fi + AC_SUBST(enable_ipv6) + AM_CONDITIONAL(CONFIG_IPV6, [test "$enable_ipv6" = "yes"]) # Check whether user wants TCP wrappers support AC_TCP_WRAPPERS @@ -172,6 +184,9 @@ AC_CHECK_FUNC(connect, , AC_CHECK_LIB(socket, connect, [LIBSOCKET="-lsocket"], AC_MSG_ERROR(Function 'socket' not found.), $LIBNSL)) +AC_CHECK_FUNC(getaddrinfo, , , + AC_MSG_ERROR(Function 'getaddrinfo' not found.)) + AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"]) if test "$enable_nfsv4" = yes; then AC_CHECK_LIB(event, event_dispatch, [libevent=1], AC_MSG_ERROR([libevent needed for nfsv4 support])) @@ -234,6 +249,17 @@ if test "$enable_gss" = yes; then fi +if test "$enable_ipv6" = yes; then + AC_CHECK_FUNC(inet_ntop, , , + AC_MSG_ERROR(Function 'inet_ntop' not found.)) + AC_CHECK_FUNC(getnameinfo, , , + AC_MSG_ERROR(Function 'getnameinfo' not found.)) + AC_CHECK_LIB(tirpc, clnt_tli_create, , + AC_MSG_ERROR([libtirpc needed for IPv6 support])) + AC_CHECK_HEADERS(tirpc/netconfig.h, , + AC_MSG_ERROR([libtirpc-devel needed for IPv6 support])) +fi + dnl ************************************************************* dnl Check for headers dnl ************************************************************* @@ -242,7 +268,7 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h \ stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \ sys/param.h sys/socket.h sys/time.h sys/vfs.h \ syslog.h unistd.h com_err.h et/com_err.h \ - ifaddrs.h]) + ifaddrs.h tirpc/netconfig.h]) dnl ************************************************************* dnl Checks for typedefs, structures, and compiler characteristics @@ -278,6 +304,10 @@ AC_FUNC_STAT AC_FUNC_VPRINTF AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \ gethostbyaddr gethostbyname gethostname getmntent \ + inet_ntop getnameinfo getrpcbyname \ + bindresvport_sa getnetconfig \ + clnt_create clnt_create_timed \ + clnt_tli_create clnt_vc_create clnt_dg_create xdr_rpcb \ gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \ realpath rmdir select socket strcasecmp strchr strdup \ strerror strrchr strtol strtoul sigprocmask]) diff --git a/depcomp b/depcomp index ca5ea4e..e5f9736 100755 --- a/depcomp +++ b/depcomp @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2006-10-15.18 +scriptversion=2007-03-29.01 -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software # Foundation, Inc. # This program is free software; you can redistribute it and/or modify @@ -215,34 +215,39 @@ aix) # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` - tmpdepfile="$stripped.u" + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u "$@" -M fi stat=$? - if test -f "$tmpdepfile"; then : - else - stripped=`echo "$stripped" | sed 's,^.*/,,'` - tmpdepfile="$stripped.u" - fi - if test $stat -eq 0; then : else - rm -f "$tmpdepfile" + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done if test -f "$tmpdepfile"; then - outname="$stripped.o" # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" - sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile diff --git a/install-sh b/install-sh index 4fbbae7..a5897de 100755 --- a/install-sh +++ b/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2006-10-14.15 +scriptversion=2006-12-25.00 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -48,7 +48,7 @@ IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" +doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else @@ -58,34 +58,49 @@ fi # Put in absolute file names if you don't have them in your path; # or use environment vars. -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' -posix_glob= posix_mkdir= # Desired mode of installed file. mode=0755 +chgrpcmd= chmodcmd=$chmodprog chowncmd= -chgrpcmd= -stripcmd= +mvcmd=$mvprog rmcmd="$rmprog -f" -mvcmd="$mvprog" +stripcmd= + src= dst= dir_arg= -dstarg= +dst_arg= + +copy_on_change=false no_target_directory= -usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... @@ -95,65 +110,55 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --c (ignored) --d create directories instead of installing files. --g GROUP $chgrpprog installed files to GROUP. --m MODE $chmodprog installed files to MODE. --o USER $chownprog installed files to USER. --s $stripprog installed files. --t DIRECTORY install into DIRECTORY. --T report an error if DSTFILE is a directory. ---help display this help and exit. ---version display version info and exit. + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG " while test $# -ne 0; do case $1 in - -c) shift - continue;; + -c) ;; + + -C) copy_on_change=true;; - -d) dir_arg=true - shift - continue;; + -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - shift - shift case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac - continue;; + shift;; -o) chowncmd="$chownprog $2" - shift - shift - continue;; + shift;; - -s) stripcmd=$stripprog - shift - continue;; + -s) stripcmd=$stripprog;; - -t) dstarg=$2 - shift - shift - continue;; + -t) dst_arg=$2 + shift;; - -T) no_target_directory=true - shift - continue;; + -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; @@ -165,21 +170,22 @@ while test $# -ne 0; do *) break;; esac + shift done -if test $# -ne 0 && test -z "$dir_arg$dstarg"; then +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do - if test -n "$dstarg"; then + if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dstarg" + set fnord "$@" "$dst_arg" shift # fnord fi shift # arg - dstarg=$arg + dst_arg=$arg done fi @@ -224,7 +230,7 @@ for src do # Protect names starting with `-'. case $src in - -*) src=./$src ;; + -*) src=./$src;; esac if test -n "$dir_arg"; then @@ -242,22 +248,22 @@ do exit 1 fi - if test -z "$dstarg"; then + if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi - dst=$dstarg + dst=$dst_arg # Protect names starting with `-'. case $dst in - -*) dst=./$dst ;; + -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then - echo "$0: $dstarg: Is a directory" >&2 + echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst @@ -378,26 +384,19 @@ do # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix=/ ;; - -*) prefix=./ ;; - *) prefix= ;; + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; esac - case $posix_glob in - '') - if (set -f) 2>/dev/null; then - posix_glob=true - else - posix_glob=false - fi ;; - esac + eval "$initialize_posix_glob" oIFS=$IFS IFS=/ - $posix_glob && set -f + $posix_glob set -f set fnord $dstdir shift - $posix_glob && set +f + $posix_glob set +f IFS=$oIFS prefixes= @@ -459,41 +458,54 @@ do # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ - && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ - && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # Now rename the file to the real destination. - { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ - || { - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - if test -f "$dst"; then - $doit $rmcmd -f "$dst" 2>/dev/null \ - || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ - && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ - || { - echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - else - : - fi - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - } || exit 1 + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 trap '' 0 fi diff --git a/linux-nfs/Makefile.in b/linux-nfs/Makefile.in index d8bd3fd..a25399b 100644 --- a/linux-nfs/Makefile.in +++ b/linux-nfs/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -162,6 +162,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ diff --git a/support/Makefile.in b/support/Makefile.in index c7305ff..2bde2ec 100644 --- a/support/Makefile.in +++ b/support/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -173,6 +173,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -324,8 +325,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -350,8 +351,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -361,13 +362,12 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/export/Makefile.in b/support/export/Makefile.in index dcddec6..00b1015 100644 --- a/support/export/Makefile.in +++ b/support/export/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -56,7 +56,7 @@ am_libexport_a_OBJECTS = client.$(OBJEXT) export.$(OBJEXT) \ hostname.$(OBJEXT) nfsctl.$(OBJEXT) rmtab.$(OBJEXT) \ xtab.$(OBJEXT) mount_clnt.$(OBJEXT) mount_xdr.$(OBJEXT) libexport_a_OBJECTS = $(am_libexport_a_OBJECTS) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -187,6 +187,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -326,8 +327,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -339,8 +340,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -350,13 +351,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/export/rmtab.c b/support/export/rmtab.c index 8f392a7..e11a22a 100644 --- a/support/export/rmtab.c +++ b/support/export/rmtab.c @@ -23,7 +23,7 @@ int rmtab_read(void) { struct rmtabent *rep; - nfs_export *exp; + nfs_export *exp = NULL; setrmtabent("r"); while ((rep = getrmtabent(1, NULL)) != NULL) { @@ -31,7 +31,7 @@ rmtab_read(void) int htype; htype = client_gettype(rep->r_client); - if (htype == MCL_FQDN || htype == MCL_SUBNETWORK + if ((htype == MCL_FQDN || htype == MCL_SUBNETWORK) && (hp = gethostbyname (rep->r_client)) && (hp = hostent_dup (hp), exp = export_allowed (hp, rep->r_path))) { diff --git a/support/include/Makefile.in b/support/include/Makefile.in index 0eace0b..131eff9 100644 --- a/support/include/Makefile.in +++ b/support/include/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -176,6 +176,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -359,8 +360,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -385,8 +386,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -396,13 +397,12 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/include/config.h.in b/support/include/config.h.in index 33fc547..dcf16cb 100644 --- a/support/include/config.h.in +++ b/support/include/config.h.in @@ -38,9 +38,27 @@ authgss_set_debug_level */ #undef HAVE_AUTHGSS_SET_DEBUG_LEVEL +/* Define to 1 if you have the `bindresvport_sa' function. */ +#undef HAVE_BINDRESVPORT_SA + /* Define this if you want to use BSD signal semantics */ #undef HAVE_BSD_SIGNALS +/* Define to 1 if you have the `clnt_create' function. */ +#undef HAVE_CLNT_CREATE + +/* Define to 1 if you have the `clnt_create_timed' function. */ +#undef HAVE_CLNT_CREATE_TIMED + +/* Define to 1 if you have the `clnt_dg_create' function. */ +#undef HAVE_CLNT_DG_CREATE + +/* Define to 1 if you have the `clnt_tli_create' function. */ +#undef HAVE_CLNT_TLI_CREATE + +/* Define to 1 if you have the `clnt_vc_create' function. */ +#undef HAVE_CLNT_VC_CREATE + /* Define to 1 if you have the header file. */ #undef HAVE_COM_ERR_H @@ -93,6 +111,15 @@ /* Define to 1 if you have the `getmntent' function. */ #undef HAVE_GETMNTENT +/* Define to 1 if you have the `getnameinfo' function. */ +#undef HAVE_GETNAMEINFO + +/* Define to 1 if you have the `getnetconfig' function. */ +#undef HAVE_GETNETCONFIG + +/* Define to 1 if you have the `getrpcbyname' function. */ +#undef HAVE_GETRPCBYNAME + /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY @@ -111,6 +138,9 @@ /* Define to 1 if you have the `inet_ntoa' function. */ #undef HAVE_INET_NTOA +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + /* Define to 1 if you have the `innetgr' function. */ #undef HAVE_INNETGR @@ -130,6 +160,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H +/* Define to 1 if you have the `tirpc' library (-ltirpc). */ +#undef HAVE_LIBTIRPC + /* tcp-wrapper */ #undef HAVE_LIBWRAP @@ -280,6 +313,9 @@ /* tcp-wrapper */ #undef HAVE_TCP_WRAPPER +/* Define to 1 if you have the header file. */ +#undef HAVE_TIRPC_NETCONFIG_H + /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H @@ -298,6 +334,12 @@ /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK +/* Define to 1 if you have the `xdr_rpcb' function. */ +#undef HAVE_XDR_RPCB + +/* Define this if you want IPv6 support compiled in */ +#undef IPV6_SUPPORTED + /* Define this as the Kerberos version number */ #undef KRB5_VERSION diff --git a/support/include/nfs/Makefile.in b/support/include/nfs/Makefile.in index 3837d26..2f3143d 100644 --- a/support/include/nfs/Makefile.in +++ b/support/include/nfs/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -166,6 +166,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -247,8 +248,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -260,8 +261,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -271,13 +272,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/include/rpcsvc/Makefile.in b/support/include/rpcsvc/Makefile.in index 909c414..74c0970 100644 --- a/support/include/rpcsvc/Makefile.in +++ b/support/include/rpcsvc/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -166,6 +166,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -247,8 +248,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -260,8 +261,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -271,13 +272,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/include/sys/Makefile.in b/support/include/sys/Makefile.in index 9bde9c0..a849c6a 100644 --- a/support/include/sys/Makefile.in +++ b/support/include/sys/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -173,6 +173,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -324,8 +325,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -350,8 +351,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -361,13 +362,12 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/include/sys/fs/Makefile.in b/support/include/sys/fs/Makefile.in index d6a00b1..90b1efc 100644 --- a/support/include/sys/fs/Makefile.in +++ b/support/include/sys/fs/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -166,6 +166,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -247,8 +248,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -260,8 +261,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -271,13 +272,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/misc/Makefile.in b/support/misc/Makefile.in index e151730..4c1974b 100644 --- a/support/misc/Makefile.in +++ b/support/misc/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -53,7 +53,7 @@ libmisc_a_LIBADD = am_libmisc_a_OBJECTS = tcpwrapper.$(OBJEXT) from_local.$(OBJEXT) \ mountpoint.$(OBJEXT) libmisc_a_OBJECTS = $(am_libmisc_a_OBJECTS) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -183,6 +183,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -304,8 +305,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -317,8 +318,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -328,13 +329,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/misc/tcpwrapper.c b/support/misc/tcpwrapper.c index 0cc9335..e4f453b 100644 --- a/support/misc/tcpwrapper.c +++ b/support/misc/tcpwrapper.c @@ -125,12 +125,12 @@ struct sockaddr_in *addr; return 0; /* Check the official name first. */ - if (hosts_ctl(daemon, "", hp->h_name, "")) + if (hosts_ctl(daemon, hp->h_name, "", "")) return 1; /* Check aliases. */ for (sp = hp->h_aliases; *sp ; sp++) { - if (hosts_ctl(daemon, "", *sp, "")) + if (hosts_ctl(daemon, *sp, "", "")) return 1; } diff --git a/support/nfs/Makefile.in b/support/nfs/Makefile.in index b4d588a..604a48e 100644 --- a/support/nfs/Makefile.in +++ b/support/nfs/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -57,7 +57,7 @@ am_libnfs_a_OBJECTS = exports.$(OBJEXT) rmtab.$(OBJEXT) xio.$(OBJEXT) \ nfsctl.$(OBJEXT) svc_socket.$(OBJEXT) cacheio.$(OBJEXT) \ closeall.$(OBJEXT) nfs_mntent.$(OBJEXT) libnfs_a_OBJECTS = $(am_libnfs_a_OBJECTS) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -187,6 +187,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -326,8 +327,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -339,8 +340,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -350,13 +351,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/support/nfs/xio.c b/support/nfs/xio.c index 0453ca7..f21f5f0 100644 --- a/support/nfs/xio.c +++ b/support/nfs/xio.c @@ -54,13 +54,19 @@ xflock(char *fname, char *type) { struct sigaction sa, oldsa; int readonly = !strcmp(type, "r"); + mode_t mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); struct flock fl = { readonly? F_RDLCK : F_WRLCK, SEEK_SET, 0, 0, 0 }; int fd; - if ((fd = open(fname, readonly? O_RDONLY : (O_RDWR|O_CREAT), 0644)) < 0) { + if (readonly) + fd = open(fname, O_RDONLY); + else + fd = open(fname, (O_RDWR|O_CREAT), mode); + if (fd < 0) { xlog(L_WARNING, "could not open %s for locking", fname); return -1; } + sa.sa_handler = doalarm; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); diff --git a/tools/Makefile.in b/tools/Makefile.in index e73e448..a13afc0 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -174,6 +174,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -326,8 +327,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -352,8 +353,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -363,13 +364,12 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/tools/locktest/Makefile.in b/tools/locktest/Makefile.in index 2a9bb30..e074375 100644 --- a/tools/locktest/Makefile.in +++ b/tools/locktest/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -54,7 +54,7 @@ testlk_LDADD = $(LDADD) testlk_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(testlk_CFLAGS) $(CFLAGS) \ $(testlk_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -184,6 +184,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -322,8 +323,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -335,8 +336,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -346,13 +347,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py new file mode 100644 index 0000000..c475c9e --- /dev/null +++ b/tools/mountstats/mountstats.py @@ -0,0 +1,604 @@ +#!/usr/bin/env python +# -*- python-mode -*- +"""Parse /proc/self/mountstats and display it in human readable form +""" + +__copyright__ = """ +Copyright (C) 2005, Chuck Lever + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" + +import sys, os, time + +Mountstats_version = '0.2' + +def difference(x, y): + """Used for a map() function + """ + return x - y + +class DeviceData: + """DeviceData objects provide methods for parsing and displaying + data for a single mount grabbed from /proc/self/mountstats + """ + def __init__(self): + self.__nfs_data = dict() + self.__rpc_data = dict() + self.__rpc_data['ops'] = [] + + def __parse_nfs_line(self, words): + if words[0] == 'device': + self.__nfs_data['export'] = words[1] + self.__nfs_data['mountpoint'] = words[4] + self.__nfs_data['fstype'] = words[7] + if words[7].find('nfs') != -1: + self.__nfs_data['statvers'] = words[8] + elif words[0] == 'age:': + self.__nfs_data['age'] = long(words[1]) + elif words[0] == 'opts:': + self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',') + elif words[0] == 'caps:': + self.__nfs_data['servercapabilities'] = ''.join(words[1:]).split(',') + elif words[0] == 'nfsv4:': + self.__nfs_data['nfsv4flags'] = ''.join(words[1:]).split(',') + elif words[0] == 'sec:': + keys = ''.join(words[1:]).split(',') + self.__nfs_data['flavor'] = int(keys[0].split('=')[1]) + self.__nfs_data['pseudoflavor'] = 0 + if self.__nfs_data['flavor'] == 6: + self.__nfs_data['pseudoflavor'] = int(keys[1].split('=')[1]) + elif words[0] == 'events:': + self.__nfs_data['inoderevalidates'] = int(words[1]) + self.__nfs_data['dentryrevalidates'] = int(words[2]) + self.__nfs_data['datainvalidates'] = int(words[3]) + self.__nfs_data['attrinvalidates'] = int(words[4]) + self.__nfs_data['syncinodes'] = int(words[5]) + self.__nfs_data['vfsopen'] = int(words[6]) + self.__nfs_data['vfslookup'] = int(words[7]) + self.__nfs_data['vfspermission'] = int(words[8]) + self.__nfs_data['vfsreadpage'] = int(words[9]) + self.__nfs_data['vfsreadpages'] = int(words[10]) + self.__nfs_data['vfswritepage'] = int(words[11]) + self.__nfs_data['vfswritepages'] = int(words[12]) + self.__nfs_data['vfsreaddir'] = int(words[13]) + self.__nfs_data['vfsflush'] = int(words[14]) + self.__nfs_data['vfsfsync'] = int(words[15]) + self.__nfs_data['vfslock'] = int(words[16]) + self.__nfs_data['vfsrelease'] = int(words[17]) + self.__nfs_data['setattrtrunc'] = int(words[18]) + self.__nfs_data['extendwrite'] = int(words[19]) + self.__nfs_data['sillyrenames'] = int(words[20]) + self.__nfs_data['shortreads'] = int(words[21]) + self.__nfs_data['shortwrites'] = int(words[22]) + self.__nfs_data['delay'] = int(words[23]) + elif words[0] == 'bytes:': + self.__nfs_data['normalreadbytes'] = long(words[1]) + self.__nfs_data['normalwritebytes'] = long(words[2]) + self.__nfs_data['directreadbytes'] = long(words[3]) + self.__nfs_data['directwritebytes'] = long(words[4]) + self.__nfs_data['serverreadbytes'] = long(words[5]) + self.__nfs_data['serverwritebytes'] = long(words[6]) + + def __parse_rpc_line(self, words): + if words[0] == 'RPC': + self.__rpc_data['statsvers'] = float(words[3]) + self.__rpc_data['programversion'] = words[5] + elif words[0] == 'xprt:': + self.__rpc_data['protocol'] = words[1] + if words[1] == 'udp': + self.__rpc_data['port'] = int(words[2]) + self.__rpc_data['bind_count'] = int(words[3]) + self.__rpc_data['rpcsends'] = int(words[4]) + self.__rpc_data['rpcreceives'] = int(words[5]) + self.__rpc_data['badxids'] = int(words[6]) + self.__rpc_data['inflightsends'] = long(words[7]) + self.__rpc_data['backlogutil'] = long(words[8]) + elif words[1] == 'tcp': + self.__rpc_data['port'] = words[2] + self.__rpc_data['bind_count'] = int(words[3]) + self.__rpc_data['connect_count'] = int(words[4]) + self.__rpc_data['connect_time'] = int(words[5]) + self.__rpc_data['idle_time'] = int(words[6]) + self.__rpc_data['rpcsends'] = int(words[7]) + self.__rpc_data['rpcreceives'] = int(words[8]) + self.__rpc_data['badxids'] = int(words[9]) + self.__rpc_data['inflightsends'] = long(words[10]) + self.__rpc_data['backlogutil'] = int(words[11]) + elif words[1] == 'rdma': + self.__rpc_data['port'] = words[2] + self.__rpc_data['bind_count'] = int(words[3]) + self.__rpc_data['connect_count'] = int(words[4]) + self.__rpc_data['connect_time'] = int(words[5]) + self.__rpc_data['idle_time'] = int(words[6]) + self.__rpc_data['rpcsends'] = int(words[7]) + self.__rpc_data['rpcreceives'] = int(words[8]) + self.__rpc_data['badxids'] = int(words[9]) + self.__rpc_data['backlogutil'] = int(words[10]) + self.__rpc_data['read_chunks'] = int(words[11]) + self.__rpc_data['write_chunks'] = int(words[12]) + self.__rpc_data['reply_chunks'] = int(words[13]) + self.__rpc_data['total_rdma_req'] = int(words[14]) + self.__rpc_data['total_rdma_rep'] = int(words[15]) + self.__rpc_data['pullup'] = int(words[16]) + self.__rpc_data['fixup'] = int(words[17]) + self.__rpc_data['hardway'] = int(words[18]) + self.__rpc_data['failed_marshal'] = int(words[19]) + self.__rpc_data['bad_reply'] = int(words[20]) + elif words[0] == 'per-op': + self.__rpc_data['per-op'] = words + else: + op = words[0][:-1] + self.__rpc_data['ops'] += [op] + self.__rpc_data[op] = [long(word) for word in words[1:]] + + def parse_stats(self, lines): + """Turn a list of lines from a mount stat file into a + dictionary full of stats, keyed by name + """ + found = False + for line in lines: + words = line.split() + if len(words) == 0: + continue + if (not found and words[0] != 'RPC'): + self.__parse_nfs_line(words) + continue + + found = True + self.__parse_rpc_line(words) + + def is_nfs_mountpoint(self): + """Return True if this is an NFS or NFSv4 mountpoint, + otherwise return False + """ + if self.__nfs_data['fstype'] == 'nfs': + return True + elif self.__nfs_data['fstype'] == 'nfs4': + return True + return False + + def display_nfs_options(self): + """Pretty-print the NFS options + """ + print 'Stats for %s mounted on %s:' % \ + (self.__nfs_data['export'], self.__nfs_data['mountpoint']) + + print ' NFS mount options: %s' % ','.join(self.__nfs_data['mountoptions']) + print ' NFS server capabilities: %s' % ','.join(self.__nfs_data['servercapabilities']) + if self.__nfs_data.has_key('nfsv4flags'): + print ' NFSv4 capability flags: %s' % ','.join(self.__nfs_data['nfsv4flags']) + if self.__nfs_data.has_key('pseudoflavor'): + print ' NFS security flavor: %d pseudoflavor: %d' % \ + (self.__nfs_data['flavor'], self.__nfs_data['pseudoflavor']) + else: + print ' NFS security flavor: %d' % self.__nfs_data['flavor'] + + def display_nfs_events(self): + """Pretty-print the NFS event counters + """ + print + print 'Cache events:' + print ' data cache invalidated %d times' % self.__nfs_data['datainvalidates'] + print ' attribute cache invalidated %d times' % self.__nfs_data['attrinvalidates'] + print ' inodes synced %d times' % self.__nfs_data['syncinodes'] + print + print 'VFS calls:' + print ' VFS requested %d inode revalidations' % self.__nfs_data['inoderevalidates'] + print ' VFS requested %d dentry revalidations' % self.__nfs_data['dentryrevalidates'] + print + print ' VFS called nfs_readdir() %d times' % self.__nfs_data['vfsreaddir'] + print ' VFS called nfs_lookup() %d times' % self.__nfs_data['vfslookup'] + print ' VFS called nfs_permission() %d times' % self.__nfs_data['vfspermission'] + print ' VFS called nfs_file_open() %d times' % self.__nfs_data['vfsopen'] + print ' VFS called nfs_file_flush() %d times' % self.__nfs_data['vfsflush'] + print ' VFS called nfs_lock() %d times' % self.__nfs_data['vfslock'] + print ' VFS called nfs_fsync() %d times' % self.__nfs_data['vfsfsync'] + print ' VFS called nfs_file_release() %d times' % self.__nfs_data['vfsrelease'] + print + print 'VM calls:' + print ' VFS called nfs_readpage() %d times' % self.__nfs_data['vfsreadpage'] + print ' VFS called nfs_readpages() %d times' % self.__nfs_data['vfsreadpages'] + print ' VFS called nfs_writepage() %d times' % self.__nfs_data['vfswritepage'] + print ' VFS called nfs_writepages() %d times' % self.__nfs_data['vfswritepages'] + print + print 'Generic NFS counters:' + print ' File size changing operations:' + print ' truncating SETATTRs: %d extending WRITEs: %d' % \ + (self.__nfs_data['setattrtrunc'], self.__nfs_data['extendwrite']) + print ' %d silly renames' % self.__nfs_data['sillyrenames'] + print ' short reads: %d short writes: %d' % \ + (self.__nfs_data['shortreads'], self.__nfs_data['shortwrites']) + print ' NFSERR_DELAYs from server: %d' % self.__nfs_data['delay'] + + def display_nfs_bytes(self): + """Pretty-print the NFS event counters + """ + print + print 'NFS byte counts:' + print ' applications read %d bytes via read(2)' % self.__nfs_data['normalreadbytes'] + print ' applications wrote %d bytes via write(2)' % self.__nfs_data['normalwritebytes'] + print ' applications read %d bytes via O_DIRECT read(2)' % self.__nfs_data['directreadbytes'] + print ' applications wrote %d bytes via O_DIRECT write(2)' % self.__nfs_data['directwritebytes'] + print ' client read %d bytes via NFS READ' % self.__nfs_data['serverreadbytes'] + print ' client wrote %d bytes via NFS WRITE' % self.__nfs_data['serverwritebytes'] + + def display_rpc_generic_stats(self): + """Pretty-print the generic RPC stats + """ + sends = self.__rpc_data['rpcsends'] + + print + print 'RPC statistics:' + + print ' %d RPC requests sent, %d RPC replies received (%d XIDs not found)' % \ + (sends, self.__rpc_data['rpcreceives'], self.__rpc_data['badxids']) + if sends != 0: + print ' average backlog queue length: %d' % \ + (float(self.__rpc_data['backlogutil']) / sends) + + def display_rpc_op_stats(self): + """Pretty-print the per-op stats + """ + sends = self.__rpc_data['rpcsends'] + + # XXX: these should be sorted by 'count' + print + for op in self.__rpc_data['ops']: + stats = self.__rpc_data[op] + count = stats[0] + retrans = stats[1] - count + if count != 0: + print '%s:' % op + print '\t%d ops (%d%%)' % \ + (count, ((count * 100) / sends)), + print '\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)), + print '\t%d major timeouts' % stats[2] + print '\tavg bytes sent per op: %d\tavg bytes received per op: %d' % \ + (stats[3] / count, stats[4] / count) + print '\tbacklog wait: %f' % (float(stats[5]) / count), + print '\tRTT: %f' % (float(stats[6]) / count), + print '\ttotal execute time: %f (milliseconds)' % \ + (float(stats[7]) / count) + + def compare_iostats(self, old_stats): + """Return the difference between two sets of stats + """ + result = DeviceData() + + # copy self into result + for key, value in self.__nfs_data.iteritems(): + result.__nfs_data[key] = value + for key, value in self.__rpc_data.iteritems(): + result.__rpc_data[key] = value + + # compute the difference of each item in the list + # note the copy loop above does not copy the lists, just + # the reference to them. so we build new lists here + # for the result object. + for op in result.__rpc_data['ops']: + result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op]) + + # update the remaining keys we care about + result.__rpc_data['rpcsends'] -= old_stats.__rpc_data['rpcsends'] + result.__rpc_data['backlogutil'] -= old_stats.__rpc_data['backlogutil'] + result.__nfs_data['serverreadbytes'] -= old_stats.__nfs_data['serverreadbytes'] + result.__nfs_data['serverwritebytes'] -= old_stats.__nfs_data['serverwritebytes'] + + return result + + def display_iostats(self, sample_time): + """Display NFS and RPC stats in an iostat-like way + """ + sends = float(self.__rpc_data['rpcsends']) + if sample_time == 0: + sample_time = float(self.__nfs_data['age']) + + print + print '%s mounted on %s:' % \ + (self.__nfs_data['export'], self.__nfs_data['mountpoint']) + + print '\top/s\trpc bklog' + print '\t%.2f' % (sends / sample_time), + if sends != 0: + print '\t%.2f' % \ + ((float(self.__rpc_data['backlogutil']) / sends) / sample_time) + else: + print '\t0.00' + + # reads: ops/s, kB/s, avg rtt, and avg exe + # XXX: include avg xfer size and retransmits? + read_rpc_stats = self.__rpc_data['READ'] + ops = float(read_rpc_stats[0]) + kilobytes = float(self.__nfs_data['serverreadbytes']) / 1024 + rtt = float(read_rpc_stats[6]) + exe = float(read_rpc_stats[7]) + + print '\treads:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)' + print '\t\t%.2f' % (ops / sample_time), + print '\t\t%.2f' % (kilobytes / sample_time), + if ops != 0: + print '\t\t%.2f' % (rtt / ops), + print '\t\t%.2f' % (exe / ops) + else: + print '\t\t0.00', + print '\t\t0.00' + + # writes: ops/s, kB/s, avg rtt, and avg exe + # XXX: include avg xfer size and retransmits? + write_rpc_stats = self.__rpc_data['WRITE'] + ops = float(write_rpc_stats[0]) + kilobytes = float(self.__nfs_data['serverwritebytes']) / 1024 + rtt = float(write_rpc_stats[6]) + exe = float(write_rpc_stats[7]) + + print '\twrites:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)' + print '\t\t%.2f' % (ops / sample_time), + print '\t\t%.2f' % (kilobytes / sample_time), + if ops != 0: + print '\t\t%.2f' % (rtt / ops), + print '\t\t%.2f' % (exe / ops) + else: + print '\t\t0.00', + print '\t\t0.00' + +def parse_stats_file(filename): + """pop the contents of a mountstats file into a dictionary, + keyed by mount point. each value object is a list of the + lines in the mountstats file corresponding to the mount + point named in the key. + """ + ms_dict = dict() + key = '' + + f = file(filename) + for line in f.readlines(): + words = line.split() + if len(words) == 0: + continue + if words[0] == 'device': + key = words[4] + new = [ line.strip() ] + else: + new += [ line.strip() ] + ms_dict[key] = new + f.close + + return ms_dict + +def print_mountstats_help(name): + print 'usage: %s [ options ] ' % name + print + print ' Version %s' % Mountstats_version + print + print ' Display NFS client per-mount statistics.' + print + print ' --version display the version of this command' + print ' --nfs display only the NFS statistics' + print ' --rpc display only the RPC statistics' + print ' --start sample and save statistics' + print ' --end resample statistics and compare them with saved' + print + +def mountstats_command(): + """Mountstats command + """ + mountpoints = [] + nfs_only = False + rpc_only = False + + for arg in sys.argv: + if arg in ['-h', '--help', 'help', 'usage']: + print_mountstats_help(prog) + return + + if arg in ['-v', '--version', 'version']: + print '%s version %s' % (sys.argv[0], Mountstats_version) + sys.exit(0) + + if arg in ['-n', '--nfs']: + nfs_only = True + continue + + if arg in ['-r', '--rpc']: + rpc_only = True + continue + + if arg in ['-s', '--start']: + raise Exception, 'Sampling is not yet implemented' + + if arg in ['-e', '--end']: + raise Exception, 'Sampling is not yet implemented' + + if arg == sys.argv[0]: + continue + + mountpoints += [arg] + + if mountpoints == []: + print_mountstats_help(prog) + return + + if rpc_only == True and nfs_only == True: + print_mountstats_help(prog) + return + + mountstats = parse_stats_file('/proc/self/mountstats') + + for mp in mountpoints: + if mp not in mountstats: + print 'Statistics for mount point %s not found' % mp + continue + + stats = DeviceData() + stats.parse_stats(mountstats[mp]) + + if not stats.is_nfs_mountpoint(): + print 'Mount point %s exists but is not an NFS mount' % mp + continue + + if nfs_only: + stats.display_nfs_options() + stats.display_nfs_events() + stats.display_nfs_bytes() + elif rpc_only: + stats.display_rpc_generic_stats() + stats.display_rpc_op_stats() + else: + stats.display_nfs_options() + stats.display_nfs_bytes() + stats.display_rpc_generic_stats() + stats.display_rpc_op_stats() + +def print_nfsstat_help(name): + print 'usage: %s [ options ]' % name + print + print ' Version %s' % Mountstats_version + print + print ' nfsstat-like program that uses NFS client per-mount statistics.' + print + +def nfsstat_command(): + print_nfsstat_help(prog) + +def print_iostat_help(name): + print 'usage: %s [ [ ] ] [ ] ' % name + print + print ' Version %s' % Mountstats_version + print + print ' iostat-like program to display NFS client per-mount statistics.' + print + print ' The parameter specifies the amount of time in seconds between' + print ' each report. The first report contains statistics for the time since each' + print ' file system was mounted. Each subsequent report contains statistics' + print ' collected during the interval since the previous report.' + print + print ' If the parameter is specified, the value of determines the' + print ' number of reports generated at seconds apart. If the interval' + print ' parameter is specified without the parameter, the command generates' + print ' reports continuously.' + print + print ' If one or more names are specified, statistics for only these' + print ' mount points will be displayed. Otherwise, all NFS mount points on the' + print ' client are listed.' + print + +def print_iostat_summary(old, new, devices, time): + for device in devices: + stats = DeviceData() + stats.parse_stats(new[device]) + if not old: + stats.display_iostats(time) + else: + old_stats = DeviceData() + old_stats.parse_stats(old[device]) + diff_stats = stats.compare_iostats(old_stats) + diff_stats.display_iostats(time) + +def iostat_command(): + """iostat-like command for NFS mount points + """ + mountstats = parse_stats_file('/proc/self/mountstats') + devices = [] + interval_seen = False + count_seen = False + + for arg in sys.argv: + if arg in ['-h', '--help', 'help', 'usage']: + print_iostat_help(prog) + return + + if arg in ['-v', '--version', 'version']: + print '%s version %s' % (sys.argv[0], Mountstats_version) + return + + if arg == sys.argv[0]: + continue + + if arg in mountstats: + devices += [arg] + elif not interval_seen: + interval = int(arg) + if interval > 0: + interval_seen = True + else: + print 'Illegal value' + return + elif not count_seen: + count = int(arg) + if count > 0: + count_seen = True + else: + print 'Illegal value' + return + + # make certain devices contains only NFS mount points + if len(devices) > 0: + check = [] + for device in devices: + stats = DeviceData() + stats.parse_stats(mountstats[device]) + if stats.is_nfs_mountpoint(): + check += [device] + devices = check + else: + for device, descr in mountstats.iteritems(): + stats = DeviceData() + stats.parse_stats(descr) + if stats.is_nfs_mountpoint(): + devices += [device] + if len(devices) == 0: + print 'No NFS mount points were found' + return + + old_mountstats = None + sample_time = 0 + + if not interval_seen: + print_iostat_summary(old_mountstats, mountstats, devices, sample_time) + return + + if count_seen: + while count != 0: + print_iostat_summary(old_mountstats, mountstats, devices, sample_time) + old_mountstats = mountstats + time.sleep(interval) + sample_time = interval + mountstats = parse_stats_file('/proc/self/mountstats') + count -= 1 + else: + while True: + print_iostat_summary(old_mountstats, mountstats, devices, sample_time) + old_mountstats = mountstats + time.sleep(interval) + sample_time = interval + mountstats = parse_stats_file('/proc/self/mountstats') + +# +# Main +# +prog = os.path.basename(sys.argv[0]) + +try: + if prog == 'mountstats': + mountstats_command() + elif prog == 'ms-nfsstat': + nfsstat_command() + elif prog == 'ms-iostat': + iostat_command() +except KeyboardInterrupt: + print 'Caught ^C... exiting' + sys.exit(1) + +sys.exit(0) diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py new file mode 100644 index 0000000..9626d42 --- /dev/null +++ b/tools/nfs-iostat/nfs-iostat.py @@ -0,0 +1,564 @@ +#!/usr/bin/env python +# -*- python-mode -*- +"""Emulate iostat for NFS mount points using /proc/self/mountstats +""" + +__copyright__ = """ +Copyright (C) 2005, Chuck Lever + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" + +import sys, os, time + +Iostats_version = '0.2' + +def difference(x, y): + """Used for a map() function + """ + return x - y + +NfsEventCounters = [ + 'inoderevalidates', + 'dentryrevalidates', + 'datainvalidates', + 'attrinvalidates', + 'vfsopen', + 'vfslookup', + 'vfspermission', + 'vfsupdatepage', + 'vfsreadpage', + 'vfsreadpages', + 'vfswritepage', + 'vfswritepages', + 'vfsreaddir', + 'vfssetattr', + 'vfsflush', + 'vfsfsync', + 'vfslock', + 'vfsrelease', + 'congestionwait', + 'setattrtrunc', + 'extendwrite', + 'sillyrenames', + 'shortreads', + 'shortwrites', + 'delay' +] + +NfsByteCounters = [ + 'normalreadbytes', + 'normalwritebytes', + 'directreadbytes', + 'directwritebytes', + 'serverreadbytes', + 'serverwritebytes', + 'readpages', + 'writepages' +] + +class DeviceData: + """DeviceData objects provide methods for parsing and displaying + data for a single mount grabbed from /proc/self/mountstats + """ + def __init__(self): + self.__nfs_data = dict() + self.__rpc_data = dict() + self.__rpc_data['ops'] = [] + + def __parse_nfs_line(self, words): + if words[0] == 'device': + self.__nfs_data['export'] = words[1] + self.__nfs_data['mountpoint'] = words[4] + self.__nfs_data['fstype'] = words[7] + if words[7] == 'nfs': + self.__nfs_data['statvers'] = words[8] + elif words[0] == 'age:': + self.__nfs_data['age'] = long(words[1]) + elif words[0] == 'opts:': + self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',') + elif words[0] == 'caps:': + self.__nfs_data['servercapabilities'] = ''.join(words[1:]).split(',') + elif words[0] == 'nfsv4:': + self.__nfs_data['nfsv4flags'] = ''.join(words[1:]).split(',') + elif words[0] == 'sec:': + keys = ''.join(words[1:]).split(',') + self.__nfs_data['flavor'] = int(keys[0].split('=')[1]) + self.__nfs_data['pseudoflavor'] = 0 + if self.__nfs_data['flavor'] == 6: + self.__nfs_data['pseudoflavor'] = int(keys[1].split('=')[1]) + elif words[0] == 'events:': + i = 1 + for key in NfsEventCounters: + self.__nfs_data[key] = int(words[i]) + i += 1 + elif words[0] == 'bytes:': + i = 1 + for key in NfsByteCounters: + self.__nfs_data[key] = long(words[i]) + i += 1 + + def __parse_rpc_line(self, words): + if words[0] == 'RPC': + self.__rpc_data['statsvers'] = float(words[3]) + self.__rpc_data['programversion'] = words[5] + elif words[0] == 'xprt:': + self.__rpc_data['protocol'] = words[1] + if words[1] == 'udp': + self.__rpc_data['port'] = int(words[2]) + self.__rpc_data['bind_count'] = int(words[3]) + self.__rpc_data['rpcsends'] = int(words[4]) + self.__rpc_data['rpcreceives'] = int(words[5]) + self.__rpc_data['badxids'] = int(words[6]) + self.__rpc_data['inflightsends'] = long(words[7]) + self.__rpc_data['backlogutil'] = long(words[8]) + elif words[1] == 'tcp': + self.__rpc_data['port'] = words[2] + self.__rpc_data['bind_count'] = int(words[3]) + self.__rpc_data['connect_count'] = int(words[4]) + self.__rpc_data['connect_time'] = int(words[5]) + self.__rpc_data['idle_time'] = int(words[6]) + self.__rpc_data['rpcsends'] = int(words[7]) + self.__rpc_data['rpcreceives'] = int(words[8]) + self.__rpc_data['badxids'] = int(words[9]) + self.__rpc_data['inflightsends'] = long(words[10]) + self.__rpc_data['backlogutil'] = long(words[11]) + elif words[1] == 'rdma': + self.__rpc_data['port'] = words[2] + self.__rpc_data['bind_count'] = int(words[3]) + self.__rpc_data['connect_count'] = int(words[4]) + self.__rpc_data['connect_time'] = int(words[5]) + self.__rpc_data['idle_time'] = int(words[6]) + self.__rpc_data['rpcsends'] = int(words[7]) + self.__rpc_data['rpcreceives'] = int(words[8]) + self.__rpc_data['badxids'] = int(words[9]) + self.__rpc_data['backlogutil'] = int(words[10]) + self.__rpc_data['read_chunks'] = int(words[11]) + self.__rpc_data['write_chunks'] = int(words[12]) + self.__rpc_data['reply_chunks'] = int(words[13]) + self.__rpc_data['total_rdma_req'] = int(words[14]) + self.__rpc_data['total_rdma_rep'] = int(words[15]) + self.__rpc_data['pullup'] = int(words[16]) + self.__rpc_data['fixup'] = int(words[17]) + self.__rpc_data['hardway'] = int(words[18]) + self.__rpc_data['failed_marshal'] = int(words[19]) + self.__rpc_data['bad_reply'] = int(words[20]) + elif words[0] == 'per-op': + self.__rpc_data['per-op'] = words + else: + op = words[0][:-1] + self.__rpc_data['ops'] += [op] + self.__rpc_data[op] = [long(word) for word in words[1:]] + + def parse_stats(self, lines): + """Turn a list of lines from a mount stat file into a + dictionary full of stats, keyed by name + """ + found = False + for line in lines: + words = line.split() + if len(words) == 0: + continue + if (not found and words[0] != 'RPC'): + self.__parse_nfs_line(words) + continue + + found = True + self.__parse_rpc_line(words) + + def is_nfs_mountpoint(self): + """Return True if this is an NFS or NFSv4 mountpoint, + otherwise return False + """ + if self.__nfs_data['fstype'] == 'nfs': + return True + elif self.__nfs_data['fstype'] == 'nfs4': + return True + return False + + def compare_iostats(self, old_stats): + """Return the difference between two sets of stats + """ + result = DeviceData() + + # copy self into result + for key, value in self.__nfs_data.iteritems(): + result.__nfs_data[key] = value + for key, value in self.__rpc_data.iteritems(): + result.__rpc_data[key] = value + + # compute the difference of each item in the list + # note the copy loop above does not copy the lists, just + # the reference to them. so we build new lists here + # for the result object. + for op in result.__rpc_data['ops']: + result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op]) + + # update the remaining keys we care about + result.__rpc_data['rpcsends'] -= old_stats.__rpc_data['rpcsends'] + result.__rpc_data['backlogutil'] -= old_stats.__rpc_data['backlogutil'] + + for key in NfsEventCounters: + result.__nfs_data[key] -= old_stats.__nfs_data[key] + for key in NfsByteCounters: + result.__nfs_data[key] -= old_stats.__nfs_data[key] + + return result + + def __print_data_cache_stats(self): + """Print the data cache hit rate + """ + nfs_stats = self.__nfs_data + app_bytes_read = float(nfs_stats['normalreadbytes']) + if app_bytes_read != 0: + client_bytes_read = float(nfs_stats['serverreadbytes'] - nfs_stats['directreadbytes']) + ratio = ((app_bytes_read - client_bytes_read) * 100) / app_bytes_read + + print + print 'app bytes: %f client bytes %f' % (app_bytes_read, client_bytes_read) + print 'Data cache hit ratio: %4.2f%%' % ratio + + def __print_attr_cache_stats(self, sample_time): + """Print attribute cache efficiency stats + """ + nfs_stats = self.__nfs_data + getattr_stats = self.__rpc_data['GETATTR'] + + if nfs_stats['inoderevalidates'] != 0: + getattr_ops = float(getattr_stats[1]) + opens = float(nfs_stats['vfsopen']) + revalidates = float(nfs_stats['inoderevalidates']) - opens + if revalidates != 0: + ratio = ((revalidates - getattr_ops) * 100) / revalidates + else: + ratio = 0.0 + + data_invalidates = float(nfs_stats['datainvalidates']) + attr_invalidates = float(nfs_stats['attrinvalidates']) + + print + print '%d inode revalidations, hitting in cache %4.2f%% of the time' % \ + (revalidates, ratio) + print '%d open operations (mandatory GETATTR requests)' % opens + if getattr_ops != 0: + print '%4.2f%% of GETATTRs resulted in data cache invalidations' % \ + ((data_invalidates * 100) / getattr_ops) + + def __print_dir_cache_stats(self, sample_time): + """Print directory stats + """ + nfs_stats = self.__nfs_data + lookup_ops = self.__rpc_data['LOOKUP'][0] + readdir_ops = self.__rpc_data['READDIR'][0] + if self.__rpc_data.has_key('READDIRPLUS'): + readdir_ops += self.__rpc_data['READDIRPLUS'][0] + + dentry_revals = nfs_stats['dentryrevalidates'] + opens = nfs_stats['vfsopen'] + lookups = nfs_stats['vfslookup'] + getdents = nfs_stats['vfsreaddir'] + + print + print '%d open operations (pathname lookups)' % opens + print '%d dentry revalidates and %d vfs lookup requests' % \ + (dentry_revals, lookups), + print 'resulted in %d LOOKUPs on the wire' % lookup_ops + print '%d vfs getdents calls resulted in %d READDIRs on the wire' % \ + (getdents, readdir_ops) + + def __print_page_stats(self, sample_time): + """Print page cache stats + """ + nfs_stats = self.__nfs_data + + vfsreadpage = nfs_stats['vfsreadpage'] + vfsreadpages = nfs_stats['vfsreadpages'] + pages_read = nfs_stats['readpages'] + vfswritepage = nfs_stats['vfswritepage'] + vfswritepages = nfs_stats['vfswritepages'] + pages_written = nfs_stats['writepages'] + + print + print '%d nfs_readpage() calls read %d pages' % \ + (vfsreadpage, vfsreadpage) + print '%d nfs_readpages() calls read %d pages' % \ + (vfsreadpages, pages_read - vfsreadpage), + if vfsreadpages != 0: + print '(%.1f pages per call)' % \ + (float(pages_read - vfsreadpage) / vfsreadpages) + else: + print + + print + print '%d nfs_updatepage() calls' % nfs_stats['vfsupdatepage'] + print '%d nfs_writepage() calls wrote %d pages' % \ + (vfswritepage, vfswritepage) + print '%d nfs_writepages() calls wrote %d pages' % \ + (vfswritepages, pages_written - vfswritepage), + if (vfswritepages) != 0: + print '(%.1f pages per call)' % \ + (float(pages_written - vfswritepage) / vfswritepages) + else: + print + + congestionwaits = nfs_stats['congestionwait'] + if congestionwaits != 0: + print + print '%d congestion waits' % congestionwaits + + def __print_rpc_op_stats(self, op, sample_time): + """Print generic stats for one RPC op + """ + if not self.__rpc_data.has_key(op): + return + + rpc_stats = self.__rpc_data[op] + ops = float(rpc_stats[0]) + retrans = float(rpc_stats[1] - rpc_stats[0]) + kilobytes = float(rpc_stats[3] + rpc_stats[4]) / 1024 + rtt = float(rpc_stats[6]) + exe = float(rpc_stats[7]) + + # prevent floating point exceptions + if ops != 0: + kb_per_op = kilobytes / ops + retrans_percent = (retrans * 100) / ops + rtt_per_op = rtt / ops + exe_per_op = exe / ops + else: + kb_per_op = 0.0 + retrans_percent = 0.0 + rtt_per_op = 0.0 + exe_per_op = 0.0 + + op += ':' + print '%s' % op.lower().ljust(15), + print ' ops/s\t\t kB/s\t\t kB/op\t\tretrans\t\tavg RTT (ms)\tavg exe (ms)' + + print '\t\t%7.3f' % (ops / sample_time), + print '\t%7.3f' % (kilobytes / sample_time), + print '\t%7.3f' % kb_per_op, + print ' %7d (%3.1f%%)' % (retrans, retrans_percent), + print '\t%7.3f' % rtt_per_op, + print '\t%7.3f' % exe_per_op + + def display_iostats(self, sample_time, which): + """Display NFS and RPC stats in an iostat-like way + """ + sends = float(self.__rpc_data['rpcsends']) + if sample_time == 0: + sample_time = float(self.__nfs_data['age']) + if sends != 0: + backlog = (float(self.__rpc_data['backlogutil']) / sends) / sample_time + else: + backlog = 0.0 + + print + print '%s mounted on %s:' % \ + (self.__nfs_data['export'], self.__nfs_data['mountpoint']) + print + + print ' op/s\t\trpc bklog' + print '%7.2f' % (sends / sample_time), + print '\t%7.2f' % backlog + + if which == 0: + self.__print_rpc_op_stats('READ', sample_time) + self.__print_rpc_op_stats('WRITE', sample_time) + elif which == 1: + self.__print_rpc_op_stats('GETATTR', sample_time) + self.__print_rpc_op_stats('ACCESS', sample_time) + self.__print_attr_cache_stats(sample_time) + elif which == 2: + self.__print_rpc_op_stats('LOOKUP', sample_time) + self.__print_rpc_op_stats('READDIR', sample_time) + if self.__rpc_data.has_key('READDIRPLUS'): + self.__print_rpc_op_stats('READDIRPLUS', sample_time) + self.__print_dir_cache_stats(sample_time) + elif which == 3: + self.__print_rpc_op_stats('READ', sample_time) + self.__print_rpc_op_stats('WRITE', sample_time) + self.__print_page_stats(sample_time) + +# +# Functions +# + +def print_iostat_help(name): + print 'usage: %s [ [ ] ] [ ] [ ] ' % name + print + print ' Version %s' % Iostats_version + print + print ' Sample iostat-like program to display NFS client per-mount statistics.' + print + print ' The parameter specifies the amount of time in seconds between' + print ' each report. The first report contains statistics for the time since each' + print ' file system was mounted. Each subsequent report contains statistics' + print ' collected during the interval since the previous report.' + print + print ' If the parameter is specified, the value of determines the' + print ' number of reports generated at seconds apart. If the interval' + print ' parameter is specified without the parameter, the command generates' + print ' reports continuously.' + print + print ' Options include "--attr", which displays statistics related to the attribute' + print ' cache, "--dir", which displays statistics related to directory operations,' + print ' and "--page", which displays statistics related to the page cache.' + print ' By default, if no option is specified, statistics related to file I/O are' + print ' displayed.' + print + print ' If one or more names are specified, statistics for only these' + print ' mount points will be displayed. Otherwise, all NFS mount points on the' + print ' client are listed.' + +def parse_stats_file(filename): + """pop the contents of a mountstats file into a dictionary, + keyed by mount point. each value object is a list of the + lines in the mountstats file corresponding to the mount + point named in the key. + """ + ms_dict = dict() + key = '' + + f = file(filename) + for line in f.readlines(): + words = line.split() + if len(words) == 0: + continue + if words[0] == 'device': + key = words[4] + new = [ line.strip() ] + else: + new += [ line.strip() ] + ms_dict[key] = new + f.close + + return ms_dict + +def print_iostat_summary(old, new, devices, time, ac): + for device in devices: + stats = DeviceData() + stats.parse_stats(new[device]) + if not old: + stats.display_iostats(time, ac) + else: + old_stats = DeviceData() + old_stats.parse_stats(old[device]) + diff_stats = stats.compare_iostats(old_stats) + diff_stats.display_iostats(time, ac) + +def iostat_command(name): + """iostat-like command for NFS mount points + """ + mountstats = parse_stats_file('/proc/self/mountstats') + devices = [] + which = 0 + interval_seen = False + count_seen = False + + for arg in sys.argv: + if arg in ['-h', '--help', 'help', 'usage']: + print_iostat_help(name) + return + + if arg in ['-v', '--version', 'version']: + print '%s version %s' % (name, Iostats_version) + return + + if arg in ['-a', '--attr']: + which = 1 + continue + + if arg in ['-d', '--dir']: + which = 2 + continue + + if arg in ['-p', '--page']: + which = 3 + continue + + if arg == sys.argv[0]: + continue + + if arg in mountstats: + devices += [arg] + elif not interval_seen: + interval = int(arg) + if interval > 0: + interval_seen = True + else: + print 'Illegal value' + return + elif not count_seen: + count = int(arg) + if count > 0: + count_seen = True + else: + print 'Illegal value' + return + + # make certain devices contains only NFS mount points + if len(devices) > 0: + check = [] + for device in devices: + stats = DeviceData() + stats.parse_stats(mountstats[device]) + if stats.is_nfs_mountpoint(): + check += [device] + devices = check + else: + for device, descr in mountstats.iteritems(): + stats = DeviceData() + stats.parse_stats(descr) + if stats.is_nfs_mountpoint(): + devices += [device] + if len(devices) == 0: + print 'No NFS mount points were found' + return + + old_mountstats = None + sample_time = 0.0 + + if not interval_seen: + print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which) + return + + if count_seen: + while count != 0: + print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which) + old_mountstats = mountstats + time.sleep(interval) + sample_time = interval + mountstats = parse_stats_file('/proc/self/mountstats') + count -= 1 + else: + while True: + print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which) + old_mountstats = mountstats + time.sleep(interval) + sample_time = interval + mountstats = parse_stats_file('/proc/self/mountstats') + +# +# Main +# +prog = os.path.basename(sys.argv[0]) + +try: + iostat_command(prog) +except KeyboardInterrupt: + print 'Caught ^C... exiting' + sys.exit(1) + +sys.exit(0) diff --git a/tools/nlmtest/Makefile.in b/tools/nlmtest/Makefile.in index e936cfb..783c519 100644 --- a/tools/nlmtest/Makefile.in +++ b/tools/nlmtest/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -161,6 +161,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ diff --git a/tools/rpcdebug/Makefile.in b/tools/rpcdebug/Makefile.in index 2c8b408..ebd86d3 100644 --- a/tools/rpcdebug/Makefile.in +++ b/tools/rpcdebug/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -56,7 +56,7 @@ rpcdebug_LDADD = $(LDADD) rpcdebug_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(rpcdebug_CFLAGS) $(CFLAGS) \ $(rpcdebug_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -189,6 +189,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -273,8 +274,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -395,8 +396,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -408,8 +409,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -419,13 +420,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/tools/rpcgen/Makefile.in b/tools/rpcgen/Makefile.in index c3993f2..ef53401 100644 --- a/tools/rpcgen/Makefile.in +++ b/tools/rpcgen/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -59,7 +59,7 @@ rpcgen_LDADD = $(LDADD) rpcgen_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(rpcgen_CFLAGS) $(CFLAGS) \ $(rpcgen_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -189,6 +189,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -467,8 +468,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -480,8 +481,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -491,13 +492,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/Makefile.in b/utils/Makefile.in index dfb16d0..75ec603 100644 --- a/utils/Makefile.in +++ b/utils/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -177,6 +177,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -337,8 +338,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -363,8 +364,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -374,13 +375,12 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/exportfs/Makefile.in b/utils/exportfs/Makefile.in index 32c0116..84ed403 100644 --- a/utils/exportfs/Makefile.in +++ b/utils/exportfs/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -57,7 +57,7 @@ am__DEPENDENCIES_1 = exportfs_DEPENDENCIES = ../../support/export/libexport.a \ ../../support/nfs/libnfs.a ../../support/misc/libmisc.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -192,6 +192,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -280,8 +281,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -478,8 +479,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -491,8 +492,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -502,13 +503,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man index 59789cc..c7b230a 100644 --- a/utils/exportfs/exportfs.man +++ b/utils/exportfs/exportfs.man @@ -22,14 +22,14 @@ The .B exportfs command is used to maintain the current table of exported file systems for NFS. This list is kept in a separate file named -.BR /var/lib/nfs/xtab +.BR /var/lib/nfs/etab which is read by .B mountd when a remote host requests access to mount a file tree, and parts of the list which are active are kept in the kernel's export table. .P Normally this -.B xtab +.B etab file is initialized with the list of all file systems named in .B /etc/exports by invoking @@ -59,7 +59,7 @@ In the new mode, does not give any information to the kernel but only provides it to .B mountd through the -.B /var/lib/nfs/xtab +.B /var/lib/nfs/etab file. .B mountd will listen to requests from the kernel and will provide information @@ -69,7 +69,7 @@ In the legacy mode, any export requests which identify a specific host (rather than a subnet or netgroup etc) are entered directly into the kernel's export table as well as being written to -.BR /var/lib/nfs/xtab . +.BR /var/lib/nfs/etab . Further, any mount points listed in .B /var/lib/nfs/rmtab which match a non host-specific export request will cause an @@ -93,8 +93,8 @@ file, so that only default options and options given on the command line are used. .TP .B -r -Reexport all directories. It synchronizes /var/lib/nfs/xtab -with /etc/exports. It removes entries in /var/lib/nfs/xtab +Reexport all directories. It synchronizes /var/lib/nfs/etab +with /etc/exports. It removes entries in /var/lib/nfs/etab which are deleted from /etc/exports, and remove any entries from the kernel export table which are no longer valid. .TP @@ -120,7 +120,7 @@ entries to the export table. When using all directories in .B exports(5) are added to -.B xtab +.B etab and the resulting list is pushed into the kernel. .P The @@ -152,7 +152,7 @@ directory. Modifications of the kernel export table used by .B nfsd(8) take place immediately after parsing the command line and updating the -.B xtab +.B etab file. .P The default export options are @@ -163,14 +163,14 @@ The third synopsis shows how to unexported a currently exported directory. When using .BR "exportfs -ua" , all entries listed in -.B xtab +.B etab are removed from the kernel export tables, and the file is cleared. This effectively shuts down all NFS activity. .P To remove an export to a host, specify a .I host:/path pair. This deletes the specified entry from -.B xtab +.B etab and removes the corresponding kernel entry (if any). To remove one or more exports to several hosts, use .BR "exportfs -ua" . @@ -198,7 +198,7 @@ and pushes the resulting export entries into the kernel: To export the .B /usr/tmp directory to host -.BR djando , +.BR django , allowing asynchronous writes, one would do this: .P .nf diff --git a/utils/gssd/Makefile.in b/utils/gssd/Makefile.in index 1441131..fa6cccb 100644 --- a/utils/gssd/Makefile.in +++ b/utils/gssd/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -93,7 +93,7 @@ svcgssd_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(svcgssd_LDFLAGS) $(LDFLAGS) -o $@ sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(sbin_SCRIPTS) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -228,6 +228,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -370,8 +371,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -877,8 +878,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -890,8 +891,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -901,13 +902,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/gssd/err_util.c b/utils/gssd/err_util.c index 5644db6..2583e06 100644 --- a/utils/gssd/err_util.c +++ b/utils/gssd/err_util.c @@ -60,3 +60,8 @@ void printerr(int priority, char *format, ...) xlog_backend(L_ERROR, format, args); va_end(args); } + +int get_verbosity(void) +{ + return verbosity; +} diff --git a/utils/gssd/err_util.h b/utils/gssd/err_util.h index 5e5af48..c4df32d 100644 --- a/utils/gssd/err_util.h +++ b/utils/gssd/err_util.h @@ -33,5 +33,6 @@ void initerr(char *progname, int verbosity, int fg); void printerr(int priority, char *format, ...); +int get_verbosity(void); #endif /* _ERR_UTIL_H_ */ diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c index bbcad20..6d8f3b9 100644 --- a/utils/gssd/gssd.c +++ b/utils/gssd/gssd.c @@ -57,8 +57,11 @@ char pipefs_dir[PATH_MAX] = GSSD_PIPEFS_DIR; char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR; char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE; char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR; +char *ccachesearch[GSSD_MAX_CCACHE_SEARCH + 1]; int use_memcache = 0; int root_uses_machine_creds = 1; +unsigned int context_timeout = 0; +char *preferred_realm = NULL; void sig_die(int signal) @@ -81,7 +84,7 @@ sig_hup(int signal) static void usage(char *progname) { - fprintf(stderr, "usage: %s [-f] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n", + fprintf(stderr, "usage: %s [-f] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n", progname); exit(1); } @@ -93,10 +96,12 @@ main(int argc, char *argv[]) int verbosity = 0; int rpc_verbosity = 0; int opt; + int i; extern char *optarg; char *progname; - while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) { + memset(ccachesearch, 0, sizeof(ccachesearch)); + while ((opt = getopt(argc, argv, "fvrmnMp:k:d:t:R:")) != -1) { switch (opt) { case 'f': fg = 1; @@ -131,11 +136,27 @@ main(int argc, char *argv[]) if (ccachedir[sizeof(ccachedir)-1] != '\0') errx(1, "ccachedir path name too long"); break; + case 't': + context_timeout = atoi(optarg); + break; + case 'R': + preferred_realm = strdup(optarg); + break; default: usage(argv[0]); break; } } + + i = 0; + ccachesearch[i++] = strtok(ccachedir, ":"); + do { + ccachesearch[i++] = strtok(NULL, ":"); + } while (ccachesearch[i-1] != NULL && i < GSSD_MAX_CCACHE_SEARCH); + + if (preferred_realm == NULL) + gssd_k5_get_default_realm(&preferred_realm); + snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s", pipefs_dir, GSSD_SERVICE_NAME); if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0') diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h index e17edde..082039a 100644 --- a/utils/gssd/gssd.h +++ b/utils/gssd/gssd.h @@ -50,6 +50,7 @@ #define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab" #define GSSD_SERVICE_NAME "nfs" #define GSSD_SERVICE_NAME_LEN 3 +#define GSSD_MAX_CCACHE_SEARCH 16 /* * The gss mechanisms that we can handle @@ -61,9 +62,11 @@ enum {AUTHTYPE_KRB5, AUTHTYPE_SPKM3, AUTHTYPE_LIPKEY}; extern char pipefs_dir[PATH_MAX]; extern char pipefs_nfsdir[PATH_MAX]; extern char keytabfile[PATH_MAX]; -extern char ccachedir[PATH_MAX]; +extern char *ccachesearch[]; extern int use_memcache; extern int root_uses_machine_creds; +extern unsigned int context_timeout; +extern char *preferred_realm; TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list; @@ -80,6 +83,7 @@ struct clnt_info { int krb5_poll_index; int spkm3_fd; int spkm3_poll_index; + int port; }; void init_client_list(void); diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man index 2fa749e..0a23cd6 100644 --- a/utils/gssd/gssd.man +++ b/utils/gssd/gssd.man @@ -74,7 +74,11 @@ where to look for the rpc_pipefs filesystem. The default value is .B -d directory Tells .B rpc.gssd -where to look for kerberos credential files. The default value is "/tmp". +where to look for Kerberos credential files. The default value is "/tmp". +This can also be a colon separated list of directories to be searched +for Kerberos credential files. Note that if machine credentials are being +stored in files, then the first directory on this list is where the +machine credentials are stored. .TP .B -v Increases the verbosity of the output (can be specified multiple times). @@ -82,6 +86,21 @@ Increases the verbosity of the output (can be specified multiple times). .B -r If the rpcsec_gss library supports setting debug level, increases the verbosity of the output (can be specified multiple times). +.TP +.B -R realm +Kerberos tickets from this +.I realm +will be preferred when scanning available credentials cache files to be +used to create a context. By default, the default realm, as configured +in the Kerberos configuration file, is preferred. +.TP +.B -t timeout +Timeout, in seconds, for kernel gss contexts. This option allows you to force +new kernel contexts to be negotiated after +.I timeout +seconds, which allows changing Kerberos tickets and identities frequently. +The default is no explicit timeout, which means the kernel context will live +the lifetime of the Kerberos service ticket used in its creation. .SH SEE ALSO .BR rpc.svcgssd(8) .SH AUTHORS diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c index 6860cc8..f415a10 100644 --- a/utils/gssd/gssd_proc.c +++ b/utils/gssd/gssd_proc.c @@ -102,7 +102,7 @@ int pollsize; /* the size of pollaray (in pollfd's) */ /* XXX buffer problems: */ static int read_service_info(char *info_file_name, char **servicename, char **servername, - int *prog, int *vers, char **protocol) { + int *prog, int *vers, char **protocol, int *port) { #define INFOBUFLEN 256 char buf[INFOBUFLEN]; static char dummy[128]; @@ -112,6 +112,8 @@ read_service_info(char *info_file_name, char **servicename, char **servername, char program[16]; char version[16]; char protoname[16]; + char cb_port[128]; + char *p; in_addr_t inaddr; int fd = -1; struct hostent *ent = NULL; @@ -143,6 +145,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername, goto fail; } + cb_port[0] = '\0'; + if ((p = strstr(buf, "port")) != NULL) + sscanf(p, "port: %127s\n", cb_port); + /* check service, program, and version */ if(memcmp(service, "nfs", 3)) return -1; *prog = atoi(program + 1); /* skip open paren */ @@ -163,6 +169,8 @@ read_service_info(char *info_file_name, char **servicename, char **servername, if (!(*servicename = calloc(strlen(buf) + 1, 1))) goto fail; memcpy(*servicename, buf, strlen(buf)); + if (cb_port[0] != '\0') + *port = atoi(cb_port); if (!(*protocol = strdup(protoname))) goto fail; @@ -238,7 +246,7 @@ process_clnt_dir_files(struct clnt_info * clp) if ((clp->servicename == NULL) && read_service_info(info_file_name, &clp->servicename, &clp->servername, &clp->prog, &clp->vers, - &clp->protocol)) + &clp->protocol, &clp->port)) return -1; return 0; } @@ -419,7 +427,7 @@ do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd, gss_buffer_desc *context_token) { char *buf = NULL, *p = NULL, *end = NULL; - unsigned int timeout = 0; /* XXX decide on a reasonable value */ + unsigned int timeout = context_timeout; unsigned int buf_size = 0; printerr(1, "doing downcall\n"); @@ -430,7 +438,6 @@ do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd, end = buf + buf_size; if (WRITE_BYTES(&p, end, uid)) goto out_err; - /* Not setting any timeout for now: */ if (WRITE_BYTES(&p, end, timeout)) goto out_err; if (WRITE_BYTES(&p, end, pd->pd_seq_win)) goto out_err; if (write_buffer(&p, end, &pd->pd_ctx_hndl)) goto out_err; @@ -587,6 +594,8 @@ int create_auth_rpc_client(struct clnt_info *clp, clp->servername, uid); goto out_fail; } + if (clp->port) + ((struct sockaddr_in *)a->ai_addr)->sin_port = htons(clp->port); if (a->ai_protocol == IPPROTO_TCP) { if ((rpc_clnt = clnttcp_create( (struct sockaddr_in *) a->ai_addr, @@ -675,6 +684,7 @@ handle_krb5_upcall(struct clnt_info *clp) gss_buffer_desc token; char **credlist = NULL; char **ccname; + char **dirname; int create_resp = -1; printerr(1, "handling krb5 upcall\n"); @@ -691,10 +701,13 @@ handle_krb5_upcall(struct clnt_info *clp) if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0)) { /* Tell krb5 gss which credentials cache to use */ - gssd_setup_krb5_user_gss_ccache(uid, clp->servername); - - create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, - AUTHTYPE_KRB5); + for (dirname = ccachesearch; *dirname != NULL; dirname++) { + if (gssd_setup_krb5_user_gss_ccache(uid, clp->servername, *dirname) == 0) + create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, + AUTHTYPE_KRB5); + if (create_resp == 0) + break; + } } if (create_resp != 0) { if (uid == 0 && root_uses_machine_creds == 1) { diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index 3cf27ca..77814bc 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -131,10 +131,12 @@ struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL; /*==========================*/ static int select_krb5_ccache(const struct dirent *d); -static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d); +static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, + struct dirent **d); static int gssd_get_single_krb5_cred(krb5_context context, krb5_keytab kt, struct gssd_k5_kt_princ *ple); - +static int query_krb5_ccache(const char* cred_cache, char **ret_princname, + char **ret_realm); /* * Called from the scandir function to weed out potential krb5 @@ -159,7 +161,7 @@ select_krb5_ccache(const struct dirent *d) } /* - * Look in the ccachedir for files that look like they + * Look in directory "dirname" for files that look like they * are Kerberos Credential Cache files for a given UID. Return * non-zero and the dirent pointer for the entry most likely to be * what we want. Otherwise, return zero and no dirent pointer. @@ -170,7 +172,7 @@ select_krb5_ccache(const struct dirent *d) * 1 => found an existing entry */ static int -gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d) +gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d) { struct dirent **namelist; int n; @@ -178,20 +180,29 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d) int found = 0; struct dirent *best_match_dir = NULL; struct stat best_match_stat, tmp_stat; + char buf[1030]; + char *princname = NULL; + char *realm = NULL; + int score, best_match_score = 0; memset(&best_match_stat, 0, sizeof(best_match_stat)); *d = NULL; - n = scandir(ccachedir, &namelist, select_krb5_ccache, 0); + n = scandir(dirname, &namelist, select_krb5_ccache, 0); if (n < 0) { - perror("scandir looking for krb5 credentials caches"); + printerr(1, "Error doing scandir on directory '%s': %s\n", + dirname, strerror(errno)); } else if (n > 0) { char statname[1024]; for (i = 0; i < n; i++) { - printerr(3, "CC file '%s' being considered\n", - namelist[i]->d_name); snprintf(statname, sizeof(statname), - "%s/%s", ccachedir, namelist[i]->d_name); + "%s/%s", dirname, namelist[i]->d_name); + printerr(3, "CC file '%s' being considered, " + "with preferred realm '%s'\n", + statname, preferred_realm ? + preferred_realm : ""); + snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, + namelist[i]->d_name); if (lstat(statname, &tmp_stat)) { printerr(0, "Error doing stat on file '%s'\n", statname); @@ -200,20 +211,33 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d) } /* Only pick caches owned by the user (uid) */ if (tmp_stat.st_uid != uid) { - printerr(3, "'%s' owned by %u, not %u\n", + printerr(3, "CC file '%s' owned by %u, not %u\n", statname, tmp_stat.st_uid, uid); free(namelist[i]); continue; } if (!S_ISREG(tmp_stat.st_mode)) { - printerr(3, "'%s' is not a regular file\n", + printerr(3, "CC file '%s' is not a regular file\n", statname); free(namelist[i]); continue; } - printerr(3, "CC file '%s' matches owner check and has " - "mtime of %u\n", - namelist[i]->d_name, tmp_stat.st_mtime); + if (!query_krb5_ccache(buf, &princname, &realm)) { + printerr(3, "CC file '%s' is expired or corrupt\n", + statname); + free(namelist[i]); + continue; + } + + score = 0; + if (preferred_realm && + strcmp(realm, preferred_realm) == 0) + score++; + + printerr(3, "CC file '%s'(%s@%s) passed all checks and" + " has mtime of %u\n", + statname, princname, realm, + tmp_stat.st_mtime); /* * if more than one match is found, return the most * recent (the one with the latest mtime), and @@ -222,30 +246,38 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d) if (!found) { best_match_dir = namelist[i]; best_match_stat = tmp_stat; + best_match_score = score; found++; } else { /* - * If the current match has an mtime later + * If current score is higher than best match + * score, we use the current match. Otherwise, + * if the current match has an mtime later * than the one we are looking at, then use * the current match. Otherwise, we still * have the best match. */ - if (tmp_stat.st_mtime > - best_match_stat.st_mtime) { + if (best_match_score < score || + (best_match_score == score && + tmp_stat.st_mtime > + best_match_stat.st_mtime)) { free(best_match_dir); best_match_dir = namelist[i]; best_match_stat = tmp_stat; + best_match_score = score; } else { free(namelist[i]); } - printerr(3, "CC file '%s' is our " + printerr(3, "CC file '%s/%s' is our " "current best match " "with mtime of %u\n", - best_match_dir->d_name, + dirname, best_match_dir->d_name, best_match_stat.st_mtime); } + free(princname); + free(realm); } free(namelist); } @@ -277,7 +309,9 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid) u_int maj_stat, min_stat; gss_cred_id_t credh; gss_OID_set_desc desired_mechs; - krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC }; + krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_MD4 }; int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]); /* We only care about getting a krb5 cred */ @@ -289,8 +323,9 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid) &credh, NULL, NULL); if (maj_stat != GSS_S_COMPLETE) { - pgsserr("gss_acquire_cred", - maj_stat, min_stat, &krb5oid); + if (get_verbosity() > 0) + pgsserr("gss_acquire_cred", + maj_stat, min_stat, &krb5oid); return -1; } @@ -404,7 +439,7 @@ gssd_get_single_krb5_cred(krb5_context context, cache_type = "FILE"; snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s", cache_type, - ccachedir, GSSD_DEFAULT_CRED_PREFIX, + ccachesearch[0], GSSD_DEFAULT_CRED_PREFIX, GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm); ple->endtime = my_creds.times.endtime; if (ple->ccname != NULL) @@ -879,6 +914,94 @@ out: return retval; } + +static inline int data_is_equal(krb5_data d1, krb5_data d2) +{ + return (d1.length == d2.length + && memcmp(d1.data, d2.data, d1.length) == 0); +} + +static int +check_for_tgt(krb5_context context, krb5_ccache ccache, + krb5_principal principal) +{ + krb5_error_code ret; + krb5_creds creds; + krb5_cc_cursor cur; + int found = 0; + + ret = krb5_cc_start_seq_get(context, ccache, &cur); + if (ret) + return 0; + + while (!found && + (ret = krb5_cc_next_cred(context, ccache, &cur, &creds)) == 0) { + if (creds.server->length == 2 && + data_is_equal(creds.server->realm, + principal->realm) && + creds.server->data[0].length == 6 && + memcmp(creds.server->data[0].data, + "krbtgt", 6) == 0 && + data_is_equal(creds.server->data[1], + principal->realm) && + creds.times.endtime > time(NULL)) + found = 1; + krb5_free_cred_contents(context, &creds); + } + krb5_cc_end_seq_get(context, ccache, &cur); + + return found; +} + +static int +query_krb5_ccache(const char* cred_cache, char **ret_princname, + char **ret_realm) +{ + krb5_error_code ret; + krb5_context context; + krb5_ccache ccache; + krb5_principal principal; + int found = 0; + char *str = NULL; + char *princstring; + + ret = krb5_init_context(&context); + if (ret) + return 0; + + if(!cred_cache || krb5_cc_resolve(context, cred_cache, &ccache)) + goto err_cache; + + if (krb5_cc_set_flags(context, ccache, 0)) + goto err_princ; + + ret = krb5_cc_get_principal(context, ccache, &principal); + if (ret) + goto err_princ; + + found = check_for_tgt(context, ccache, principal); + if (found) { + ret = krb5_unparse_name(context, principal, &princstring); + if (ret == 0) { + if ((str = strchr(princstring, '@')) != NULL) { + *str = '\0'; + *ret_princname = strdup(princstring); + *ret_realm = strdup(str+1); + } + k5_free_unparsed_name(context, princstring); + } else { + found = 0; + } + } + krb5_free_principal(context, principal); +err_princ: + krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE); + krb5_cc_close(context, ccache); +err_cache: + krb5_free_context(context); + return found; +} + /*==========================*/ /*=== External routines ===*/ /*==========================*/ @@ -889,10 +1012,11 @@ out: * do the best we can. * * Returns: - * void + * 0 => a ccache was found + * 1 => no ccache was found */ -void -gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername) +int +gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname) { char buf[MAX_NETOBJ_SZ]; struct dirent *d; @@ -900,17 +1024,16 @@ gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername) printerr(2, "getting credentials for client with uid %u for " "server %s\n", uid, servername); memset(buf, 0, sizeof(buf)); - if (gssd_find_existing_krb5_ccache(uid, &d)) { - snprintf(buf, sizeof(buf), "FILE:%s/%s", - ccachedir, d->d_name); + if (gssd_find_existing_krb5_ccache(uid, dirname, &d)) { + snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name); free(d); } else - snprintf(buf, sizeof(buf), "FILE:%s/%s%u", - ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid); + return 1; printerr(2, "using %s as credentials cache for client with " "uid %u for server %s\n", buf, uid, servername); gssd_set_krb5_ccache_name(buf); + return 0; } /* @@ -1129,3 +1252,19 @@ gssd_k5_err_msg(krb5_context context, krb5_error_code code) return error_message(code); #endif } + +/* + * Return default Kerberos realm + */ +void +gssd_k5_get_default_realm(char **def_realm) +{ + krb5_context context; + + if (krb5_init_context(&context)) + return; + + krb5_get_default_realm(context, def_realm); + + krb5_free_context(context); +} diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h index 78ad45c..4b2da6b 100644 --- a/utils/gssd/krb5_util.h +++ b/utils/gssd/krb5_util.h @@ -17,7 +17,8 @@ struct gssd_k5_kt_princ { }; -void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername); +int gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, + char *dirname); int gssd_get_krb5_machine_cred_list(char ***list); void gssd_free_krb5_machine_cred_list(char **list); void gssd_setup_krb5_machine_gss_ccache(char *servername); @@ -26,6 +27,7 @@ int gssd_refresh_krb5_machine_credential(char *hostname, struct gssd_k5_kt_princ *ple); const char * gssd_k5_err_msg(krb5_context context, krb5_error_code code); +void gssd_k5_get_default_realm(char **def_realm); #ifdef HAVE_SET_ALLOWABLE_ENCTYPES int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid); diff --git a/utils/idmapd/Makefile.in b/utils/idmapd/Makefile.in index a31cd5e..057e80c 100644 --- a/utils/idmapd/Makefile.in +++ b/utils/idmapd/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -55,7 +55,7 @@ am_idmapd_OBJECTS = atomicio.$(OBJEXT) cfg.$(OBJEXT) idmapd.$(OBJEXT) \ strlcat.$(OBJEXT) strlcpy.$(OBJEXT) idmapd_OBJECTS = $(am_idmapd_OBJECTS) idmapd_DEPENDENCIES = ../../support/nfs/libnfs.a -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -189,6 +189,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -288,8 +289,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -445,8 +446,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -458,8 +459,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -469,13 +470,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/mount/Makefile.am b/utils/mount/Makefile.am index 27a01de..459fa45 100644 --- a/utils/mount/Makefile.am +++ b/utils/mount/Makefile.am @@ -9,11 +9,13 @@ man5_MANS = nfs.man sbin_PROGRAMS = mount.nfs EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS) -mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c parse_opt.c \ +mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c \ + parse_opt.c parse_dev.c \ nfsmount.c nfs4mount.c stropts.c\ nfsumount.c \ - mount_constants.h error.h network.h fstab.h token.h parse_opt.h \ - nfs4_mount.h nfs_mount4.h stropts.h + mount_constants.h error.h network.h fstab.h token.h \ + parse_opt.h parse_dev.h \ + nfs4_mount.h nfs_mount4.h stropts.h version.h mount_nfs_LDADD = ../../support/nfs/libnfs.a \ ../../support/export/libexport.a diff --git a/utils/mount/Makefile.in b/utils/mount/Makefile.in index f1c341d..876fb69 100644 --- a/utils/mount/Makefile.in +++ b/utils/mount/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -53,12 +53,12 @@ sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(sbin_PROGRAMS) am_mount_nfs_OBJECTS = mount.$(OBJEXT) error.$(OBJEXT) \ network.$(OBJEXT) fstab.$(OBJEXT) token.$(OBJEXT) \ - parse_opt.$(OBJEXT) nfsmount.$(OBJEXT) nfs4mount.$(OBJEXT) \ - stropts.$(OBJEXT) nfsumount.$(OBJEXT) + parse_opt.$(OBJEXT) parse_dev.$(OBJEXT) nfsmount.$(OBJEXT) \ + nfs4mount.$(OBJEXT) stropts.$(OBJEXT) nfsumount.$(OBJEXT) mount_nfs_OBJECTS = $(am_mount_nfs_OBJECTS) mount_nfs_DEPENDENCIES = ../../support/nfs/libnfs.a \ ../../support/export/libexport.a -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -192,6 +192,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -233,11 +234,13 @@ top_srcdir = @top_srcdir@ man8_MANS = mount.nfs.man umount.nfs.man man5_MANS = nfs.man EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS) -mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c parse_opt.c \ +mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c \ + parse_opt.c parse_dev.c \ nfsmount.c nfs4mount.c stropts.c\ nfsumount.c \ - mount_constants.h error.h network.h fstab.h token.h parse_opt.h \ - nfs4_mount.h nfs_mount4.h stropts.h + mount_constants.h error.h network.h fstab.h token.h \ + parse_opt.h parse_dev.h \ + nfs4_mount.h nfs_mount4.h stropts.h version.h mount_nfs_LDADD = ../../support/nfs/libnfs.a \ ../../support/export/libexport.a @@ -285,8 +288,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -321,6 +324,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfs4mount.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsmount.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsumount.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_dev.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_opt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stropts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@ @@ -447,8 +451,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -460,8 +464,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -471,13 +475,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/mount/error.c b/utils/mount/error.c index 23a91ff..5c9d3f2 100644 --- a/utils/mount/error.c +++ b/utils/mount/error.c @@ -35,8 +35,6 @@ #include #include #include -#include -#include #include "xcommon.h" #include "nls.h" @@ -227,9 +225,17 @@ void mount_error(const char *spec, const char *mount_point, int error) nfs_error(_("%s: mount point %s does not exist"), progname, mount_point); break; + case ESPIPE: + rpc_mount_errors((char *)spec, 0, 0); + break; case EIO: + nfs_error(_("%s: mount system call failed"), progname); + break; case EFAULT: - nfs_error(_("%s: internal error"), progname); + nfs_error(_("%s: encountered unexpected error condition."), + progname); + nfs_error(_("%s: please report the error to" PACKAGE_BUGREPORT), + progname); break; default: nfs_error(_("%s: %s"), diff --git a/utils/mount/error.h b/utils/mount/error.h index 8b8e9ae..7126de5 100644 --- a/utils/mount/error.h +++ b/utils/mount/error.h @@ -21,6 +21,9 @@ * */ +#ifndef _NFS_UTILS_MOUNT_ERROR_H +#define _NFS_UTILS_MOUNT_ERROR_H + char *nfs_strerror(int); void mount_error(const char *, const char *, int); @@ -28,3 +31,5 @@ void rpc_mount_errors(char *, int, int); void sys_mount_errors(char *, int, int, int); void umount_error(int, const char *); + +#endif /* _NFS_UTILS_MOUNT_ERROR_H */ diff --git a/utils/mount/fstab.c b/utils/mount/fstab.c index ec7ab52..e19e58b 100644 --- a/utils/mount/fstab.c +++ b/utils/mount/fstab.c @@ -46,6 +46,11 @@ get_mtab_info(void) { } } +void +reset_mtab_info(void) { + have_mtab_info = 0; +} + int mtab_does_not_exist(void) { get_mtab_info(); diff --git a/utils/mount/fstab.h b/utils/mount/fstab.h index 64c8355..dc7c9fc 100644 --- a/utils/mount/fstab.h +++ b/utils/mount/fstab.h @@ -1,5 +1,5 @@ -#ifndef _NFS_FSTAB_H -#define _NFS_FSTAB_H +#ifndef _NFS_UTILS_MOUNT_FSTAB_H +#define _NFS_UTILS_MOUNT_FSTAB_H #include "nfs_mntent.h" @@ -9,6 +9,7 @@ int mtab_is_writable(void); int mtab_does_not_exist(void); +void reset_mtab_info(void); struct mntentchn { struct mntentchn *nxt, *prev; @@ -26,5 +27,4 @@ void lock_mtab (void); void unlock_mtab (void); void update_mtab (const char *special, struct mntent *with); -#endif /* _NFS_FSTAB_H */ - +#endif /* _NFS_UTILS_MOUNT_FSTAB_H */ diff --git a/utils/mount/mount.c b/utils/mount/mount.c index 5076468..06e2804 100644 --- a/utils/mount/mount.c +++ b/utils/mount/mount.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -45,8 +44,8 @@ #include "nfs4_mount.h" #include "mount.h" #include "error.h" -#include "network.h" #include "stropts.h" +#include "version.h" char *progname; int nfs_mount_data_version; @@ -146,21 +145,7 @@ static const struct opt_map opt_map[] = { { NULL, 0, 0, 0 } }; -#define MAKE_VERSION(p,q,r) (65536 * (p) + 256 * (q) + (r)) - -int linux_version_code(void) -{ - struct utsname my_utsname; - int p, q, r; - - if (uname(&my_utsname) == 0) { - p = atoi(strtok(my_utsname.release, ".")); - q = atoi(strtok(NULL, ".")); - r = atoi(strtok(NULL, ".")); - return MAKE_VERSION(p,q,r); - } - return 0; -} +static void parse_opts(const char *options, int *flags, char **extra_opts); /* * Choose the version of the nfs_mount_data structure that is appropriate @@ -237,12 +222,59 @@ static char *fix_opts_string(int flags, const char *extra_opts) return new_opts; } +/* Create mtab with a root entry. */ +static void +create_mtab (void) { + struct mntentchn *fstab; + struct mntent mnt; + int flags; + mntFILE *mfp; + + lock_mtab(); + + mfp = nfs_setmntent (MOUNTED, "a+"); + if (mfp == NULL || mfp->mntent_fp == NULL) { + int errsv = errno; + die (EX_FILEIO, _("mount: can't open %s for writing: %s"), + MOUNTED, strerror (errsv)); + } + + /* Find the root entry by looking it up in fstab */ + if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) { + char *extra_opts; + parse_opts (fstab->m.mnt_opts, &flags, &extra_opts); + mnt.mnt_dir = "/"; + mnt.mnt_fsname = xstrdup(fstab->m.mnt_fsname); + mnt.mnt_type = fstab->m.mnt_type; + mnt.mnt_opts = fix_opts_string (flags, extra_opts); + mnt.mnt_freq = mnt.mnt_passno = 0; + free(extra_opts); + + if (nfs_addmntent (mfp, &mnt) == 1) { + int errsv = errno; + die (EX_FILEIO, _("mount: error writing %s: %s"), + _PATH_MOUNTED, strerror (errsv)); + } + } + if (fchmod (fileno (mfp->mntent_fp), 0644) < 0) + if (errno != EROFS) { + int errsv = errno; + die (EX_FILEIO, + _("mount: error changing mode of %s: %s"), + _PATH_MOUNTED, strerror (errsv)); + } + nfs_endmntent (mfp); + + unlock_mtab(); + + reset_mtab_info(); +} + static int add_mtab(char *spec, char *mount_point, char *fstype, int flags, char *opts, int freq, int pass) { struct mntent ment; - mntFILE *mtab; - int result = EX_FILEIO; + int result = EX_SUCCESS; ment.mnt_fsname = spec; ment.mnt_dir = mount_point; @@ -251,39 +283,37 @@ static int add_mtab(char *spec, char *mount_point, char *fstype, ment.mnt_freq = freq; ment.mnt_passno = pass; - if (flags & MS_REMOUNT) { - update_mtab(ment.mnt_dir, &ment); - free(ment.mnt_opts); - return EX_SUCCESS; - } - - lock_mtab(); - - mtab = nfs_setmntent(MOUNTED, "a+"); - if (mtab == NULL || mtab->mntent_fp == NULL) { - nfs_error(_("Can't open mtab: %s"), - strerror(errno)); - goto fail_unlock; - } - - if (nfs_addmntent(mtab, &ment) == 1) { - nfs_error(_("Can't write mount entry to mtab: %s"), - strerror(errno)); - goto fail_close; + if (!nomtab && mtab_does_not_exist()) { + if (verbose > 1) + printf(_("mount: no %s found - creating it..\n"), + MOUNTED); + create_mtab (); } - if (fchmod(fileno(mtab->mntent_fp), 0644) == -1) { - nfs_error(_("Can't set permissions on mtab: %s"), - strerror(errno)); - goto fail_close; + if (!nomtab && mtab_is_writable()) { + if (flags & MS_REMOUNT) + update_mtab(ment.mnt_dir, &ment); + else { + mntFILE *mtab; + + lock_mtab(); + mtab = nfs_setmntent(MOUNTED, "a+"); + if (mtab == NULL || mtab->mntent_fp == NULL) { + nfs_error(_("Can't open mtab: %s"), + strerror(errno)); + result = EX_FILEIO; + } else { + if (nfs_addmntent(mtab, &ment) == 1) { + nfs_error(_("Can't write mount entry to mtab: %s"), + strerror(errno)); + result = EX_FILEIO; + } + } + nfs_endmntent(mtab); + unlock_mtab(); + } } - result = EX_SUCCESS; - -fail_close: - nfs_endmntent(mtab); -fail_unlock: - unlock_mtab(); free(ment.mnt_opts); return result; @@ -409,9 +439,8 @@ static int try_mount(char *spec, char *mount_point, int flags, if (!fake) print_one(spec, mount_point, fs_type, mount_opts); - if (!nomtab) - ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts, - 0, 0 /* these are always zero for NFS */ ); + ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts, + 0, 0 /* these are always zero for NFS */ ); return ret; } @@ -539,6 +568,12 @@ int main(int argc, char *argv[]) mnt_err = EX_USAGE; goto out; } + + if (geteuid() != 0) { + nfs_error(_("%s: not installed setuid - " + "\"user\" NFS mounts not supported."), progname); + exit(EX_FAIL); + } } if (chk_mountpoint(mount_point)) { diff --git a/utils/mount/mount_constants.h b/utils/mount/mount_constants.h index 4f3c729..cbfb099 100644 --- a/utils/mount/mount_constants.h +++ b/utils/mount/mount_constants.h @@ -1,5 +1,5 @@ -#ifndef _NFS_MOUNT_CONSTANTS_H -#define _NFS_MOUNT_CONSTANTS_H +#ifndef _NFS_UTILS_MOUNT_CONSTANTS_H +#define _NFS_UTILS_MOUNT_CONSTANTS_H #ifndef MS_DIRSYNC #define MS_DIRSYNC 128 /* Directory modifications are synchronous */ @@ -64,4 +64,4 @@ if we have a stack or plain mount - mount atop of it, forming a stack. */ #define MS_MGC_MSK 0xffff0000 /* magic flag number mask */ #endif -#endif /* _NFS_MOUNT_CONSTANTS_H */ +#endif /* _NFS_UTILS_MOUNT_CONSTANTS_H */ diff --git a/utils/mount/network.c b/utils/mount/network.c index ab7f6d0..75354a7 100644 --- a/utils/mount/network.c +++ b/utils/mount/network.c @@ -33,10 +33,13 @@ #include #include #include + +#include +#include +#include #include #include #include -#include #include "xcommon.h" #include "mount.h" @@ -45,17 +48,6 @@ #include "mount_constants.h" #include "network.h" -#ifdef HAVE_RPCSVC_NFS_PROT_H -#include -#else -#include -#define nfsstat nfs_stat -#endif - -#ifndef NFS_PORT -#define NFS_PORT 2049 -#endif - #define PMAP_TIMEOUT (10) #define CONNECT_TIMEOUT (20) #define MOUNT_TIMEOUT (30) @@ -143,6 +135,60 @@ static const unsigned long probe_mnt3_first[] = { 0, }; +/** + * nfs_name_to_address - resolve hostname to an IPv4 or IPv6 socket address + * @hostname: pointer to C string containing DNS hostname to resolve + * @sap: pointer to buffer to fill with socket address + * @len: IN: size of buffer to fill; OUT: size of socket address + * + * Returns 1 and places a socket address at @sap if successful; + * otherwise zero. + */ +int nfs_name_to_address(const char *hostname, + const sa_family_t af_hint, + struct sockaddr *sap, socklen_t *salen) +{ + struct addrinfo *gai_results; + struct addrinfo gai_hint = { + .ai_family = af_hint, + .ai_flags = AI_ADDRCONFIG, + }; + socklen_t len = *salen; + int error, ret = 0; + + if (af_hint == AF_INET6) + gai_hint.ai_flags |= AI_V4MAPPED|AI_ALL; + + *salen = 0; + + error = getaddrinfo(hostname, NULL, &gai_hint, &gai_results); + if (error) { + nfs_error(_("%s: DNS resolution failed for %s: %s"), + progname, hostname, (error == EAI_SYSTEM ? + strerror(errno) : gai_strerror(error))); + return ret; + } + + switch (gai_results->ai_addr->sa_family) { + case AF_INET: + case AF_INET6: + if (len >= gai_results->ai_addrlen) { + *salen = gai_results->ai_addrlen; + memcpy(sap, gai_results->ai_addr, *salen); + ret = 1; + } + break; + default: + /* things are really broken if we get here, so warn */ + nfs_error(_("%s: unrecognized DNS resolution results for %s"), + progname, hostname); + break; + } + + freeaddrinfo(gai_results); + return ret; +} + /** * nfs_gethostbyname - resolve a hostname to an IPv4 address * @hostname: pointer to a C string containing a DNS hostname @@ -150,26 +196,104 @@ static const unsigned long probe_mnt3_first[] = { * * Returns 1 if successful, otherwise zero. */ -int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr) +int nfs_gethostbyname(const char *hostname, struct sockaddr_in *sin) { - struct hostent *hp; + socklen_t len = sizeof(*sin); - saddr->sin_family = AF_INET; - if (!inet_aton(hostname, &saddr->sin_addr)) { - if ((hp = gethostbyname(hostname)) == NULL) { - nfs_error(_("%s: can't get address for %s\n"), - progname, hostname); - return 0; - } else { - if (hp->h_length > sizeof(*saddr)) { - nfs_error(_("%s: got bad hp->h_length\n"), - progname); - hp->h_length = sizeof(*saddr); + return nfs_name_to_address(hostname, AF_INET, + (struct sockaddr *)sin, &len); +} + +/** + * nfs_string_to_sockaddr - convert string address to sockaddr + * @address: pointer to presentation format address to convert + * @addrlen: length of presentation address + * @sap: pointer to socket address buffer to fill in + * @salen: IN: length of address buffer + * OUT: length of converted socket address + * + * Convert a presentation format address string to a socket address. + * Similar to nfs_name_to_address(), but the DNS query is squelched, + * and won't make any noise if the getaddrinfo() call fails. + * + * Returns 1 and fills in @sap and @salen if successful; otherwise zero. + * + * See RFC 4038 section 5.1 or RFC 3513 section 2.2 for more details + * on presenting IPv6 addresses as text strings. + */ +int nfs_string_to_sockaddr(const char *address, const size_t addrlen, + struct sockaddr *sap, socklen_t *salen) +{ + struct addrinfo *gai_results; + struct addrinfo gai_hint = { + .ai_flags = AI_NUMERICHOST, + }; + socklen_t len = *salen; + int ret = 0; + + *salen = 0; + + if (getaddrinfo(address, NULL, &gai_hint, &gai_results) == 0) { + switch (gai_results->ai_addr->sa_family) { + case AF_INET: + case AF_INET6: + if (len >= gai_results->ai_addrlen) { + *salen = gai_results->ai_addrlen; + memcpy(sap, gai_results->ai_addr, *salen); + ret = 1; } - memcpy(&saddr->sin_addr, hp->h_addr, hp->h_length); + break; } + freeaddrinfo(gai_results); } - return 1; + + return ret; +} + +/** + * nfs_present_sockaddr - convert sockaddr to string + * @sap: pointer to socket address to convert + * @salen: length of socket address + * @buf: pointer to buffer to fill in + * @buflen: length of buffer + * + * Convert the passed-in sockaddr-style address to presentation format. + * The presentation format address is placed in @buf and is + * '\0'-terminated. + * + * Returns 1 if successful; otherwise zero. + * + * See RFC 4038 section 5.1 or RFC 3513 section 2.2 for more details + * on presenting IPv6 addresses as text strings. + */ +int nfs_present_sockaddr(const struct sockaddr *sap, const socklen_t salen, + char *buf, const size_t buflen) +{ +#ifdef HAVE_GETNAMEINFO + int result; + + result = getnameinfo(sap, salen, buf, buflen, + NULL, 0, NI_NUMERICHOST); + if (!result) + return 1; + + nfs_error(_("%s: invalid server address: %s"), progname, + gai_strerror(result)); + return 0; +#else /* HAVE_GETNAMEINFO */ + char *addr; + + if (sap->sa_family == AF_INET) { + addr = inet_ntoa(((struct sockaddr_in *)sap)->sin_addr); + if (addr && strlen(addr) < buflen) { + strcpy(buf, addr); + return 1; + } + } + + nfs_error(_("%s: invalid server address"), progname); + return 0; +#endif /* HAVE_GETNAMEINFO */ } /* @@ -408,11 +532,10 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions, } if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL)) goto out_ok; - if (rpc_createerr.cf_stat == RPC_TIMEDOUT) - goto out_bad; } } if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED && + rpc_createerr.cf_stat != RPC_TIMEDOUT && rpc_createerr.cf_stat != RPC_PROGVERSMISMATCH) goto out_bad; @@ -421,6 +544,9 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions, continue; p_prot = protos; } + if (rpc_createerr.cf_stat == RPC_TIMEDOUT) + goto out_bad; + if (vers || !*++p_vers) break; } @@ -751,35 +877,120 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog, return 0; } -/** - * get_client_address - acquire our local network address - * @saddr: server's address - * @caddr: filled in with our network address - * - * Discover a network address that the server will use to call us back. - * On multi-homed clients, this address depends on which NIC we use to - * route requests to the server. +/* + * Try a getsockname() on a connected datagram socket. * - * Use a connected datagram socket so as not to leave a socket in TIME_WAIT. + * Returns 1 and fills in @buf if successful; otherwise, zero. * - * Returns one if successful, otherwise zero. + * A connected datagram socket prevents leaving a socket in TIME_WAIT. + * This conserves the ephemeral port number space, helping reduce failed + * socket binds during mount storms. */ -int get_client_address(struct sockaddr_in *saddr, struct sockaddr_in *caddr) +static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen, + struct sockaddr *buf, socklen_t *buflen) { - socklen_t len = sizeof(*caddr); - int socket, err; + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_ANY), + }; + struct sockaddr_in6 sin6 = { + .sin6_family = AF_INET6, + .sin6_addr = IN6ADDR_ANY_INIT, + }; + int sock; - socket = get_socket(saddr, IPPROTO_UDP, CONNECT_TIMEOUT, FALSE, TRUE); - if (socket == RPC_ANYSOCK) + sock = socket(sap->sa_family, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) return 0; - err = getsockname(socket, caddr, &len); - close(socket); + switch (sap->sa_family) { + case AF_INET: + if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + close(sock); + return 0; + } + break; + case AF_INET6: + if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) { + close(sock); + return 0; + } + break; + default: + errno = EAFNOSUPPORT; + return 0; + } - if (err && verbose) { - nfs_error(_("%s: getsockname failed: %s"), - progname, strerror(errno)); + if (connect(sock, sap, salen) < 0) { + close(sock); return 0; } + + return !getsockname(sock, buf, buflen); +} + +/* + * Try to generate an address that prevents the server from calling us. + * + * Returns 1 and fills in @buf if successful; otherwise, zero. + */ +static int nfs_ca_gai(const struct sockaddr *sap, const socklen_t salen, + struct sockaddr *buf, socklen_t *buflen) +{ + struct addrinfo *gai_results; + struct addrinfo gai_hint = { + .ai_family = sap->sa_family, + .ai_flags = AI_PASSIVE, /* ANYADDR */ + }; + + if (getaddrinfo(NULL, "", &gai_hint, &gai_results)) + return 0; + + *buflen = gai_results->ai_addrlen; + memcpy(buf, gai_results->ai_addr, *buflen); + + freeaddrinfo(gai_results); + + return 1; +} + +/** + * nfs_callback_address - acquire our local network address + * @sap: pointer to address of remote + * @sap_len: length of address + * @buf: pointer to buffer to be filled in with local network address + * @buflen: IN: length of buffer to fill in; OUT: length of filled-in address + * + * Discover a network address that an NFSv4 server can use to call us back. + * On multi-homed clients, this address depends on which NIC we use to + * route requests to the server. + * + * Returns 1 and fills in @buf if an unambiguous local address is + * available; returns 1 and fills in an appropriate ANYADDR address + * if a local address isn't available; otherwise, returns zero. + */ +int nfs_callback_address(const struct sockaddr *sap, const socklen_t salen, + struct sockaddr *buf, socklen_t *buflen) +{ + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf; + + if (nfs_ca_sockname(sap, salen, buf, buflen) == 0) + if (nfs_ca_gai(sap, salen, buf, buflen) == 0) + goto out_failed; + + /* + * The server can't use an interface ID that was generated + * here on the client, so always clear sin6_scope_id. + */ + if (sin6->sin6_family == AF_INET6) + sin6->sin6_scope_id = 0; + return 1; + +out_failed: + *buflen = 0; + if (verbose) + nfs_error(_("%s: failed to construct callback address")); + return 0; + } diff --git a/utils/mount/network.h b/utils/mount/network.h index 99ecc1e..a4dba1b 100644 --- a/utils/mount/network.h +++ b/utils/mount/network.h @@ -21,17 +21,10 @@ * */ -#include -#include - -#include "mount.h" +#ifndef _NFS_UTILS_MOUNT_NETWORK_H +#define _NFS_UTILS_MOUNT_NETWORK_H -#ifdef HAVE_RPCSVC_NFS_PROT_H -#include -#else -#include -#define nfsstat nfs_stat -#endif +#include #define MNT_SENDBUFSIZE (2048U) #define MNT_RECVBUFSIZE (1024U) @@ -48,7 +41,14 @@ static const struct timeval RETRY_TIMEOUT = { 3, 0 }; int probe_bothports(clnt_addr_t *, clnt_addr_t *); int nfs_gethostbyname(const char *, struct sockaddr_in *); -int get_client_address(struct sockaddr_in *, struct sockaddr_in *); +int nfs_name_to_address(const char *, const sa_family_t, + struct sockaddr *, socklen_t *); +int nfs_string_to_sockaddr(const char *, const size_t, + struct sockaddr *, socklen_t *); +int nfs_present_sockaddr(const struct sockaddr *, + const socklen_t, char *, const size_t); +int nfs_callback_address(const struct sockaddr *, const socklen_t, + struct sockaddr *, socklen_t *); int nfs_call_umount(clnt_addr_t *, dirpath *); int clnt_ping(struct sockaddr_in *, const unsigned long, const unsigned long, const unsigned int, @@ -60,3 +60,5 @@ unsigned long nfsvers_to_mnt(const unsigned long); CLIENT *mnt_openclnt(clnt_addr_t *, int *); void mnt_closeclnt(CLIENT *, int); + +#endif /* _NFS_UTILS_MOUNT_NETWORK_H */ diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man index 2c0b687..0fc5079 100644 --- a/utils/mount/nfs.man +++ b/utils/mount/nfs.man @@ -489,6 +489,25 @@ or the server's mountd service is not available on the advertised port. This option can be used when mounting an NFS server through a firewall that blocks the rpcbind protocol. .TP 1.5i +.BI mountproto= netid +The transport protocol used by the NFS client +to transmit requests to the NFS server's mountd service when performing +this mount request, and when later unmounting this mount point. +.I netid +can be either +.B udp +or +.BR tcp . +.IP +This option can be used when mounting an NFS server +through a firewall that blocks a particular transport protocol. +When used in combination with the +.B proto +option, different transports for mountd requests and NFS requests +can be specified. +If the server's mountd service is not available via the specified +transport, the mount request fails. +.TP 1.5i .BI mounthost= name The hostname of the host running mountd. If this option is not specified, the diff --git a/utils/mount/nfs4mount.c b/utils/mount/nfs4mount.c index 311e5a0..a2f318f 100644 --- a/utils/mount/nfs4mount.c +++ b/utils/mount/nfs4mount.c @@ -34,6 +34,7 @@ #include #include #include + #ifdef HAVE_RPCSVC_NFS_PROT_H #include #else @@ -45,6 +46,7 @@ #include "nls.h" #include "xcommon.h" +#include "mount.h" #include "mount_constants.h" #include "nfs4_mount.h" #include "nfs_mount.h" @@ -188,10 +190,9 @@ int nfs4mount(const char *spec, const char *node, int flags, int bg, soft, intr; int nocto, noac, unshared; int retry; - int retval; + int retval = EX_FAIL; time_t timeout, t; - retval = EX_FAIL; if (strlen(spec) >= sizeof(hostdir)) { nfs_error(_("%s: excessively long host:dir argument\n"), progname); @@ -238,7 +239,7 @@ int nfs4mount(const char *spec, const char *node, int flags, nocto = 0; noac = 0; unshared = 0; - retry = 10000; /* 10000 minutes ~ 1 week */ + retry = -1; /* * NFSv4 specifies that the default port should be 2049 @@ -332,6 +333,14 @@ int nfs4mount(const char *spec, const char *node, int flags, } } + /* if retry is still -1, then it wasn't set via an option */ + if (retry == -1) { + if (bg) + retry = 10000; /* 10000 mins == ~1 week */ + else + retry = 2; /* 2 min default on fg mounts */ + } + data.flags = (soft ? NFS4_MOUNT_SOFT : 0) | (intr ? NFS4_MOUNT_INTR : 0) | (nocto ? NFS4_MOUNT_NOCTO : 0) @@ -435,6 +444,13 @@ int nfs4mount(const char *spec, const char *node, int flags, rpc_mount_errors(hostname, 0, bg); goto fail; } + + if (bg && !running_bg) { + if (retry > 0) + retval = EX_BG; + goto fail; + } + t = time(NULL); if (t >= timeout) { rpc_mount_errors(hostname, 0, bg); diff --git a/utils/mount/nfs_mount.h b/utils/mount/nfs_mount.h index 7df8fb2..2becfb1 100644 --- a/utils/mount/nfs_mount.h +++ b/utils/mount/nfs_mount.h @@ -8,8 +8,8 @@ * so it is easiest to ignore the kernel altogether (at compile time). */ -#ifndef _NFS_MOUNT_H -#define _NFS_MOUNT_H +#ifndef _NFS_UTILS_MOUNT_NFS_MOUNT_H +#define _NFS_UTILS_MOUNT_NFS_MOUNT_H #include #include @@ -83,4 +83,4 @@ struct nfs_mount_data { int nfsmount(const char *, const char *, int , char **, int, int); int nfsumount(int, char **); -#endif /* _NFS_MOUNT_H */ +#endif /* _NFS_UTILS_MOUNT_NFS_MOUNT_H */ diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c index d1d43c6..6355681 100644 --- a/utils/mount/nfsmount.c +++ b/utils/mount/nfsmount.c @@ -67,6 +67,14 @@ #include "nls.h" #include "error.h" #include "network.h" +#include "version.h" + +#ifdef HAVE_RPCSVC_NFS_PROT_H +#include +#else +#include +#define nfsstat nfs_stat +#endif #ifndef NFS_PORT #define NFS_PORT 2049 @@ -95,8 +103,6 @@ extern char *progname; extern int verbose; extern int sloppy; -extern int linux_version_code(void); - static inline enum clnt_stat nfs3_mount(CLIENT *clnt, mnt3arg_t *mnt3arg, mnt3res_t *mnt3res) { @@ -479,7 +485,7 @@ static int nfsmnt_check_compat(const struct pmap *nfs_pmap, } if (mnt_pmap->pm_vers > max_mnt_vers) { - nfs_error(_("%s: NFS mount version %ld s not supported"), + nfs_error(_("%s: NFS mount version %ld is not supported"), progname, mnt_pmap->pm_vers); goto out_bad; } @@ -494,7 +500,6 @@ int nfsmount(const char *spec, const char *node, int flags, char **extra_opts, int fake, int running_bg) { - static char *prev_bg_host; char hostdir[1024]; char *hostname, *dirname, *old_opts, *mounthost = NULL; char new_opts[1024], cbuf[1024]; @@ -571,7 +576,7 @@ nfsmount(const char *spec, const char *node, int flags, #endif bg = 0; - retry = 10000; /* 10000 minutes ~ 1 week */ + retry = -1; memset(mnt_pmap, 0, sizeof(*mnt_pmap)); mnt_pmap->pm_prog = MOUNTPROG; @@ -585,9 +590,13 @@ nfsmount(const char *spec, const char *node, int flags, goto fail; if (!nfsmnt_check_compat(nfs_pmap, mnt_pmap)) goto fail; - - if (retry == 10000 && !bg) - retry = 2; /* reset for fg mounts */ + + if (retry == -1) { + if (bg) + retry = 10000; /* 10000 mins == ~1 week*/ + else + retry = 2; /* 2 min default on fg mounts */ + } #ifdef NFS_MOUNT_DEBUG printf(_("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n"), @@ -624,18 +633,6 @@ nfsmount(const char *spec, const char *node, int flags, if (flags & MS_REMOUNT) goto out_ok; - /* - * If the previous mount operation on the same host was - * backgrounded, and the "bg" for this mount is also set, - * give up immediately, to avoid the initial timeout. - */ - if (bg && !running_bg && - prev_bg_host && strcmp(hostname, prev_bg_host) == 0) { - if (retry > 0) - retval = EX_BG; - return retval; - } - /* create mount deamon client */ /* @@ -704,7 +701,6 @@ nfsmount(const char *spec, const char *node, int flags, continue; } if (!running_bg) { - prev_bg_host = xstrdup(hostname); if (retry > 0) retval = EX_BG; goto fail; @@ -738,7 +734,7 @@ nfsmount(const char *spec, const char *node, int flags, #if NFS_MOUNT_VERSION >= 4 mountres3_ok *mountres; fhandle3 *fhandle; - int i, *flavor, yum = 0; + int i, n_flavors, *flavor, yum = 0; if (mntres.nfsv3.fhs_status != 0) { nfs_error(_("%s: %s:%s failed, reason given by server: %s"), progname, hostname, dirname, @@ -747,13 +743,16 @@ nfsmount(const char *spec, const char *node, int flags, } #if NFS_MOUNT_VERSION >= 5 mountres = &mntres.nfsv3.mountres3_u.mountinfo; - i = mountres->auth_flavors.auth_flavors_len; - if (i <= 0) + n_flavors = mountres->auth_flavors.auth_flavors_len; + if (n_flavors <= 0) goto noauth_flavors; flavor = mountres->auth_flavors.auth_flavors_val; - while (--i >= 0) { - /* If no flavour requested, use first simple + for (i = 0; i < n_flavors; ++i) { + /* + * Per RFC2623, section 2.7, we should prefer the + * flavour listed first. + * If no flavour requested, use the first simple * flavour that is offered. */ if (! (data.flags & NFS_MOUNT_SECFLAVOUR) && @@ -815,7 +814,7 @@ noauth_flavors: * to avoid problems with multihomed hosts. * --Swen */ - if (linux_version_code() <= 0x01030a && fsock != -1 + if (linux_version_code() <= MAKE_VERSION(1, 3, 10) && fsock != -1 && connect(fsock, (struct sockaddr *) nfs_saddr, sizeof (*nfs_saddr)) < 0) { perror(_("nfs connect")); diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c index 285273b..b2327e0 100644 --- a/utils/mount/nfsumount.c +++ b/utils/mount/nfsumount.c @@ -34,6 +34,7 @@ #include "mount.h" #include "error.h" #include "network.h" +#include "parse_dev.h" #if !defined(MNT_FORCE) /* dare not try to include -- lots of errors */ @@ -150,21 +151,11 @@ static int do_nfs_umount23(const char *spec, char *opts) struct mntent mnt = { .mnt_opts = opts }; struct pmap *pmap = &mnt_server.pmap; char *p; + int result = EX_USAGE; + + if (!nfs_parse_devname(spec, &hostname, &dirname)) + return result; - if (spec == NULL) { - nfs_error(_("%s: No NFS export name was provided"), - progname); - return EX_USAGE; - } - - p = strchr(spec, ':'); - if (p == NULL) { - nfs_error(_("%s: '%s' is not a legal NFS export name"), - progname, spec); - return EX_USAGE; - } - hostname = xstrndup(spec, p - spec); - dirname = xstrdup(p + 1); #ifdef NFS_MOUNT_DEBUG printf(_("host: %s, directory: %s\n"), hostname, dirname); #endif @@ -203,24 +194,36 @@ static int do_nfs_umount23(const char *spec, char *opts) pmap->pm_vers = nfsvers_to_mnt(atoi(p+5)); if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10))) pmap->pm_vers = atoi(p+10); - if (opts && (hasmntopt(&mnt, "udp") || hasmntopt(&mnt, "proto=udp"))) + if (opts && (hasmntopt(&mnt, "udp") + || hasmntopt(&mnt, "proto=udp") + || hasmntopt(&mnt, "mountproto=udp") + )) pmap->pm_prot = IPPROTO_UDP; - if (opts && (hasmntopt(&mnt, "tcp") || hasmntopt(&mnt, "proto=tcp"))) + if (opts && (hasmntopt(&mnt, "tcp") + || hasmntopt(&mnt, "proto=tcp") + || hasmntopt(&mnt, "mountproto=tcp") + )) pmap->pm_prot = IPPROTO_TCP; if (!nfs_gethostbyname(hostname, &mnt_server.saddr)) { - nfs_error(_("%s: '%s' does not contain a recognized hostname"), - progname, spec); - return EX_USAGE; + nfs_error(_("%s: DNS resolution of '%s' failed"), + progname, hostname); + goto out; } if (!nfs_call_umount(&mnt_server, &dirname)) { nfs_error(_("%s: Server failed to unmount '%s'"), progname, spec); - return EX_USAGE; + result = EX_FAIL; + goto out; } - return EX_SUCCESS; + result = EX_SUCCESS; + +out: + free(hostname); + free(dirname); + return result; } static struct option umount_longopts[] = @@ -347,8 +350,13 @@ int nfsumount(int argc, char *argv[]) ret = 0; if (mc) { if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0) - ret = do_nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts); - ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir) ?: ret; + /* We ignore the error from do_nfs_umount23. + * If the actual umount succeeds (in del_mtab), + * we don't want to signal an error, as that + * could cause /sbin/mount to retry! + */ + do_nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts); + ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir); } else if (*spec != '/') { if (!lazy) ret = do_nfs_umount23(spec, "tcp,v3"); diff --git a/utils/mount/parse_dev.c b/utils/mount/parse_dev.c new file mode 100644 index 0000000..c0a8e18 --- /dev/null +++ b/utils/mount/parse_dev.c @@ -0,0 +1,230 @@ +/* + * parse_dev.c -- parse device name into hostname and export path + * + * Copyright (C) 2008 Oracle. All rights reserved. + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "xcommon.h" +#include "nls.h" +#include "parse_dev.h" + +#ifndef NFS_MAXHOSTNAME +#define NFS_MAXHOSTNAME (255) +#endif + +#ifndef NFS_MAXPATHNAME +#define NFS_MAXPATHNAME (1024) +#endif + +extern char *progname; +extern int verbose; + +static int nfs_pdn_no_devname_err(void) +{ + nfs_error(_("%s: no device name was provided"), progname); + return 0; +} + +static int nfs_pdn_hostname_too_long_err(void) +{ + nfs_error(_("%s: server hostname is too long"), progname); + return 0; +} + +static int nfs_pdn_pathname_too_long_err(void) +{ + nfs_error(_("%s: export pathname is too long"), progname); + return 0; +} + +static int nfs_pdn_bad_format_err(void) +{ + nfs_error(_("%s: remote share not in 'host:dir' format"), progname); + return 0; +} + +static int nfs_pdn_nomem_err(void) +{ + nfs_error(_("%s: no memory available to parse devname"), progname); + return 0; +} + +static int nfs_pdn_missing_brace_err(void) +{ + nfs_error(_("%s: closing bracket missing from server address"), + progname); + return 0; +} + +/* + * Standard hostname:path format + */ +static int nfs_parse_simple_hostname(const char *dev, + char **hostname, char **pathname) +{ + size_t host_len, path_len; + char *colon, *comma; + + /* Must have a colon */ + colon = strchr(dev, ':'); + if (colon == NULL) + return nfs_pdn_bad_format_err(); + *colon = '\0'; + host_len = colon - dev; + + if (host_len > NFS_MAXHOSTNAME) + return nfs_pdn_hostname_too_long_err(); + + /* If there's a comma before the colon, take only the + * first name in list */ + comma = strchr(dev, ','); + if (comma != NULL) { + *comma = '\0'; + host_len = comma - dev; + nfs_error(_("%s: warning: multiple hostnames not supported"), + progname); + } else + + colon++; + path_len = strlen(colon); + if (path_len > NFS_MAXPATHNAME) + return nfs_pdn_pathname_too_long_err(); + + if (hostname) { + *hostname = strndup(dev, host_len); + if (*hostname == NULL) + return nfs_pdn_nomem_err(); + } + if (pathname) { + *pathname = strndup(colon, path_len); + if (*pathname == NULL) { + free(*hostname); + return nfs_pdn_nomem_err(); + } + } + return 1; +} + +/* + * To handle raw IPv6 addresses (which contain colons), the + * server's address is enclosed in square brackets. Return + * what's between the brackets. + * + * There could be anything in between the brackets, but we'll + * let DNS resolution sort it out later. + */ +static int nfs_parse_square_bracket(const char *dev, + char **hostname, char **pathname) +{ + size_t host_len, path_len; + char *cbrace; + + dev++; + + /* Must have a closing square bracket */ + cbrace = strchr(dev, ']'); + if (cbrace == NULL) + return nfs_pdn_missing_brace_err(); + *cbrace = '\0'; + host_len = cbrace - dev; + + /* Must have a colon just after the closing bracket */ + cbrace++; + if (*cbrace != ':') + return nfs_pdn_bad_format_err(); + + if (host_len > NFS_MAXHOSTNAME) + return nfs_pdn_hostname_too_long_err(); + + cbrace++; + path_len = strlen(cbrace); + if (path_len > NFS_MAXPATHNAME) + return nfs_pdn_pathname_too_long_err(); + + if (hostname) { + *hostname = strndup(dev, host_len); + if (*hostname == NULL) + return nfs_pdn_nomem_err(); + } + if (pathname) { + *pathname = strndup(cbrace, path_len); + if (*pathname == NULL) { + free(*hostname); + return nfs_pdn_nomem_err(); + } + } + return 1; +} + +/* + * RFC 2224 says an NFS client must grok "public file handles" to + * support NFS URLs. Linux doesn't do that yet. Print a somewhat + * helpful error message in this case instead of pressing forward + * with the mount request and failing with a cryptic error message + * later. + */ +static int nfs_parse_nfs_url(const char *dev, + char **hostname, char **pathname) +{ + nfs_error(_("%s: NFS URLs are not supported"), progname); + return 0; +} + +/** + * nfs_parse_devname - Determine the server's hostname by looking at "devname". + * @devname: pointer to mounted device name (first argument of mount command) + * @hostname: OUT: pointer to server's hostname + * @pathname: OUT: pointer to export path on server + * + * Returns 1 if succesful, or zero if some error occurred. On success, + * @hostname and @pathname point to dynamically allocated buffers containing + * the hostname of the server and the export pathname (both '\0'-terminated). + * + * @hostname or @pathname may be NULL if caller doesn't want a copy of those + * parts of @devname. + * + * Note that this will not work if @devname is a wide-character string. + */ +int nfs_parse_devname(const char *devname, + char **hostname, char **pathname) +{ + char *dev; + int result; + + if (devname == NULL) + return nfs_pdn_no_devname_err(); + + /* Parser is destructive, so operate on a copy of the device name. */ + dev = strdup(devname); + if (dev == NULL) + return nfs_pdn_nomem_err(); + if (*dev == '[') + result = nfs_parse_square_bracket(dev, hostname, pathname); + else if (strncmp(dev, "nfs://", 6) == 0) + result = nfs_parse_nfs_url(dev, hostname, pathname); + else + result = nfs_parse_simple_hostname(dev, hostname, pathname); + + free(dev); + return result; +} diff --git a/utils/mount/parse_dev.h b/utils/mount/parse_dev.h new file mode 100644 index 0000000..a1288c2 --- /dev/null +++ b/utils/mount/parse_dev.h @@ -0,0 +1,28 @@ +/* + * parse_dev.c -- parse device name into hostname and export path + * + * Copyright (C) 2008 Oracle. All rights reserved. + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef __NFS_UTILS_PARSE_DEV_HEADER +#define __NFS_UTILS_PARSE_DEV_HEADER + +extern int nfs_parse_devname(const char *, char **, char **); + +#endif /* __NFS_UTILS_PARSE_DEV */ diff --git a/utils/mount/parse_opt.h b/utils/mount/parse_opt.h index e7924dd..fb003c3 100644 --- a/utils/mount/parse_opt.h +++ b/utils/mount/parse_opt.h @@ -21,6 +21,9 @@ * */ +#ifndef _NFS_UTILS_PARSE_OPT_H +#define _NFS_UTILS_PARSE_OPT_H + typedef enum { PO_FAILED = 0, PO_SUCCEEDED = 1, @@ -50,3 +53,5 @@ char * po_get(struct mount_options *, char *); po_rightmost_t po_rightmost(struct mount_options *, char *, char *); po_found_t po_remove_all(struct mount_options *, char *); void po_destroy(struct mount_options *); + +#endif /* _NFS_UTILS_PARSE_OPT_H */ diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index cadb1f4..09fca86 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -25,36 +25,33 @@ #include #endif -#include #include -#include -#include -#include #include #include #include + #include #include +#include +#include #include "xcommon.h" #include "mount.h" #include "nls.h" -#include "nfs_mount.h" #include "mount_constants.h" #include "stropts.h" #include "error.h" #include "network.h" #include "parse_opt.h" +#include "version.h" +#include "parse_dev.h" -#ifdef HAVE_RPCSVC_NFS_PROT_H -#include -#else -#include -#define nfsstat nfs_stat +#ifndef NFS_PROGRAM +#define NFS_PROGRAM (100003) #endif #ifndef NFS_PORT -#define NFS_PORT 2049 +#define NFS_PORT (2049) #endif #ifndef NFS_MAXHOSTNAME @@ -65,79 +62,90 @@ #define NFS_MAXPATHNAME (1024) #endif +#ifndef NFS_DEF_FG_TIMEOUT_MINUTES +#define NFS_DEF_FG_TIMEOUT_MINUTES (2u) +#endif + +#ifndef NFS_DEF_BG_TIMEOUT_MINUTES +#define NFS_DEF_BG_TIMEOUT_MINUTES (10000u) +#endif + extern int nfs_mount_data_version; extern char *progname; extern int verbose; +extern int sloppy; -static int parse_devname(const char *spec, char **hostname) -{ - int ret = 0; - char *dev, *pathname, *s; +struct nfsmount_info { + const char *spec, /* server:/path */ + *node, /* mounted-on dir */ + *type; /* "nfs" or "nfs4" */ + char *hostname; /* server's hostname */ - dev = xstrdup(spec); + struct mount_options *options; /* parsed mount options */ + char **extra_opts; /* string for /etc/mtab */ - if (!(pathname = strchr(dev, ':'))) { - nfs_error(_("%s: remote share not in 'host:dir' format"), - progname); - goto out; - } - *pathname = '\0'; - pathname++; + int flags, /* MS_ flags */ + fake, /* actually do the mount? */ + child; /* forked bg child? */ - /* - * We don't need a copy of the pathname, but let's - * sanity check it anyway. - */ - if (strlen(pathname) > NFS_MAXPATHNAME) { - nfs_error(_("%s: export pathname is too long"), - progname); - goto out; - } + sa_family_t family; /* supported address family */ +}; - /* - * Ignore all but first hostname in replicated mounts - * until they can be fully supported. (mack@sgi.com) - */ - if ((s = strchr(dev, ','))) { - *s = '\0'; - nfs_error(_("%s: warning: multiple hostnames not supported"), - progname); - nfs_error(_("%s: ignoring hostnames that follow the first one"), - progname); - } - *hostname = xstrdup(dev); - if (strlen(*hostname) > NFS_MAXHOSTNAME) { - nfs_error(_("%s: server hostname is too long"), - progname); - free(*hostname); - goto out; +/* + * Obtain a retry timeout value based on the value of the "retry=" option. + * + * Returns a time_t timeout timestamp, in seconds. + */ +static time_t nfs_parse_retry_option(struct mount_options *options, + unsigned int timeout_minutes) +{ + char *retry_option, *endptr; + + retry_option = po_get(options, "retry"); + if (retry_option) { + long tmp; + + errno = 0; + tmp = strtol(retry_option, &endptr, 10); + if (errno == 0 && endptr != retry_option && tmp >= 0) + timeout_minutes = tmp; + else if (verbose) + nfs_error(_("%s: invalid retry timeout was specified; " + "using default timeout"), progname); } - ret = 1; - -out: - free(dev); - return ret; + return time(NULL) + (time_t)(timeout_minutes * 60); } -static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr) +/* + * Convert the passed-in sockaddr-style address to presentation + * format, then append an option of the form "keyword=address". + * + * Returns 1 if the option was appended successfully; otherwise zero. + */ +static int nfs_append_generic_address_option(const struct sockaddr *sap, + const socklen_t salen, + const char *keyword, + struct mount_options *options) { - struct hostent *hp; - addr->sin_family = AF_INET; + char address[NI_MAXHOST]; + char new_option[512]; + + if (!nfs_present_sockaddr(sap, salen, address, sizeof(address))) + goto out_err; + + if (snprintf(new_option, sizeof(new_option), "%s=%s", + keyword, address) >= sizeof(new_option)) + goto out_err; + + if (po_append(options, new_option) != PO_SUCCEEDED) + goto out_err; - if (inet_aton(hostname, &addr->sin_addr)) - return 1; - if ((hp = gethostbyname(hostname)) == NULL) { - nfs_error(_("%s: can't get address for %s\n"), - progname, hostname); - return 0; - } - if (hp->h_length > sizeof(struct in_addr)) { - nfs_error(_("%s: got bad hp->h_length"), progname); - hp->h_length = sizeof(struct in_addr); - } - memcpy(&addr->sin_addr, hp->h_addr, hp->h_length); return 1; + +out_err: + nfs_error(_("%s: failed to construct %s option"), progname, keyword); + return 0; } /* @@ -152,19 +160,12 @@ static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr) * Returns 1 if 'addr=' option appended successfully; * otherwise zero. */ -static int append_addr_option(struct sockaddr_in *saddr, - struct mount_options *options) +static int nfs_append_addr_option(const struct sockaddr *sap, + socklen_t salen, + struct mount_options *options) { - char new_option[24]; - po_remove_all(options, "addr"); - - snprintf(new_option, sizeof(new_option) - 1, - "addr=%s", inet_ntoa(saddr->sin_addr)); - - if (po_append(options, new_option) == PO_SUCCEEDED) - return 1; - return 0; + return nfs_append_generic_address_option(sap, salen, "addr", options); } /* @@ -174,71 +175,110 @@ static int append_addr_option(struct sockaddr_in *saddr, * Returns 1 if 'clientaddr=' option created successfully or if * 'clientaddr=' option is already present; otherwise zero. */ -static int append_clientaddr_option(struct sockaddr_in *saddr, - struct mount_options *options) +static int nfs_append_clientaddr_option(const struct sockaddr *sap, + socklen_t salen, + struct mount_options *options) { - struct sockaddr_in my_addr; - char new_option[32]; + struct sockaddr_storage dummy; + struct sockaddr *my_addr = (struct sockaddr *)&dummy; + socklen_t my_len = sizeof(dummy); - if (po_contains(options, "clientaddr") == PO_SUCCEEDED) + if (po_contains(options, "clientaddr") == PO_FOUND) return 1; - if (!get_client_address(saddr, &my_addr)) - return 0; - - snprintf(new_option, sizeof(new_option) - 1, - "clientaddr=%s", inet_ntoa(my_addr.sin_addr)); + nfs_callback_address(sap, salen, my_addr, &my_len); - if (po_append(options, new_option) == PO_SUCCEEDED) - return 1; - return 0; + return nfs_append_generic_address_option(my_addr, my_len, + "clientaddr", options); } /* * Resolve the 'mounthost=' hostname and append a new option using - * the resulting IPv4 address. + * the resulting address. */ -static int fix_mounthost_option(struct mount_options *options) +static int nfs_fix_mounthost_option(const sa_family_t family, + struct mount_options *options) { - struct sockaddr_in maddr; - char *mounthost, new_option[32]; + struct sockaddr_storage dummy; + struct sockaddr *sap = (struct sockaddr *)&dummy; + socklen_t salen = sizeof(dummy); + char *mounthost; mounthost = po_get(options, "mounthost"); if (!mounthost) return 1; - if (!fill_ipv4_sockaddr(mounthost, &maddr)) + if (!nfs_name_to_address(mounthost, family, sap, &salen)) { + nfs_error(_("%s: unable to determine mount server's address"), + progname); return 0; + } - snprintf(new_option, sizeof(new_option) - 1, - "mountaddr=%s", inet_ntoa(maddr.sin_addr)); + return nfs_append_generic_address_option(sap, salen, + "mountaddr", options); +} - if (po_append(options, new_option) == PO_SUCCEEDED) +/* + * Returns zero if the "lock" option is in effect, but statd + * can't be started. Otherwise, returns 1. + */ +static int nfs_verify_lock_option(struct mount_options *options) +{ + if (po_rightmost(options, "nolock", "lock") == PO_KEY1_RIGHTMOST) return 1; - return 0; + + if (!start_statd()) { + nfs_error(_("%s: rpc.statd is not running but is " + "required for remote locking."), progname); + nfs_error(_("%s: Either use '-o nolock' to keep " + "locks local, or start statd."), progname); + return 0; + } + + return 1; +} + +static int nfs_append_sloppy_option(struct mount_options *options) +{ + if (!sloppy || linux_version_code() < MAKE_VERSION(2, 6, 27)) + return 1; + + if (po_append(options, "sloppy") == PO_FAILED) + return 0; + return 1; } /* - * Set up mandatory mount options. + * Set up mandatory NFS mount options. * * Returns 1 if successful; otherwise zero. */ -static int set_mandatory_options(const char *type, - struct sockaddr_in *saddr, - struct mount_options *options) +static int nfs_validate_options(struct nfsmount_info *mi) { - if (!append_addr_option(saddr, options)) + struct sockaddr_storage dummy; + struct sockaddr *sap = (struct sockaddr *)&dummy; + socklen_t salen = sizeof(dummy); + + if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL)) return 0; - if (strncmp(type, "nfs4", 4) == 0) { - if (!append_clientaddr_option(saddr, options)) + if (!nfs_name_to_address(mi->hostname, mi->family, sap, &salen)) + return 0; + + if (strncmp(mi->type, "nfs4", 4) == 0) { + if (!nfs_append_clientaddr_option(sap, salen, mi->options)) return 0; } else { - if (!fix_mounthost_option(options)) + if (!nfs_fix_mounthost_option(mi->family, mi->options)) + return 0; + if (!mi->fake && !nfs_verify_lock_option(mi->options)) return 0; } - return 1; + if (!nfs_append_sloppy_option(mi->options)) + return 0; + + return nfs_append_addr_option(sap, salen, mi->options); } /* @@ -249,10 +289,9 @@ static int set_mandatory_options(const char *type, * passed-in error is permanent, thus the mount system call * should not be retried. */ -static int is_permanent_error(int error) +static int nfs_is_permanent_error(int error) { switch (error) { - case EACCES: case ESTALE: case ETIMEDOUT: case ECONNREFUSED: @@ -269,13 +308,13 @@ static int is_permanent_error(int error) * * To handle version and transport protocol fallback properly, we * need to parse some of the mount options in order to set up a - * portmap probe. Mount options that rewrite_mount_options() + * portmap probe. Mount options that nfs_rewrite_mount_options() * doesn't recognize are left alone. * * Returns a new group of mount options if successful; otherwise * NULL is returned if some failure occurred. */ -static struct mount_options *rewrite_mount_options(char *str) +static struct mount_options *nfs_rewrite_mount_options(char *str) { struct mount_options *options; char *option, new_option[64]; @@ -284,9 +323,12 @@ static struct mount_options *rewrite_mount_options(char *str) int p; options = po_split(str); - if (!options) + if (!options) { + errno = EFAULT; return NULL; + } + errno = EINVAL; option = po_get(options, "addr"); if (option) { nfs_server.saddr.sin_family = AF_INET; @@ -311,6 +353,17 @@ static struct mount_options *rewrite_mount_options(char *str) option = po_get(options, "mountvers"); if (option) mnt_server.pmap.pm_vers = atoi(option); + option = po_get(options, "mountproto"); + if (option) { + if (strcmp(option, "tcp") == 0) { + mnt_server.pmap.pm_prot = IPPROTO_TCP; + po_remove_all(options, "mountproto"); + } + if (strcmp(option, "udp") == 0) { + mnt_server.pmap.pm_prot = IPPROTO_UDP; + po_remove_all(options, "mountproto"); + } + } option = po_get(options, "port"); if (option) { @@ -353,7 +406,7 @@ static struct mount_options *rewrite_mount_options(char *str) po_remove_all(options, "udp"); if (!probe_bothports(&mnt_server, &nfs_server)) { - rpc_mount_errors("rpcbind", 0, 0); + errno = ESPIPE; goto err; } @@ -379,6 +432,21 @@ static struct mount_options *rewrite_mount_options(char *str) } + if (mnt_server.pmap.pm_prot == IPPROTO_TCP) + snprintf(new_option, sizeof(new_option) - 1, + "mountproto=tcp"); + else + snprintf(new_option, sizeof(new_option) - 1, + "mountproto=udp"); + if (po_append(options, new_option) == PO_FAILED) + goto err; + + snprintf(new_option, sizeof(new_option) - 1, + "mountport=%lu", mnt_server.pmap.pm_port); + if (po_append(options, new_option) == PO_FAILED) + goto err; + + errno = 0; return options; err: @@ -386,6 +454,27 @@ err: return NULL; } +/* + * Do the mount(2) system call. + * + * Returns 1 if successful, otherwise zero. + * "errno" is set to reflect the individual error. + */ +static int nfs_sys_mount(const struct nfsmount_info *mi, const char *type, + const char *options) +{ + int result; + + result = mount(mi->spec, mi->node, type, + mi->flags & ~(MS_USER|MS_USERS), options); + if (verbose && result) { + int save = errno; + nfs_error(_("%s: mount(2): %s"), progname, strerror(save)); + errno = save; + } + return !result; +} + /* * Retry an NFS mount that failed because the requested service isn't * available on the server. @@ -397,18 +486,15 @@ err: * 'extra_opts' are updated to reflect the mount options that worked. * If the retry fails, 'options' and 'extra_opts' are left unchanged. */ -static int retry_nfsmount(const char *spec, const char *node, - int flags, struct mount_options *options, - int fake, char **extra_opts) +static int nfs_retry_nfs23mount(struct nfsmount_info *mi) { struct mount_options *retry_options; char *retry_str = NULL; + char **extra_opts = mi->extra_opts; - retry_options = rewrite_mount_options(*extra_opts); - if (!retry_options) { - errno = EIO; + retry_options = nfs_rewrite_mount_options(*extra_opts); + if (!retry_options) return 0; - } if (po_join(retry_options, &retry_str) == PO_FAILED) { po_destroy(retry_options); @@ -420,17 +506,16 @@ static int retry_nfsmount(const char *spec, const char *node, printf(_("%s: text-based options (retry): '%s'\n"), progname, retry_str); - if (!mount(spec, node, "nfs", - flags & ~(MS_USER|MS_USERS), retry_str)) { - free(*extra_opts); - *extra_opts = retry_str; - po_replace(options, retry_options); - return 1; + if (!nfs_sys_mount(mi, "nfs", retry_str)) { + po_destroy(retry_options); + free(retry_str); + return 0; } - po_destroy(retry_options); - free(retry_str); - return 0; + free(*extra_opts); + *extra_opts = retry_str; + po_replace(mi->options, retry_options); + return 1; } /* @@ -446,11 +531,11 @@ static int retry_nfsmount(const char *spec, const char *node, * 'extra_opts' are updated to reflect the mount options that worked. * If the retry fails, 'options' and 'extra_opts' are left unchanged. */ -static int try_nfs23mount(const char *spec, const char *node, - int flags, struct mount_options *options, - int fake, char **extra_opts) +static int nfs_try_nfs23mount(struct nfsmount_info *mi) { - if (po_join(options, extra_opts) == PO_FAILED) { + char **extra_opts = mi->extra_opts; + + if (po_join(mi->options, extra_opts) == PO_FAILED) { errno = EIO; return 0; } @@ -459,11 +544,10 @@ static int try_nfs23mount(const char *spec, const char *node, printf(_("%s: text-based options: '%s'\n"), progname, *extra_opts); - if (fake) + if (mi->fake) return 1; - if (!mount(spec, node, "nfs", - flags & ~(MS_USER|MS_USERS), *extra_opts)) + if (nfs_sys_mount(mi, "nfs", *extra_opts)) return 1; /* @@ -473,7 +557,7 @@ static int try_nfs23mount(const char *spec, const char *node, if (errno != EOPNOTSUPP && errno != EPROTONOSUPPORT) return 0; - return retry_nfsmount(spec, node, flags, options, fake, extra_opts); + return nfs_retry_nfs23mount(mi); } /* @@ -482,11 +566,11 @@ static int try_nfs23mount(const char *spec, const char *node, * Returns 1 if successful. Otherwise, returns zero. * "errno" is set to reflect the individual error. */ -static int try_nfs4mount(const char *spec, const char *node, - int flags, struct mount_options *options, - int fake, char **extra_opts) +static int nfs_try_nfs4mount(struct nfsmount_info *mi) { - if (po_join(options, extra_opts) == PO_FAILED) { + char **extra_opts = mi->extra_opts; + + if (po_join(mi->options, extra_opts) == PO_FAILED) { errno = EIO; return 0; } @@ -495,31 +579,24 @@ static int try_nfs4mount(const char *spec, const char *node, printf(_("%s: text-based options: '%s'\n"), progname, *extra_opts); - if (fake) + if (mi->fake) return 1; - if (!mount(spec, node, "nfs4", - flags & ~(MS_USER|MS_USERS), *extra_opts)) - return 1; - return 0; + return nfs_sys_mount(mi, "nfs4", *extra_opts); } /* - * Try the mount(2) system call. + * Perform either an NFSv2/3 mount, or an NFSv4 mount system call. * * Returns 1 if successful. Otherwise, returns zero. * "errno" is set to reflect the individual error. */ -static int try_mount(const char *spec, const char *node, const char *type, - int flags, struct mount_options *options, int fake, - char **extra_opts) +static int nfs_try_mount(struct nfsmount_info *mi) { - if (strncmp(type, "nfs4", 4) == 0) - return try_nfs4mount(spec, node, flags, - options, fake, extra_opts); + if (strncmp(mi->type, "nfs4", 4) == 0) + return nfs_try_nfs4mount(mi); else - return try_nfs23mount(spec, node, flags, - options, fake, extra_opts); + return nfs_try_nfs23mount(mi); } /* @@ -529,30 +606,22 @@ static int try_mount(const char *spec, const char *node, const char *type, * * Returns a valid mount command exit code. */ -static int nfsmount_fg(const char *spec, const char *node, - const char *type, int flags, - struct mount_options *options, int fake, - char **extra_opts) +static int nfsmount_fg(struct nfsmount_info *mi) { unsigned int secs = 1; - time_t timeout = time(NULL); - char *retry; - - timeout += 60 * 2; /* default: 2 minutes */ - retry = po_get(options, "retry"); - if (retry) - timeout += 60 * atoi(retry); + time_t timeout; + timeout = nfs_parse_retry_option(mi->options, + NFS_DEF_FG_TIMEOUT_MINUTES); if (verbose) printf(_("%s: timeout set for %s"), progname, ctime(&timeout)); for (;;) { - if (try_mount(spec, node, type, flags, - options, fake, extra_opts)) + if (nfs_try_mount(mi)) return EX_SUCCESS; - if (is_permanent_error(errno)) + if (nfs_is_permanent_error(errno)) break; if (time(NULL) > timeout) { @@ -569,7 +638,7 @@ static int nfsmount_fg(const char *spec, const char *node, } }; - mount_error(spec, node, errno); + mount_error(mi->spec, mi->node, errno); return EX_FAIL; } @@ -580,21 +649,17 @@ static int nfsmount_fg(const char *spec, const char *node, * * EX_BG should cause the caller to fork and invoke nfsmount_child. */ -static int nfsmount_parent(const char *spec, const char *node, - const char *type, char *hostname, int flags, - struct mount_options *options, - int fake, char **extra_opts) +static int nfsmount_parent(struct nfsmount_info *mi) { - if (try_mount(spec, node, type, flags, options, - fake, extra_opts)) + if (nfs_try_mount(mi)) return EX_SUCCESS; - if (is_permanent_error(errno)) { - mount_error(spec, node, errno); + if (nfs_is_permanent_error(errno)) { + mount_error(mi->spec, mi->node, errno); return EX_FAIL; } - sys_mount_errors(hostname, errno, 1, 1); + sys_mount_errors(mi->hostname, errno, 1, 1); return EX_BG; } @@ -606,19 +671,13 @@ static int nfsmount_parent(const char *spec, const char *node, * error return, though, so we use sys_mount_errors to log the * failure. */ -static int nfsmount_child(const char *spec, const char *node, - const char *type, char *hostname, int flags, - struct mount_options *options, - int fake, char **extra_opts) +static int nfsmount_child(struct nfsmount_info *mi) { unsigned int secs = 1; - time_t timeout = time(NULL); - char *retry; + time_t timeout; - timeout += 60 * 10000; /* default: 10,000 minutes */ - retry = po_get(options, "retry"); - if (retry) - timeout += 60 * atoi(retry); + timeout = nfs_parse_retry_option(mi->options, + NFS_DEF_BG_TIMEOUT_MINUTES); for (;;) { if (sleep(secs)) @@ -627,20 +686,19 @@ static int nfsmount_child(const char *spec, const char *node, if (secs > 120) secs = 120; - if (try_mount(spec, node, type, flags, options, - fake, extra_opts)) + if (nfs_try_mount(mi)) return EX_SUCCESS; - if (is_permanent_error(errno)) + if (nfs_is_permanent_error(errno)) break; if (time(NULL) > timeout) break; - sys_mount_errors(hostname, errno, 1, 1); + sys_mount_errors(mi->hostname, errno, 1, 1); }; - sys_mount_errors(hostname, errno, 1, 0); + sys_mount_errors(mi->hostname, errno, 1, 0); return EX_FAIL; } @@ -649,17 +707,28 @@ static int nfsmount_child(const char *spec, const char *node, * * Returns a valid mount command exit code. */ -static int nfsmount_bg(const char *spec, const char *node, - const char *type, char *hostname, int flags, - struct mount_options *options, - int fake, int child, char **extra_opts) +static int nfsmount_bg(struct nfsmount_info *mi) { - if (!child) - return nfsmount_parent(spec, node, type, hostname, flags, - options, fake, extra_opts); + if (!mi->child) + return nfsmount_parent(mi); else - return nfsmount_child(spec, node, type, hostname, flags, - options, fake, extra_opts); + return nfsmount_child(mi); +} + +/* + * Process mount options and try a mount system call. + * + * Returns a valid mount command exit code. + */ +static int nfsmount_start(struct nfsmount_info *mi) +{ + if (!nfs_validate_options(mi)) + return EX_FAIL; + + if (po_rightmost(mi->options, "bg", "fg") == PO_KEY1_RIGHTMOST) + return nfsmount_bg(mi); + else + return nfsmount_fg(mi); } /** @@ -676,35 +745,29 @@ static int nfsmount_bg(const char *spec, const char *node, int nfsmount_string(const char *spec, const char *node, const char *type, int flags, char **extra_opts, int fake, int child) { - struct mount_options *options = NULL; - struct sockaddr_in saddr; - char *hostname; + struct nfsmount_info mi = { + .spec = spec, + .node = node, + .type = type, + .extra_opts = extra_opts, + .flags = flags, + .fake = fake, + .child = child, +#ifdef IPV6_SUPPORTED + .family = AF_UNSPEC, /* either IPv4 or v6 */ +#else + .family = AF_INET, /* only IPv4 */ +#endif + }; int retval = EX_FAIL; - if (!parse_devname(spec, &hostname)) - return retval; - if (!fill_ipv4_sockaddr(hostname, &saddr)) - goto fail; - - options = po_split(*extra_opts); - if (!options) { + mi.options = po_split(*extra_opts); + if (mi.options) { + retval = nfsmount_start(&mi); + po_destroy(mi.options); + } else nfs_error(_("%s: internal option parsing error"), progname); - goto fail; - } - if (!set_mandatory_options(type, &saddr, options)) - goto out; - - if (po_rightmost(options, "bg", "fg") == PO_KEY1_RIGHTMOST) - retval = nfsmount_bg(spec, node, type, hostname, flags, - options, fake, child, extra_opts); - else - retval = nfsmount_fg(spec, node, type, flags, options, - fake, extra_opts); - -out: - po_destroy(options); -fail: - free(hostname); + free(mi.hostname); return retval; } diff --git a/utils/mount/stropts.h b/utils/mount/stropts.h index b926d68..b4fd888 100644 --- a/utils/mount/stropts.h +++ b/utils/mount/stropts.h @@ -21,5 +21,10 @@ * */ +#ifndef _NFS_UTILS_MOUNT_STROPTS_H +#define _NFS_UTILS_MOUNT_STROPTS_H + int nfsmount_string(const char *, const char *, const char *, int, char **, int, int); + +#endif /* _NFS_UTILS_MOUNT_STROPTS_H */ diff --git a/utils/mount/token.h b/utils/mount/token.h index 47762dc..5a675ed 100644 --- a/utils/mount/token.h +++ b/utils/mount/token.h @@ -21,9 +21,14 @@ * */ +#ifndef _NFS_UTILS_MOUNT_TOKEN_H +#define _NFS_UTILS_MOUNT_TOKEN_H + struct tokenizer_state; char *next_token(struct tokenizer_state *); struct tokenizer_state *init_tokenizer(char *, char); int tokenizer_error(struct tokenizer_state *); void end_tokenizer(struct tokenizer_state *); + +#endif /* _NFS_UTILS_MOUNT_TOKEN_H */ diff --git a/utils/mount/version.h b/utils/mount/version.h new file mode 100644 index 0000000..46552a1 --- /dev/null +++ b/utils/mount/version.h @@ -0,0 +1,51 @@ +/* + * version.h -- get running kernel version + * + * Copyright (C) 2008 Oracle. All rights reserved. + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + */ + +#ifndef _NFS_UTILS_MOUNT_VERSION_H +#define _NFS_UTILS_MOUNT_VERSION_H + +#include +#include + +#include + +static inline unsigned int MAKE_VERSION(unsigned int p, unsigned int q, + unsigned int r) +{ + return (65536 * p) + (256 * q) + r; +} + +static inline unsigned int linux_version_code(void) +{ + struct utsname my_utsname; + unsigned int p, q, r; + + if (uname(&my_utsname)) + return 0; + + p = atoi(strtok(my_utsname.release, ".")); + q = atoi(strtok(NULL, ".")); + r = atoi(strtok(NULL, ".")); + return MAKE_VERSION(p, q, r); +} + +#endif /* _NFS_UTILS_MOUNT_VERSION_H */ diff --git a/utils/mountd/Makefile.in b/utils/mountd/Makefile.in index ef54e76..a5e7677 100644 --- a/utils/mountd/Makefile.in +++ b/utils/mountd/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -60,7 +60,7 @@ mountd_DEPENDENCIES = ../../support/export/libexport.a \ ../../support/nfs/libnfs.a ../../support/misc/libmisc.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -193,6 +193,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -287,8 +288,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -499,8 +500,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -512,8 +513,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -523,13 +524,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 63d5ce1..8137f7f 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -342,7 +342,14 @@ mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res) #define AUTH_GSS_KRB5 390003 #define AUTH_GSS_KRB5I 390004 #define AUTH_GSS_KRB5P 390005 - static int flavors[] = { AUTH_NULL, AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P}; + static int flavors[] = { AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P}; + /* + * We should advertise the preferred flavours first. (See RFC 2623 + * section 2.7.) AUTH_UNIX is arbitrarily ranked over the GSS's. + * AUTH_NULL is dropped from the list to avoid backward compatibility + * issue with older Linux clients, who inspect the list in reversed + * order. + */ struct nfs_fh_len *fh; xlog(D_CALL, "MNT3(%s) called", *path); diff --git a/utils/nfsd/Makefile.in b/utils/nfsd/Makefile.in index abb03e4..37183fd 100644 --- a/utils/nfsd/Makefile.in +++ b/utils/nfsd/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -54,7 +54,7 @@ am_nfsd_OBJECTS = nfsd.$(OBJEXT) nfsd_OBJECTS = $(am_nfsd_OBJECTS) nfsd_DEPENDENCIES = ../../support/export/libexport.a \ ../../support/nfs/libnfs.a ../../support/misc/libmisc.a -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -187,6 +187,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -274,8 +275,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -382,8 +383,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -395,8 +396,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -406,13 +407,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/nfsstat/Makefile.in b/utils/nfsstat/Makefile.in index 0da76b4..1cfccb0 100644 --- a/utils/nfsstat/Makefile.in +++ b/utils/nfsstat/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -54,7 +54,7 @@ am_nfsstat_OBJECTS = nfsstat.$(OBJEXT) nfsstat_OBJECTS = $(am_nfsstat_OBJECTS) nfsstat_DEPENDENCIES = ../../support/export/libexport.a \ ../../support/nfs/libnfs.a ../../support/misc/libmisc.a -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -187,6 +187,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -272,8 +273,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -380,8 +381,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -393,8 +394,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -404,13 +405,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/nfsstat/nfsstat.c b/utils/nfsstat/nfsstat.c index aa6c961..1517414 100644 --- a/utils/nfsstat/nfsstat.c +++ b/utils/nfsstat/nfsstat.c @@ -539,7 +539,7 @@ print_numbers(const char *hdr, unsigned int *info, unsigned int nr) fputs(hdr, stdout); for (i = 0; i < nr; i++) - printf("%s%-8d", i? " " : "", info[i]); + printf("%s%-8u", i? " " : "", info[i]); printf("\n"); } @@ -562,7 +562,7 @@ print_callstats(const char *hdr, const char **names, printf("\n"); for (j = 0; j < 6 && i + j < nr; j++) { pct = ((unsigned long long) info[i+j]*100)/total; - printf("%-8d%3llu%% ", info[i+j], pct); + printf("%-8u%3llu%% ", info[i+j], pct); } printf("\n"); } @@ -604,7 +604,7 @@ parse_raw_statfile(const char *name, struct statinfo *statp) for (i = 0; i < cnt; i++) { if (!(sp = strtok(NULL, " \t"))) break; - ip->valptr[i] = atoi(sp); + ip->valptr[i] = (unsigned int) strtoul(sp, NULL, 0); total += ip->valptr[i]; } ip->valptr[cnt - 1] = total; @@ -618,7 +618,8 @@ parse_raw_statfile(const char *name, struct statinfo *statp) static int parse_pretty_statfile(const char *filename, struct statinfo *info) { - int numvals, curindex, numconsumed, n, sum, err = 1; + int numvals, curindex, numconsumed, n, err = 1; + unsigned int sum; char buf[4096], *bufp, *fmt, is_proc; FILE *fp = NULL; struct statinfo *ip; @@ -716,7 +717,7 @@ mounts(const char *name) if (!(type = strtok(NULL, " \t"))) continue; - if (strcmp(type, "nfs")) { + if (strcmp(type, "nfs") && strcmp(type,"nfs4")) { continue; } diff --git a/utils/showmount/Makefile.in b/utils/showmount/Makefile.in index b5b5725..557b07f 100644 --- a/utils/showmount/Makefile.in +++ b/utils/showmount/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -54,7 +54,7 @@ am_showmount_OBJECTS = showmount-showmount.$(OBJEXT) showmount_OBJECTS = $(am_showmount_OBJECTS) showmount_DEPENDENCIES = ../../support/export/libexport.a \ ../../support/nfs/libnfs.a ../../support/misc/libmisc.a -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -187,6 +187,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -275,8 +276,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -397,8 +398,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -410,8 +411,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -421,13 +422,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/showmount/showmount.c b/utils/showmount/showmount.c index 4e10a29..213a573 100644 --- a/utils/showmount/showmount.c +++ b/utils/showmount/showmount.c @@ -82,6 +82,8 @@ static void usage(FILE *fp, int n) * * tout contains the timeout. It will be modified to contain the time * remaining (i.e. time provided - time elasped). + * + * Returns 0 for success */ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) { @@ -177,7 +179,7 @@ static unsigned short getport(struct sockaddr_in *addr, tout.tv_sec = TIMEOUT_TCP; ret = connect_nb(sock, &saddr, &tout); - if (ret == -1) { + if (ret < 0) { close(sock); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; @@ -240,6 +242,8 @@ static unsigned short getport(struct sockaddr_in *addr, rpc_createerr.cf_stat = status; clnt_destroy(client); return 0; + } else if (port == 0) { + rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; } clnt_destroy(client); @@ -350,7 +354,7 @@ int main(int argc, char **argv) MOUNTPROG, MOUNTVERS, IPPROTO_TCP); if (server_addr.sin_port) { ret = connect_nb(msock, &server_addr, 0); - if (ret != -1) + if (ret == 0) /* success */ mclient = clnttcp_create(&server_addr, MOUNTPROG, MOUNTVERS, &msock, 0, 0); @@ -364,7 +368,7 @@ int main(int argc, char **argv) server_addr.sin_port = getport(&server_addr, MOUNTPROG, MOUNTVERS, IPPROTO_UDP); if (!server_addr.sin_port) { - clnt_pcreateerror("portmap getport"); + clnt_pcreateerror("showmount"); exit(1); } msock = RPC_ANYSOCK; diff --git a/utils/statd/Makefile.in b/utils/statd/Makefile.in index 7e190a8..3467931 100644 --- a/utils/statd/Makefile.in +++ b/utils/statd/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008 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. @@ -68,7 +68,7 @@ statd_DEPENDENCIES = ../../support/export/libexport.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) dist_sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(dist_sbin_SCRIPTS) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -201,6 +201,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_gss = @enable_gss@ +enable_ipv6 = @enable_ipv6@ enable_nfsv3 = @enable_nfsv3@ enable_nfsv4 = @enable_nfsv4@ exec_prefix = @exec_prefix@ @@ -306,8 +307,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS) || test -f $$p1 \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done @@ -449,8 +450,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -462,8 +463,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -473,13 +474,12 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c index bb67c37..b75f11b 100644 --- a/utils/statd/sm-notify.c +++ b/utils/statd/sm-notify.c @@ -24,6 +24,8 @@ #include #include +#include "config.h" + #ifndef BASEDIR # ifdef NFS_STATEDIR # define BASEDIR NFS_STATEDIR @@ -76,7 +78,7 @@ static int log_syslog = 0; static unsigned int nsm_get_state(int); static void notify(void); -static void notify_host(int, struct nsm_host *); +static int notify_host(int, struct nsm_host *); static void recv_reply(int); static void backup_hosts(const char *, const char *); static void get_hosts(const char *); @@ -277,7 +279,7 @@ notify(void) if (failtime && now >= failtime) break; - while ((wait = hosts->send_next - now) <= 0) { + while (hosts && ((wait = hosts->send_next - now) <= 0)) { /* Never send more than 10 packets at once */ if (sent++ >= 10) break; @@ -286,7 +288,13 @@ notify(void) hp = hosts; hosts = hp->next; - notify_host(sock, hp); + if (notify_host(sock, hp)){ + unlink(hp->path); + free(hp->name); + free(hp->path); + free(hp); + continue; + } /* Set the timeout for this call, using an exponential timeout strategy */ @@ -298,6 +306,8 @@ notify(void) insert_host(hp); } + if (hosts == NULL) + return; nsm_log(LOG_DEBUG, "Host %s due in %ld seconds", hosts->name, wait); @@ -318,7 +328,7 @@ notify(void) /* * Send notification to a single host */ -void +int notify_host(int sock, struct nsm_host *host) { static unsigned int xid = 0; @@ -331,6 +341,16 @@ notify_host(int sock, struct nsm_host *host) if (!host->xid) host->xid = xid++; + if (host->ai == NULL) { + host->ai = host_lookup(AF_UNSPEC, host->name); + if (host->ai == NULL) { + nsm_log(LOG_WARNING, + "%s doesn't seem to be a valid address," + " skipped", host->name); + return 1; + } + } + memset(msgbuf, 0, sizeof(msgbuf)); p = msgbuf; *p++ = htonl(host->xid); @@ -343,14 +363,19 @@ notify_host(int sock, struct nsm_host *host) * point. */ if (host->retries >= 4) { - struct addrinfo *hold = host->ai; + struct addrinfo *first = host->ai; struct addrinfo **next = &host->ai; - *next = hold->ai_next; + + /* remove the first entry from the list */ + host->ai = first->ai_next; + first->ai_next = NULL; + /* find the end of the list */ + next = &first->ai_next; while ( *next ) next = & (*next)->ai_next; - *next = hold; - hold->ai_next = NULL; - memcpy(&host->addr, hold->ai_addr, hold->ai_addrlen); + /* put first entry at end */ + *next = first; + memcpy(&host->addr, first->ai_addr, first->ai_addrlen); addr_set_port(&host->addr, 0); host->retries = 0; } @@ -394,7 +419,11 @@ notify_host(int sock, struct nsm_host *host) } len = (p - msgbuf) << 2; - sendto(sock, msgbuf, len, 0, (struct sockaddr *) &dest, sizeof(dest)); + if (sendto(sock, msgbuf, len, 0, (struct sockaddr *) &dest, sizeof(dest)) < 0) + nsm_log(LOG_WARNING, "Sending Reboot Notification to " + "'%s' failed: errno %d (%s)", host->name, errno, strerror(errno)); + + return 0; } /* @@ -504,7 +533,7 @@ backup_hosts(const char *dirname, const char *bakname) } /* - * Get all entries from sm.bak and convert them to host names + * Get all entries from sm.bak and convert them to host entries */ static void get_hosts(const char *dirname) @@ -532,15 +561,6 @@ get_hosts(const char *dirname) if (stat(path, &stb) < 0) continue; - host->ai = host_lookup(AF_UNSPEC, de->d_name); - if (! host->ai) { - nsm_log(LOG_WARNING, - "%s doesn't seem to be a valid address, skipped", - de->d_name); - unlink(path); - continue; - } - host->last_used = stb.st_mtime; host->timeout = NSM_TIMEOUT; host->path = strdup(path);