mkdir -p $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak
touch $(DESTDIR)$(statedir)/state
chmod go-rwx $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
- chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
+ -chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
uninstall-hook:
rm $(DESTDIR)$(statedir)/xtab
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
- ChangeLog INSTALL NEWS config.guess config.sub depcomp \
+ ChangeLog INSTALL NEWS compile config.guess config.sub depcomp \
install-sh ltmain.sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
mkdir -p $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak
touch $(DESTDIR)$(statedir)/state
chmod go-rwx $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
- chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
+ -chown $(statduser) $(DESTDIR)$(statedir)/sm $(DESTDIR)$(statedir)/sm.bak $(DESTDIR)$(statedir)/state
uninstall-hook:
rm $(DESTDIR)$(statedir)/xtab
-This is a dummy news file to make automake happy.
+Significant changes for nfs-utils 1.1.0 - March/April 2007
+
+ - rpc.lockd is gone. One 3 old kernel releases need it.
+ - /sbin/{u,}mount.nfs{,4} is now installed so 'mount' will
+ use these to mount nfs filesystems instead of internal code.
+ + mount.nfs will check for 'statd' to be running when mounting
+ a filesystem which requires it. If it is not running it will
+ run "/usr/sbin/start-statd" to try to start it.
+ If statd is not running and cannot be started, mount.nfs will
+ refuse to mount the filesystem and will suggest the 'nolock'
+ option.
+ - Substantial changes to statd
+ + The 'notify' process that must happen at boot has been split
+ into a separate program "sm-notify". It ensures that it
+ only runs once even if you restart statd. This is correct
+ behaviour.
+ + statd stores state in the files in /var/lib/nfs/sm/ so that
+ if you kill and restart it, it will restore that state and
+ continue working correctly.
+ + statd makes more use of DNS lookup and should handle
+ multi-homed peers better.
+ - If you export a directory as 'crossmnt', all filesystems
+ mounted beneath are automatically exported with the same
+ options (unless explicitly exported with different options).
+ - subtree_check is no-longer the default. The default is now
+ no_subtree_check.
+ - By default the system 'rpcgen' is used while building
+ nfs-utils rather than the internal one.
+
+
+Further notes on statd:
+
+ statd should be installed in /usr/sbin, not /sbin.
+ If you need to mount /usr via nfs, use 'nolock'
+
+ At boot time, run "/usr/sbin/sm-notify".
+ Run "statd" only when starting the NFS server.
+ "statd" should be run before starting the NFS server.
+ You do not need to start statd at boot time incase an
+ NFS filesystem is mounted. mount.nfs will take care of that.
+
+ Make sure /usr/sbin/start-statd will run statd with required
+ arguments.
rm -f confinc confmf
])
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005
+# 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 5
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
AC_DEFINE_UNQUOTED(KRB5_VERSION, $K5VERS, [Define this as the Kerberos version number])
if test -f $dir/include/gssapi/gssapi_krb5.h -a \
\( -f $dir/lib/libgssapi_krb5.a -o \
+ -f $dir/lib64/libgssapi_krb5.a -o \
+ -f $dir/lib64/libgssapi_krb5.so -o \
-f $dir/lib/libgssapi_krb5.so \) ; then
AC_DEFINE(HAVE_KRB5, 1, [Define this if you have MIT Kerberos libraries])
KRBDIR="$dir"
--- /dev/null
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2005-05-14.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# 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, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as `compile cc -o foo foo.c'.
+ # So we strip `-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no `-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # `.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.0.11.
+# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.1.0-rc1.
#
# Report bugs to <nfs@lists.sf.net>.
#
# Identity of this package.
PACKAGE_NAME='linux nfs-utils'
PACKAGE_TARNAME='nfs-utils'
-PACKAGE_VERSION='1.0.11'
-PACKAGE_STRING='linux nfs-utils 1.0.11'
+PACKAGE_VERSION='1.1.0-rc1'
+PACKAGE_STRING='linux nfs-utils 1.1.0-rc1'
PACKAGE_BUGREPORT='nfs@lists.sf.net'
-ac_unique_file="tools/getiversion/getiversion.c"
ac_default_prefix=/usr
ac_unique_file="support/include/config.h.in"
# Factoring default headers for most tests.
RELEASE
statedir
statduser
+startstatd
enable_nfsv3
IDMAPD
enable_nfsv4
secure_statd
CONFIG_RQUOTAD_TRUE
CONFIG_RQUOTAD_FALSE
+RPCGEN_PATH
+CONFIG_RPCGEN_TRUE
+CONFIG_RPCGEN_FALSE
CONFIG_MOUNT_TRUE
CONFIG_MOUNT_FALSE
CC
# 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.0.11 to adapt to many kinds of systems.
+\`configure' configures linux nfs-utils 1.1.0-rc1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of linux nfs-utils 1.0.11:";;
+ short | recursive ) echo "Configuration of linux nfs-utils 1.1.0-rc1:";;
esac
cat <<\_ACEOF
--enable-kprefix install progs as rpc.knfsd etc
--enable-secure-statd Only lockd can use statd (security)
--enable-rquotad enable rquotad [default=yes]
+ --without-uuid Exclude uuid support and so avoid possibly buggy
+ libblkid
--enable-mount Create mount.nfs and don't use the util-linux
mount(8) functionality. [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
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
--enable-fast-install[=PKGS]
--with-statedir=/foo use state dir /foo /var/lib/nfs
--with-statduser=rpcuser
statd to run under [rpcuser or nobody]
+ --with-start-statd=scriptname
+ When an nfs filesystems is mounted with locking, run
+ this script
+ --with-rpcgen=internal use internal rpcgen instead of system one
--with-tcp-wrappers[=PATH] Enable tcpwrappers support
(optionally in PATH)
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-linux nfs-utils configure 1.0.11
+linux nfs-utils configure 1.1.0-rc1
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
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.0.11, which was
+It was created by linux nfs-utils $as_me 1.1.0-rc1, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
-
am__api_version='1.10'
# Find a good install program. We prefer a C program (faster),
# Define the identity of the package.
PACKAGE='nfs-utils'
- VERSION='1.0.11'
+ VERSION='1.1.0-rc1'
cat >>confdefs.h <<_ACEOF
fi
+
+# Check whether --with-start-statd was given.
+if test "${with_start_statd+set}" = set; then
+ withval=$with_start_statd; startstatd=$withval
+else
+ startstatd=/usr/sbin/start-statd
+
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define START_STATD "$startstatd"
+_ACEOF
+
# Check whether --enable-nfsv3 was given.
if test "${enable_nfsv3+set}" = set; then
enableval=$enable_nfsv3; enable_nfsv3=$enableval
if test "${enable_secure_statd+set}" = set; then
enableval=$enable_secure_statd; test "$enableval" = "yes" && secure_statd=yes
else
- secure_statd=no
+ secure_statd=yes
fi
if test "$secure_statd" = yes; then
fi
+# Check whether --with-rpcgen was given.
+if test "${with_rpcgen+set}" = set; then
+ withval=$with_rpcgen; rpcgen_path=$withval
+else
+ rpcgen_path=yes
+fi
+
+ RPCGEN_PATH=
+ if test "$rpcgen_path" == "yes"; then
+ for p in /usr/local/bin/rpcgen /usr/bin/rpcgen /bin/rpcgen
+ do if test -f $p ; then RPCGEN_PATH=$p ; break; fi ; done
+ elif test "$rpcgen_path" != "internal"; then
+ RPCGEN_PATH=$rpcgen_path
+ fi
+
+ if test "$RPCGEN_PATH" == ""; then
+ CONFIG_RPCGEN_TRUE=
+ CONFIG_RPCGEN_FALSE='#'
+else
+ CONFIG_RPCGEN_TRUE='#'
+ CONFIG_RPCGEN_FALSE=
+fi
+
+# Check whether --enable-uuid was given.
+if test "${enable_uuid+set}" = set; then
+ enableval=$enable_uuid; if test "$enableval" = "yes" ; then use_blkid=1; else use_blkid=0; fi
+else
+ use_blkid=1
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define USE_BLKID $use_blkid
+_ACEOF
+
# Check whether --enable-mount was given.
if test "${enable_mount+set}" = set; then
enableval=$enable_mount; enable_mount=$enableval
else
- enable_mount=no
+ enable_mount=yes
fi
if test "$enable_mount" = "yes"; then
+# Arrange for large-file support
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_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
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ 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_cv_sys_largefile_CC=' -n32'; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_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_cv_sys_file_offset_bits=no; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_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_cv_sys_file_offset_bits=64; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -f conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_large_files+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_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_cv_sys_large_files=no; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_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_cv_sys_large_files=1; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -f conftest*
+ fi
+fi
+
+
ac_config_headers="$ac_config_headers support/include/config.h"
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 6298 "configure"' > conftest.$ac_ext
+ echo '#line 6709 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
-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:8327: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8738: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8331: \$? = $ac_status" >&5
+ echo "$as_me:8742: \$? = $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.
-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:8595: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:9006: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8599: \$? = $ac_status" >&5
+ echo "$as_me:9010: \$? = $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.
-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:8699: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:9110: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8703: \$? = $ac_status" >&5
+ echo "$as_me:9114: \$? = $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
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10996 "configure"
+#line 11407 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 11096 "configure"
+#line 11507 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
-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:13432: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13843: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13436: \$? = $ac_status" >&5
+ echo "$as_me:13847: \$? = $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.
-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:13536: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13947: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13540: \$? = $ac_status" >&5
+ echo "$as_me:13951: \$? = $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
-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:15097: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15508: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15101: \$? = $ac_status" >&5
+ echo "$as_me:15512: \$? = $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.
-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:15201: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15612: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15205: \$? = $ac_status" >&5
+ echo "$as_me:15616: \$? = $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
-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:17388: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17799: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17392: \$? = $ac_status" >&5
+ echo "$as_me:17803: \$? = $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.
-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:17656: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:18067: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17660: \$? = $ac_status" >&5
+ echo "$as_me:18071: \$? = $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.
-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:17760: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:18171: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17764: \$? = $ac_status" >&5
+ echo "$as_me:18175: \$? = $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
+if test "x$CC" != xcc; then
+ { echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5
+echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6; }
+else
+ { echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5
+echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6; }
+fi
+set dummy $CC; ac_cc=`echo $2 |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+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. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { (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_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ test -f conftest2.$ac_objext && { (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_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); };
+then
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.$ac_ext >&5'
+ { (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_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+ rm -f conftest2.*
+ if { (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_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ test -f conftest2.$ac_objext && { (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_try") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); };
+ then
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define NO_MINUS_C_MINUS_O 1
+_ACEOF
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+
+
if test "x$cross_compiling" = "xno"; then
CC_FOR_BUILD=${CC_FOR_BUILD-${CC-gcc}}
fi
fi
-{ echo "$as_me:$LINENO: checking for blkid_get_cache in -lblkid" >&5
+if test "$use_blkid" = 1; then
+ { echo "$as_me:$LINENO: checking for blkid_get_cache in -lblkid" >&5
echo $ECHO_N "checking for blkid_get_cache in -lblkid... $ECHO_C" >&6; }
if test "${ac_cv_lib_blkid_blkid_get_cache+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
{ (exit 1); exit 1; }; }
fi
-if test "${ac_cv_header_blkid_blkid_h+set}" = set; then
+ if test "${ac_cv_header_blkid_blkid_h+set}" = set; then
{ echo "$as_me:$LINENO: checking for blkid/blkid.h" >&5
echo $ECHO_N "checking for blkid/blkid.h... $ECHO_C" >&6; }
if test "${ac_cv_header_blkid_blkid_h+set}" = set; then
fi
+fi
if test -f $dir/include/gssapi/gssapi_krb5.h -a \
\( -f $dir/lib/libgssapi_krb5.a -o \
+ -f $dir/lib64/libgssapi_krb5.a -o \
+ -f $dir/lib64/libgssapi_krb5.so -o \
-f $dir/lib/libgssapi_krb5.so \) ; then
cat >>confdefs.h <<\_ACEOF
my_am_cflags="-Wall $ARCHFLAGS -pipe"
-AM_CPPFLAGS="-I\${top_srcdir}/support/include -D_FILE_OFFSET_BITS=64"
+AM_CPPFLAGS="-I\${top_srcdir}/support/include"
AM_CFLAGS="$my_am_cflags"
ACLOCAL_AMFLAGS="-I $ac_macro_dir \$(ACLOCAL_FLAGS)"
-ac_config_files="$ac_config_files Makefile linux-nfs/Makefile support/Makefile support/export/Makefile support/include/nfs/Makefile support/include/rpcsvc/Makefile support/include/sys/fs/Makefile support/include/sys/Makefile support/include/Makefile support/misc/Makefile support/nfs/Makefile tools/Makefile tools/getiversion/Makefile tools/locktest/Makefile tools/nlmtest/Makefile tools/rpcdebug/Makefile tools/rpcgen/Makefile utils/Makefile utils/exportfs/Makefile utils/gssd/Makefile utils/idmapd/Makefile utils/lockd/Makefile utils/mount/Makefile utils/mountd/Makefile utils/nfsd/Makefile utils/nfsstat/Makefile utils/rquotad/Makefile utils/showmount/Makefile utils/statd/Makefile"
+ac_config_files="$ac_config_files Makefile linux-nfs/Makefile support/Makefile support/export/Makefile support/include/nfs/Makefile support/include/rpcsvc/Makefile support/include/sys/fs/Makefile support/include/sys/Makefile support/include/Makefile support/misc/Makefile support/nfs/Makefile tools/Makefile tools/locktest/Makefile tools/nlmtest/Makefile tools/rpcdebug/Makefile tools/rpcgen/Makefile utils/Makefile utils/exportfs/Makefile utils/gssd/Makefile utils/idmapd/Makefile utils/mount/Makefile utils/mountd/Makefile utils/nfsd/Makefile utils/nfsstat/Makefile utils/rquotad/Makefile utils/showmount/Makefile utils/statd/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${CONFIG_RPCGEN_TRUE}" && test -z "${CONFIG_RPCGEN_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"CONFIG_RPCGEN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"CONFIG_RPCGEN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${CONFIG_MOUNT_TRUE}" && test -z "${CONFIG_MOUNT_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"CONFIG_MOUNT\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
# 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.0.11, which was
+This file was extended by linux nfs-utils $as_me 1.1.0-rc1, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-linux nfs-utils config.status 1.0.11
+linux nfs-utils config.status 1.1.0-rc1
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
"support/misc/Makefile") CONFIG_FILES="$CONFIG_FILES support/misc/Makefile" ;;
"support/nfs/Makefile") CONFIG_FILES="$CONFIG_FILES support/nfs/Makefile" ;;
"tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
- "tools/getiversion/Makefile") CONFIG_FILES="$CONFIG_FILES tools/getiversion/Makefile" ;;
"tools/locktest/Makefile") CONFIG_FILES="$CONFIG_FILES tools/locktest/Makefile" ;;
"tools/nlmtest/Makefile") CONFIG_FILES="$CONFIG_FILES tools/nlmtest/Makefile" ;;
"tools/rpcdebug/Makefile") CONFIG_FILES="$CONFIG_FILES tools/rpcdebug/Makefile" ;;
"utils/exportfs/Makefile") CONFIG_FILES="$CONFIG_FILES utils/exportfs/Makefile" ;;
"utils/gssd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/gssd/Makefile" ;;
"utils/idmapd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/idmapd/Makefile" ;;
- "utils/lockd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/lockd/Makefile" ;;
"utils/mount/Makefile") CONFIG_FILES="$CONFIG_FILES utils/mount/Makefile" ;;
"utils/mountd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/mountd/Makefile" ;;
"utils/nfsd/Makefile") CONFIG_FILES="$CONFIG_FILES utils/nfsd/Makefile" ;;
RELEASE!$RELEASE$ac_delim
statedir!$statedir$ac_delim
statduser!$statduser$ac_delim
+startstatd!$startstatd$ac_delim
enable_nfsv3!$enable_nfsv3$ac_delim
IDMAPD!$IDMAPD$ac_delim
enable_nfsv4!$enable_nfsv4$ac_delim
secure_statd!$secure_statd$ac_delim
CONFIG_RQUOTAD_TRUE!$CONFIG_RQUOTAD_TRUE$ac_delim
CONFIG_RQUOTAD_FALSE!$CONFIG_RQUOTAD_FALSE$ac_delim
+RPCGEN_PATH!$RPCGEN_PATH$ac_delim
+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
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
-OBJEXT!$OBJEXT$ac_delim
-DEPDIR!$DEPDIR$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+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
am__quote!$am__quote$ac_delim
AMDEP_TRUE!$AMDEP_TRUE$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 56; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 60; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
--- /dev/null
+dnl Process this file with autoconf to produce a configure script.
+dnl
+AC_INIT([linux nfs-utils],[1.1.0-rc1],[nfs@lists.sf.net],[nfs-utils])
+AC_CANONICAL_BUILD([])
+AC_CANONICAL_HOST([])
+AC_CONFIG_MACRO_DIR(aclocal)
+AM_INIT_AUTOMAKE
+AC_PREREQ(2.59)
+AC_PREFIX_DEFAULT(/usr)
+AM_MAINTAINER_MODE
+
+dnl *************************************************************
+dnl * Define the set of applicable options
+dnl *************************************************************
+AC_ARG_WITH(release,
+ [AC_HELP_STRING([--with-release=XXX], [set release to XXX [1]])],
+ RELEASE=$withval,
+ RELEASE=1)
+ AC_SUBST(RELEASE)
+AC_ARG_WITH(statedir,
+ [ --with-statedir=/foo use state dir /foo [/var/lib/nfs]],
+ statedir=$withval,
+ statedir=/var/lib/nfs)
+ AC_SUBST(statedir)
+AC_ARG_WITH(statduser,
+ [AC_HELP_STRING([--with-statduser=rpcuser],
+ [statd to run under @<:@rpcuser or nobody@:>@]
+ )],
+ statduser=$withval,
+ if test "x$cross_compiling" = "xno"; then
+ if grep -s '^rpcuser:' /etc/passwd > /dev/null; then
+ statduser=rpcuser
+ else
+ statduser=nobody
+ fi
+ else
+ statduser=nobody
+ fi)
+ AC_SUBST(statduser)
+AC_ARG_WITH(start-statd,
+ [AC_HELP_STRING([--with-start-statd=scriptname],
+ [When an nfs filesystems is mounted with locking, run this script]
+ )],
+ startstatd=$withval,
+ startstatd=/usr/sbin/start-statd
+ )
+ AC_SUBST(startstatd)
+ AC_DEFINE_UNQUOTED(START_STATD, "$startstatd", [Define this to a script which can start statd on mount])
+AC_ARG_ENABLE(nfsv3,
+ [AC_HELP_STRING([--enable-nfsv3],
+ [enable support for NFSv3 @<:@default=yes@:>@])],
+ enable_nfsv3=$enableval,
+ enable_nfsv3=yes)
+ if test "$enable_nfsv3" = yes; then
+ AC_DEFINE(NFS3_SUPPORTED, 1, [Define this if you want NFSv3 support compiled in])
+ else
+ enable_nfsv3=
+ fi
+ AC_SUBST(enable_nfsv3)
+AC_ARG_ENABLE(nfsv4,
+ [AC_HELP_STRING([--enable-nfsv4],
+ [enable support for NFSv4 @<:@default=yes@:>@])],
+ enable_nfsv4=$enableval,
+ enable_nfsv4=yes)
+ if test "$enable_nfsv4" = yes; then
+ AC_DEFINE(NFS4_SUPPORTED, 1, [Define this if you want NFSv4 support compiled in])
+ IDMAPD=idmapd
+ else
+ enable_nfsv4=
+ IDMAPD=
+ fi
+ AC_SUBST(IDMAPD)
+ AC_SUBST(enable_nfsv4)
+ AM_CONDITIONAL(CONFIG_NFSV4, [test "$enable_nfsv4" = "yes"])
+AC_ARG_ENABLE(gss,
+ [AC_HELP_STRING([--enable-gss],
+ [enable support for rpcsec_gss @<:@default=yes@:>@])],
+ enable_gss=$enableval,
+ enable_gss=yes)
+ if test "$enable_gss" = yes; then
+ AC_DEFINE(GSS_SUPPORTED, 1, [Define this if you want rpcsec_gss support compiled in])
+ GSSD=gssd
+ SVCGSSD=svcgssd
+ else
+ enable_gss=
+ GSSD=
+ SVCGSSD=
+ fi
+ AC_SUBST(GSSD)
+ AC_SUBST(SVCGSSD)
+ AC_SUBST(enable_gss)
+ AM_CONDITIONAL(CONFIG_GSS, [test "$enable_gss" = "yes"])
+AC_ARG_ENABLE(kprefix,
+ [AC_HELP_STRING([--enable-kprefix], [install progs as rpc.knfsd etc])],
+ test "$enableval" = "yes" && kprefix=k,
+ kprefix=)
+ AC_SUBST(kprefix)
+AC_ARG_ENABLE(secure-statd,
+ [AC_HELP_STRING([--enable-secure-statd],
+ [Only lockd can use statd (security)])],
+ test "$enableval" = "yes" && secure_statd=yes,
+ secure_statd=yes)
+ if test "$secure_statd" = yes; then
+ AC_DEFINE(RESTRICTED_STATD, 1, [Define this if you want to enable various security checks in statd. These checks basically keep anyone but lockd from using this service.])
+ fi
+ AC_SUBST(secure_statd)
+AC_ARG_ENABLE(rquotad,
+ [AC_HELP_STRING([--enable-rquotad],
+ [enable rquotad @<:@default=yes@:>@])],
+ enable_rquotad=$enableval,
+ enable_rquotad=yes)
+ if test "$enable_rquotad" = yes; then
+ RQUOTAD=rquotad
+ else
+ RQUOTAD=
+ fi
+ AM_CONDITIONAL(CONFIG_RQUOTAD, [test "$enable_rquotad" = "yes"])
+AC_ARG_WITH(rpcgen,
+ [AC_HELP_STRING([--with-rpcgen=internal], [use internal rpcgen instead of system one])],
+ rpcgen_path=$withval,
+ rpcgen_path=yes )
+ RPCGEN_PATH=
+ if test "$rpcgen_path" == "yes"; then
+ for p in /usr/local/bin/rpcgen /usr/bin/rpcgen /bin/rpcgen
+ do if test -f $p ; then RPCGEN_PATH=$p ; break; fi ; done
+ elif test "$rpcgen_path" != "internal"; then
+ RPCGEN_PATH=$rpcgen_path
+ fi
+ AC_SUBST(RPCGEN_PATH)
+ AM_CONDITIONAL(CONFIG_RPCGEN, [test "$RPCGEN_PATH" == ""])
+AC_ARG_ENABLE(uuid,
+ [AC_HELP_STRING([--without-uuid], [Exclude uuid support and so avoid possibly buggy libblkid])],
+ if test "$enableval" = "yes" ; then use_blkid=1; else use_blkid=0; fi,
+ use_blkid=1)
+ AC_DEFINE_UNQUOTED(USE_BLKID, $use_blkid, [Define if you want to use blkid to find uuid of filesystems])
+AC_ARG_ENABLE(mount,
+ [AC_HELP_STRING([--enable-mount],
+ [Create mount.nfs and don't use the util-linux mount(8) functionality. @<:@default=no@:>@])],
+ enable_mount=$enableval,
+ enable_mount=yes)
+ AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"])
+
+# Check whether user wants TCP wrappers support
+AC_TCP_WRAPPERS
+
+# Arrange for large-file support
+AC_SYS_LARGEFILE
+
+AC_CONFIG_SRCDIR([support/include/config.h.in])
+AC_CONFIG_HEADERS([support/include/config.h])
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+AM_PROG_CC_C_O
+
+if test "x$cross_compiling" = "xno"; then
+ CC_FOR_BUILD=${CC_FOR_BUILD-${CC-gcc}}
+else
+ CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
+fi
+
+AC_SUBST(CC_FOR_BUILD)
+
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(LD, ld)
+
+AC_HEADER_STDC([])
+AC_GNULIBC
+AC_BSD_SIGNALS
+
+dnl *************************************************************
+dnl * Check for required libraries
+dnl *************************************************************
+AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBNSL="-lnsl"])])
+AC_SUBST(LIBNSL)
+
+AC_CHECK_FUNC(connect, ,
+ AC_CHECK_LIB(socket, connect, [LIBSOCKET="-lsocket"],
+ AC_MSG_ERROR(Function 'socket' not found.), $LIBNSL))
+
+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]))
+ AC_CHECK_LIB(nfsidmap, nfs4_init_name_mapping, [libnfsidmap=1], AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
+ AC_CHECK_HEADERS(event.h, ,AC_MSG_ERROR([libevent needed for nfsv4 support]))
+ AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
+ dnl librpcsecgss already has a dependency on libgssapi,
+ dnl but we need to make sure we get the right version
+ if test "$enable_gss" = yes; then
+ PKG_CHECK_MODULES(RPCSECGSS, librpcsecgss >= 0.10, ,
+ [AC_MSG_ERROR([Unable to locate information required to use librpcsecgss. If you have pkgconfig installed, you might try setting environment variable PKG_CONFIG_PATH to /usr/local/lib/pkgconfig])
+ ]
+ )
+ PKG_CHECK_MODULES(GSSAPI, libgssapi >= 0.9)
+ fi
+
+fi
+if test "$knfsd_cv_glibc2" = no; then
+ AC_CHECK_LIB(bsd, daemon, [LIBBSD="-lbsd"])
+fi
+if test "$use_blkid" = 1; then
+ AC_CHECK_LIB(blkid, blkid_get_cache, [LIBBLKID="-lblkid"], AC_MSG_ERROR([libblkid needed]))
+ AC_CHECK_HEADER(blkid/blkid.h, , AC_MSG_ERROR([Cannot file libblkid header file blkid/blkid.h]))
+fi
+AC_SUBST(LIBSOCKET)
+AC_SUBST(LIBCRYPT)
+AC_SUBST(LIBBSD)
+AC_SUBST(LIBBLKID)
+
+if test "$enable_gss" = yes; then
+ dnl 'gss' also depends on nfsidmap.h - at least for svcgssd_proc.c
+ AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for gss support]))
+ AC_CHECK_HEADERS(spkm3.h, ,AC_MSG_WARN([could not locate SPKM3 header; will not have SPKM3 support]))
+ dnl the nfs4_set_debug function doesn't appear in all version of the library
+ AC_CHECK_LIB(nfsidmap, nfs4_set_debug,
+ AC_DEFINE(HAVE_NFS4_SET_DEBUG,1,
+ [Whether nfs4_set_debug() is present in libnfsidmap]),)
+
+ dnl Check for Kerberos V5
+ AC_KERBEROS_V5
+
+ dnl This is not done until here because we need to have KRBLIBS set
+ dnl ("librpcsecgss=1" is so that it doesn't get added to LIBS)
+ AC_CHECK_LIB(rpcsecgss, authgss_create_default, [librpcsecgss=1], AC_MSG_ERROR([librpcsecgss needed for nfsv4 support]), -lgssapi -ldl)
+ AC_CHECK_LIB(rpcsecgss, authgss_set_debug_level,
+ AC_DEFINE(HAVE_AUTHGSS_SET_DEBUG_LEVEL, 1, [Define this if the rpcsec_gss library has the function authgss_set_debug_level]),, -lgssapi -ldl)
+
+fi
+
+dnl *************************************************************
+dnl Check for headers
+dnl *************************************************************
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h \
+ malloc.h memory.h netdb.h netinet/in.h paths.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])
+
+dnl *************************************************************
+dnl Checks for typedefs, structures, and compiler characteristics
+dnl *************************************************************
+AC_C_CONST
+AC_TYPE_UID_T
+AC_C_INLINE
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl *************************************************************
+dnl Check for functions
+dnl *************************************************************
+AC_FUNC_ALLOCA
+AC_FUNC_CLOSEDIR_VOID
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FORK
+AC_FUNC_GETGROUPS
+AC_FUNC_GETMNTENT
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_LSTAT
+AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
+AC_HEADER_MAJOR
+#AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+#AC_FUNC_REALLOC
+AC_FUNC_SELECT_ARGTYPES
+AC_TYPE_SIGNAL
+AC_FUNC_STAT
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
+ gethostbyaddr gethostbyname gethostname getmntent \
+ gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
+ realpath rmdir select socket strcasecmp strchr strdup \
+ strerror strrchr strtol strtoul sigprocmask])
+
+
+dnl *************************************************************
+dnl Check for data sizes (XXX These should go away with libgssapi pkg-config)
+dnl *************************************************************
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(socklen_t)
+
+
+dnl *************************************************************
+dnl Export some path names to config.h
+dnl *************************************************************
+AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$statedir", [This defines the location of the NFS state files. Warning: this must match definitions in config.mk!])
+
+if test "x$cross_compiling" = "xno"; then
+ CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"$CFLAGS"}
+ CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-"$CXXFLAGS"}
+ CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-"$CPPFLAGS"}
+ LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-"$LDFLAGS"}
+else
+ CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-""}
+ CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-""}
+ CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-""}
+ LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-""}
+fi
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+
+AC_SUBST(CFLAGS_FOR_BUILD)
+AC_SUBST(CXXFLAGS_FOR_BUILD)
+AC_SUBST(CPPFLAGS_FOR_BUILD)
+AC_SUBST(LDFLAGS_FOR_BUILD)
+
+dnl *************************************************************
+dnl Set up "global" CFLAGS
+dnl *************************************************************
+dnl Use architecture-specific compile flags
+dnl (We use $host and not $build in case we are cross-compiling)
+dnl *************************************************************
+case $host in
+ alpha*)
+ ARCHFLAGS="-mno-fp-regs -ffixed-8" ;;
+ *)
+ ARCHFLAGS="" ;;
+esac
+
+my_am_cflags="-Wall $ARCHFLAGS -pipe"
+
+AC_SUBST([AM_CPPFLAGS], ["-I\${top_srcdir}/support/include"])
+AC_SUBST([AM_CFLAGS], ["$my_am_cflags"])
+
+# Make sure that $ACLOCAL_FLAGS are used during a rebuild
+AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
+
+AC_CONFIG_FILES([
+ Makefile
+ linux-nfs/Makefile
+ support/Makefile
+ support/export/Makefile
+ support/include/nfs/Makefile
+ support/include/rpcsvc/Makefile
+ support/include/sys/fs/Makefile
+ support/include/sys/Makefile
+ support/include/Makefile
+ support/misc/Makefile
+ support/nfs/Makefile
+ tools/Makefile
+ tools/locktest/Makefile
+ tools/nlmtest/Makefile
+ tools/rpcdebug/Makefile
+ tools/rpcgen/Makefile
+ utils/Makefile
+ utils/exportfs/Makefile
+ utils/gssd/Makefile
+ utils/idmapd/Makefile
+ utils/mount/Makefile
+ utils/mountd/Makefile
+ utils/nfsd/Makefile
+ utils/nfsstat/Makefile
+ utils/rquotad/Makefile
+ utils/showmount/Makefile
+ utils/statd/Makefile])
+AC_OUTPUT
+
+++ /dev/null
-dnl Process this file with autoconf to produce a configure script.
-dnl
-AC_INIT([linux nfs-utils],[1.0.11],[nfs@lists.sf.net],[nfs-utils])
-AC_CANONICAL_BUILD([])
-AC_CANONICAL_HOST([])
-AC_CONFIG_SRCDIR(tools/getiversion/getiversion.c)
-AC_CONFIG_MACRO_DIR(aclocal)
-AM_INIT_AUTOMAKE
-AC_PREREQ(2.59)
-AC_PREFIX_DEFAULT(/usr)
-AM_MAINTAINER_MODE
-
-dnl *************************************************************
-dnl * Define the set of applicable options
-dnl *************************************************************
-AC_ARG_WITH(release,
- [AC_HELP_STRING([--with-release=XXX], [set release to XXX [1]])],
- RELEASE=$withval,
- RELEASE=1)
- AC_SUBST(RELEASE)
-AC_ARG_WITH(statedir,
- [ --with-statedir=/foo use state dir /foo [/var/lib/nfs]],
- statedir=$withval,
- statedir=/var/lib/nfs)
- AC_SUBST(statedir)
-AC_ARG_WITH(statduser,
- [AC_HELP_STRING([--with-statduser=rpcuser],
- [statd to run under @<:@rpcuser or nobody@:>@]
- )],
- statduser=$withval,
- if test "x$cross_compiling" = "xno"; then
- if grep -s '^rpcuser:' /etc/passwd > /dev/null; then
- statduser=rpcuser
- else
- statduser=nobody
- fi
- else
- statduser=nobody
- fi)
- AC_SUBST(statduser)
-AC_ARG_ENABLE(nfsv3,
- [AC_HELP_STRING([--enable-nfsv3],
- [enable support for NFSv3 @<:@default=yes@:>@])],
- enable_nfsv3=$enableval,
- enable_nfsv3=yes)
- if test "$enable_nfsv3" = yes; then
- AC_DEFINE(NFS3_SUPPORTED, 1, [Define this if you want NFSv3 support compiled in])
- else
- enable_nfsv3=
- fi
- AC_SUBST(enable_nfsv3)
-AC_ARG_ENABLE(nfsv4,
- [AC_HELP_STRING([--enable-nfsv4],
- [enable support for NFSv4 @<:@default=yes@:>@])],
- enable_nfsv4=$enableval,
- enable_nfsv4=yes)
- if test "$enable_nfsv4" = yes; then
- AC_DEFINE(NFS4_SUPPORTED, 1, [Define this if you want NFSv4 support compiled in])
- IDMAPD=idmapd
- else
- enable_nfsv4=
- IDMAPD=
- fi
- AC_SUBST(IDMAPD)
- AC_SUBST(enable_nfsv4)
- AM_CONDITIONAL(CONFIG_NFSV4, [test "$enable_nfsv4" = "yes"])
-AC_ARG_ENABLE(gss,
- [AC_HELP_STRING([--enable-gss],
- [enable support for rpcsec_gss @<:@default=yes@:>@])],
- enable_gss=$enableval,
- enable_gss=yes)
- if test "$enable_gss" = yes; then
- AC_DEFINE(GSS_SUPPORTED, 1, [Define this if you want rpcsec_gss support compiled in])
- GSSD=gssd
- SVCGSSD=svcgssd
- else
- enable_gss=
- GSSD=
- SVCGSSD=
- fi
- AC_SUBST(GSSD)
- AC_SUBST(SVCGSSD)
- AC_SUBST(enable_gss)
- AM_CONDITIONAL(CONFIG_GSS, [test "$enable_gss" = "yes"])
-AC_ARG_ENABLE(kprefix,
- [AC_HELP_STRING([--enable-kprefix], [install progs as rpc.knfsd etc])],
- test "$enableval" = "yes" && kprefix=k,
- kprefix=)
- AC_SUBST(kprefix)
-AC_ARG_ENABLE(secure-statd,
- [AC_HELP_STRING([--enable-secure-statd],
- [Only lockd can use statd (security)])],
- test "$enableval" = "yes" && secure_statd=yes,
- secure_statd=no)
- if test "$secure_statd" = yes; then
- AC_DEFINE(RESTRICTED_STATD, 1, [Define this if you want to enable various security checks in statd. These checks basically keep anyone but lockd from using this service.])
- fi
- AC_SUBST(secure_statd)
-AC_ARG_ENABLE(rquotad,
- [AC_HELP_STRING([--enable-rquotad],
- [enable rquotad @<:@default=yes@:>@])],
- enable_rquotad=$enableval,
- enable_rquotad=yes)
- if test "$enable_rquotad" = yes; then
- RQUOTAD=rquotad
- else
- RQUOTAD=
- fi
- AM_CONDITIONAL(CONFIG_RQUOTAD, [test "$enable_rquotad" = "yes"])
-
-AC_ARG_ENABLE(mount,
- [AC_HELP_STRING([--enable-mount],
- [Create mount.nfs and don't use the util-linux mount(8) functionality. @<:@default=no@:>@])],
- enable_mount=$enableval,
- enable_mount=no)
- AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"])
-
-# Check whether user wants TCP wrappers support
-AC_TCP_WRAPPERS
-
-AC_CONFIG_SRCDIR([support/include/config.h.in])
-AC_CONFIG_HEADERS([support/include/config.h])
-
-# Checks for programs.
-AC_PROG_CXX
-AC_PROG_CC
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-AC_PROG_LIBTOOL
-
-if test "x$cross_compiling" = "xno"; then
- CC_FOR_BUILD=${CC_FOR_BUILD-${CC-gcc}}
-else
- CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
-fi
-
-AC_SUBST(CC_FOR_BUILD)
-
-AC_CHECK_TOOL(AR, ar)
-AC_CHECK_TOOL(LD, ld)
-
-AC_HEADER_STDC([])
-AC_GNULIBC
-AC_BSD_SIGNALS
-
-dnl *************************************************************
-dnl * Check for required libraries
-dnl *************************************************************
-AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBNSL="-lnsl"])])
-AC_SUBST(LIBNSL)
-
-AC_CHECK_FUNC(connect, ,
- AC_CHECK_LIB(socket, connect, [LIBSOCKET="-lsocket"],
- AC_MSG_ERROR(Function 'socket' not found.), $LIBNSL))
-
-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]))
- AC_CHECK_LIB(nfsidmap, nfs4_init_name_mapping, [libnfsidmap=1], AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
- AC_CHECK_HEADERS(event.h, ,AC_MSG_ERROR([libevent needed for nfsv4 support]))
- AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for nfsv4 support]))
- dnl librpcsecgss already has a dependency on libgssapi,
- dnl but we need to make sure we get the right version
- if test "$enable_gss" = yes; then
- PKG_CHECK_MODULES(RPCSECGSS, librpcsecgss >= 0.10, ,
- [AC_MSG_ERROR([Unable to locate information required to use librpcsecgss. If you have pkgconfig installed, you might try setting environment variable PKG_CONFIG_PATH to /usr/local/lib/pkgconfig])
- ]
- )
- PKG_CHECK_MODULES(GSSAPI, libgssapi >= 0.9)
- fi
-
-fi
-if test "$knfsd_cv_glibc2" = no; then
- AC_CHECK_LIB(bsd, daemon, [LIBBSD="-lbsd"])
-fi
-AC_CHECK_LIB(blkid, blkid_get_cache, [LIBBLKID="-lblkid"], AC_MSG_ERROR([libblkid needed]))
-AC_CHECK_HEADER(blkid/blkid.h, , AC_MSG_ERROR([Cannot file libblkid header file blkid/blkid.h]))
-AC_SUBST(LIBSOCKET)
-AC_SUBST(LIBCRYPT)
-AC_SUBST(LIBBSD)
-AC_SUBST(LIBBLKID)
-
-if test "$enable_gss" = yes; then
- dnl 'gss' also depends on nfsidmap.h - at least for svcgssd_proc.c
- AC_CHECK_HEADERS(nfsidmap.h, ,AC_MSG_ERROR([libnfsidmap needed for gss support]))
- AC_CHECK_HEADERS(spkm3.h, ,AC_MSG_WARN([could not locate SPKM3 header; will not have SPKM3 support]))
- dnl the nfs4_set_debug function doesn't appear in all version of the library
- AC_CHECK_LIB(nfsidmap, nfs4_set_debug,
- AC_DEFINE(HAVE_NFS4_SET_DEBUG,1,
- [Whether nfs4_set_debug() is present in libnfsidmap]),)
-
- dnl Check for Kerberos V5
- AC_KERBEROS_V5
-
- dnl This is not done until here because we need to have KRBLIBS set
- dnl ("librpcsecgss=1" is so that it doesn't get added to LIBS)
- AC_CHECK_LIB(rpcsecgss, authgss_create_default, [librpcsecgss=1], AC_MSG_ERROR([librpcsecgss needed for nfsv4 support]), -lgssapi -ldl)
- AC_CHECK_LIB(rpcsecgss, authgss_set_debug_level,
- AC_DEFINE(HAVE_AUTHGSS_SET_DEBUG_LEVEL, 1, [Define this if the rpcsec_gss library has the function authgss_set_debug_level]),, -lgssapi -ldl)
-
-fi
-
-dnl *************************************************************
-dnl Check for headers
-dnl *************************************************************
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h \
- malloc.h memory.h netdb.h netinet/in.h paths.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])
-
-dnl *************************************************************
-dnl Checks for typedefs, structures, and compiler characteristics
-dnl *************************************************************
-AC_C_CONST
-AC_TYPE_UID_T
-AC_C_INLINE
-AC_TYPE_OFF_T
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_HEADER_TIME
-AC_STRUCT_TM
-
-dnl *************************************************************
-dnl Check for functions
-dnl *************************************************************
-AC_FUNC_ALLOCA
-AC_FUNC_CLOSEDIR_VOID
-AC_FUNC_ERROR_AT_LINE
-AC_FUNC_FORK
-AC_FUNC_GETGROUPS
-AC_FUNC_GETMNTENT
-AC_PROG_GCC_TRADITIONAL
-AC_FUNC_LSTAT
-AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
-AC_HEADER_MAJOR
-#AC_FUNC_MALLOC
-AC_FUNC_MEMCMP
-#AC_FUNC_REALLOC
-AC_FUNC_SELECT_ARGTYPES
-AC_TYPE_SIGNAL
-AC_FUNC_STAT
-AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
- gethostbyaddr gethostbyname gethostname getmntent \
- gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
- realpath rmdir select socket strcasecmp strchr strdup \
- strerror strrchr strtol strtoul sigprocmask])
-
-
-dnl *************************************************************
-dnl Check for data sizes (XXX These should go away with libgssapi pkg-config)
-dnl *************************************************************
-AC_CHECK_SIZEOF(short)
-AC_CHECK_SIZEOF(int)
-AC_CHECK_SIZEOF(long)
-AC_CHECK_SIZEOF(size_t)
-AC_CHECK_SIZEOF(socklen_t)
-
-
-dnl *************************************************************
-dnl Export some path names to config.h
-dnl *************************************************************
-AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$statedir", [This defines the location of the NFS state files. Warning: this must match definitions in config.mk!])
-
-if test "x$cross_compiling" = "xno"; then
- CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"$CFLAGS"}
- CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-"$CXXFLAGS"}
- CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-"$CPPFLAGS"}
- LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-"$LDFLAGS"}
-else
- CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-""}
- CXXFLAGS_FOR_BUILD=${CXXFLAGS_FOR_BUILD-""}
- CPPFLAGS_FOR_BUILD=${CPPFLAGS_FOR_BUILD-""}
- LDFLAGS_FOR_BUILD=${LDFLAGS_FOR_BUILD-""}
-fi
-
-AC_SUBST(CFLAGS)
-AC_SUBST(CXXFLAGS)
-AC_SUBST(CPPFLAGS)
-AC_SUBST(LDFLAGS)
-
-AC_SUBST(CFLAGS_FOR_BUILD)
-AC_SUBST(CXXFLAGS_FOR_BUILD)
-AC_SUBST(CPPFLAGS_FOR_BUILD)
-AC_SUBST(LDFLAGS_FOR_BUILD)
-
-dnl *************************************************************
-dnl Set up "global" CFLAGS
-dnl *************************************************************
-dnl Use architecture-specific compile flags
-dnl (We use $host and not $build in case we are cross-compiling)
-dnl *************************************************************
-case $host in
- alpha*)
- ARCHFLAGS="-mno-fp-regs -ffixed-8" ;;
- *)
- ARCHFLAGS="" ;;
-esac
-
-my_am_cflags="-Wall $ARCHFLAGS -pipe"
-
-AC_SUBST([AM_CPPFLAGS], ["-I\${top_srcdir}/support/include -D_FILE_OFFSET_BITS=64"])
-AC_SUBST([AM_CFLAGS], ["$my_am_cflags"])
-
-# Make sure that $ACLOCAL_FLAGS are used during a rebuild
-AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
-
-AC_CONFIG_FILES([
- Makefile
- linux-nfs/Makefile
- support/Makefile
- support/export/Makefile
- support/include/nfs/Makefile
- support/include/rpcsvc/Makefile
- support/include/sys/fs/Makefile
- support/include/sys/Makefile
- support/include/Makefile
- support/misc/Makefile
- support/nfs/Makefile
- tools/Makefile
- tools/getiversion/Makefile
- tools/locktest/Makefile
- tools/nlmtest/Makefile
- tools/rpcdebug/Makefile
- tools/rpcgen/Makefile
- utils/Makefile
- utils/exportfs/Makefile
- utils/gssd/Makefile
- utils/idmapd/Makefile
- utils/lockd/Makefile
- utils/mount/Makefile
- utils/mountd/Makefile
- utils/nfsd/Makefile
- utils/nfsstat/Makefile
- utils/rquotad/Makefile
- utils/showmount/Makefile
- utils/statd/Makefile])
-AC_OUTPUT
-
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
## Process this file with automake to produce Makefile.in
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
GENFILES_CLNT = mount_clnt.c
GENFILES_XDR = mount_xdr.c
rm ${distdir}/$$f; \
done
+if CONFIG_RPCGEN
+RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
$(RPCGEN):
make -C $(top_srcdir)/tools/rpcgen all
+else
+RPCGEN = @RPCGEN_PATH@
+endif
$(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
test -f $@ && rm -rf $@ || true
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
GENFILES_CLNT = mount_clnt.c
GENFILES_XDR = mount_xdr.c
GENFILES_H = mount.h
BUILT_SOURCES = $(GENFILES)
noinst_HEADERS = mount.h
+@CONFIG_RPCGEN_FALSE@RPCGEN = @RPCGEN_PATH@
+@CONFIG_RPCGEN_TRUE@RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
MAINTAINERCLEANFILES = Makefile.in
CLEANFILES = $(GENFILES) $(top_builddir)/support/include/mount.h
all: $(BUILT_SOURCES)
for f in $(GENFILES); do \
rm ${distdir}/$$f; \
done
-
-$(RPCGEN):
- make -C $(top_srcdir)/tools/rpcgen all
+@CONFIG_RPCGEN_TRUE@$(RPCGEN):
+@CONFIG_RPCGEN_TRUE@ make -C $(top_srcdir)/tools/rpcgen all
$(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
test -f $@ && rm -rf $@ || true
strcat(new, ",");
strcat(new, cp);
}
+ free(old);
return new;
}
exp->m_xtabent = 0;
exp->m_mayexport = 0;
exp->m_changed = 0;
+ exp->m_warned = 0;
exp->m_client = clp;
clp->m_count++;
}
new->m_exported = 0;
new->m_xtabent = 0;
new->m_changed = 0;
+ new->m_warned = 0;
export_add(new);
return new;
if (stat(exp->m_export.m_path, &stb) < 0)
return 0;
- if (exp->m_export.e_maptype != CLE_MAP_IDENT) {
- xlog(L_ERROR, "%s: unsupported mapping; kernel supports only 'identity' (default)",
- exp->m_export.m_path);
- errno = EINVAL;
- return 0;
- }
memset(exparg, 0, sizeof(*exparg));
strncpy(exparg->ex_path, exp->m_export.m_path,
sizeof (exparg->ex_path) - 1);
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
-/* support/include/config.h.in. Generated from configure.in by autoheader. */
+/* support/include/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if the `closedir' function returns void instead of `int'. */
#undef CLOSEDIR_VOID
definitions in config.mk! */
#undef NFS_STATEDIR
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
/* Name of package */
#undef PACKAGE
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
+/* Define this to a script which can start statd on mount */
+#undef START_STATD
+
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
+/* Define if you want to use blkid to find uuid of filesystems */
+#undef USE_BLKID
+
/* Define this if the private function, gss_krb5_cache_name, must be used to
tell the Kerberos library which credentials cache to use. Otherwise, this
is done by setting the KRB5CCNAME environment variable */
/* Version number of package */
#undef VERSION
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
struct sockaddr_in *);
u_long nfsvers_to_mnt(const u_long);
u_long mntvers_to_nfs(const u_long);
-int get_socket(struct sockaddr_in *, u_int, int);
+int get_socket(struct sockaddr_in *, u_int, int, int);
CLIENT * mnt_openclnt(clnt_addr_t *, int *);
void mnt_closeclnt(CLIENT *, int);
int m_exported; /* known to knfsd. -1 means not sure */
int m_xtabent : 1, /* xtab entry exists */
m_mayexport: 1, /* derived from xtabbed */
- m_changed : 1; /* options (may) have changed */
+ m_changed : 1, /* options (may) have changed */
+ m_warned : 1; /* warned about multiple exports
+ * matching one client */
} nfs_export;
extern nfs_client * clientlist[MCL_MAXTYPES];
#include "nfs_mntent.h"
+#ifndef _PATH_FSTAB
+#define _PATH_FSTAB "/etc/fstab"
+#endif
+
int mtab_is_writable(void);
int mtab_does_not_exist(void);
struct mntentchn {
struct mntentchn *nxt, *prev;
- nfs_mntent_t m;
+ struct mntent m;
};
-struct mntentchn *mtab_head (void);
struct mntentchn *getmntoptfile (const char *file);
struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc);
struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc);
+struct mntentchn *getfsfile (const char *file);
+struct mntentchn *getfsspec (const char *spec);
+
void lock_mtab (void);
void unlock_mtab (void);
-void update_mtab (const char *special, nfs_mntent_t *with);
+void update_mtab (const char *special, struct mntent *with);
#endif /* _NFS_FSTAB_H */
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
#define NFSCTL_GETFD 7 /* get an fh by path (used by mountd) */
#define NFSCTL_GETFS 8 /* get an fh by path with max size (used by mountd) */
-/* Above this is for lockd. */
-#define NFSCTL_LOCKD 0x10000
-#define LOCKDCTL_SVC NFSCTL_LOCKD
-
#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << ((_v) - 1)))
#define NFSCTL_UDPUNSET(_cltbits) ((_cltbits) &= ~(1 << (17 - 1)))
#define NFSCTL_TCPUNSET(_cltbits) ((_cltbits) &= ~(1 << (18 - 1)))
#ifndef _NFS_MNTENT_H
#define _NFS_MNTENT_H
-
-typedef struct nfs_mntent_s {
- const char *mnt_fsname;
- const char *mnt_dir;
- const char *mnt_type;
- const char *mnt_opts;
- int mnt_freq;
- int mnt_passno;
-} nfs_mntent_t;
+#include <mntent.h>
#define ERR_MAX 5
mntFILE *nfs_setmntent (const char *file, char *mode);
void nfs_endmntent (mntFILE *mfp);
-int nfs_addmntent (mntFILE *mfp, nfs_mntent_t *mnt);
+int nfs_addmntent (mntFILE *mfp, struct mntent *mnt);
struct nfs_mntent *my_getmntent (mntFILE *mfp);
-nfs_mntent_t *nfs_getmntent (mntFILE *mfp);
+struct mntent *nfs_getmntent (mntFILE *mfp);
#endif /* _NFS_MNTENT_H */
#define _PATH_PROC_EXPORTS_ALT "/proc/fs/nfsd/exports"
#endif
-enum cle_maptypes {
- CLE_MAP_IDENT = 0,
- CLE_MAP_FILE,
- CLE_MAP_UGIDD,
-};
-
/*
* Data related to a single exports entry as returned by getexportent.
* FIXME: export options should probably be parsed at a later time to
use it for anything else. */
char m_path[NFS_MAXPATHLEN+1];
int e_flags;
- int e_maptype;
int e_anonuid;
int e_anongid;
int * e_squids;
void closeall(int min);
-/* lockd. */
-int lockdsvc();
-
int svctcp_socket (u_long __number, int __reuse);
int svcudp_socket (u_long __number, int __reuse);
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
noinst_LIBRARIES = libnfs.a
libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \
- nfsexport.c getfh.c nfsctl.c lockdsvc.c \
+ nfsexport.c getfh.c nfsctl.c \
svc_socket.c cacheio.c closeall.c conn.c fstab.c nfs_mntent.c
MAINTAINERCLEANFILES = Makefile.in
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
rpcmisc.$(OBJEXT) rpcdispatch.$(OBJEXT) xlog.$(OBJEXT) \
xcommon.$(OBJEXT) wildmat.$(OBJEXT) nfssvc.$(OBJEXT) \
nfsclient.$(OBJEXT) nfsexport.$(OBJEXT) getfh.$(OBJEXT) \
- nfsctl.$(OBJEXT) lockdsvc.$(OBJEXT) svc_socket.$(OBJEXT) \
- cacheio.$(OBJEXT) closeall.$(OBJEXT) conn.$(OBJEXT) \
- fstab.$(OBJEXT) nfs_mntent.$(OBJEXT)
+ nfsctl.$(OBJEXT) svc_socket.$(OBJEXT) cacheio.$(OBJEXT) \
+ closeall.$(OBJEXT) conn.$(OBJEXT) fstab.$(OBJEXT) \
+ nfs_mntent.$(OBJEXT)
libnfs_a_OBJECTS = $(am_libnfs_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
noinst_LIBRARIES = libnfs.a
libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \
- nfsexport.c getfh.c nfsctl.c lockdsvc.c \
+ nfsexport.c getfh.c nfsctl.c \
svc_socket.c cacheio.c closeall.c conn.c fstab.c nfs_mntent.c
MAINTAINERCLEANFILES = Makefile.in
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exports.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstab.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfh.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockdsvc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfs_mntent.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsclient.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsctl.Po@am__quote@
* RPC_ANYSOCK is returned which will cause
* the RPC code to create the socket instead.
*/
-int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)
+int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp, int conn)
{
int so, cc, type;
struct sockaddr_in laddr;
return RPC_ANYSOCK;
}
}
- if (type == SOCK_STREAM || type == SOCK_DGRAM) {
+ if (type == SOCK_STREAM || (conn && type == SOCK_DGRAM)) {
cc = connect(so, (struct sockaddr *)saddr, namelen);
if (cc < 0) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
CLIENT *clnt=NULL;
int sock, stat;
static char clnt_res;
+ struct sockaddr dissolve;
rpc_createerr.cf_stat = stat = errno = 0;
- sock = get_socket(saddr, prot, FALSE);
- if (sock == RPC_ANYSOCK && errno == ETIMEDOUT) {
- /*
- * TCP timeout. Bubble up the error to see
- * how it should be handled.
- */
- rpc_createerr.cf_stat = RPC_TIMEDOUT;
- goto out_bad;
+ sock = get_socket(saddr, prot, FALSE, TRUE);
+ if (sock == RPC_ANYSOCK) {
+ if (errno == ETIMEDOUT) {
+ /*
+ * TCP timeout. Bubble up the error to see
+ * how it should be handled.
+ */
+ rpc_createerr.cf_stat = RPC_TIMEDOUT;
+ }
+ return 0;
+ }
+
+ if (caddr) {
+ /* Get the address of our end of this connection */
+ socklen_t len = sizeof(*caddr);
+ if (getsockname(sock, caddr, &len) != 0)
+ caddr->sin_family = 0;
}
switch(prot) {
case IPPROTO_UDP:
+ /* The socket is connected (so we could getsockname successfully),
+ * but some servers on multi-homed hosts reply from
+ * the wrong address, so if we stay connected, we lose the reply.
+ */
+ dissolve.sa_family = AF_UNSPEC;
+ connect(sock, &dissolve, sizeof(dissolve));
+
clnt = clntudp_bufcreate(saddr, prog, vers,
RETRY_TIMEOUT, &sock,
RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
clnt = clnttcp_create(saddr, prog, vers, &sock,
RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
break;
- default:
- goto out_bad;
}
- if (!clnt)
- goto out_bad;
+ if (!clnt) {
+ close(sock);
+ return 0;
+ }
memset(&clnt_res, 0, sizeof(clnt_res));
stat = clnt_call(clnt, NULLPROC,
(xdrproc_t)xdr_void, (caddr_t)NULL,
rpc_createerr.cf_stat = stat;
}
clnt_destroy(clnt);
- if (sock != -1) {
- if (caddr) {
- /* Get the address of our end of this connection */
- socklen_t len = sizeof(*caddr);
- if (getsockname(sock, caddr, &len) != 0)
- caddr->sin_family = 0;
- }
- close(sock);
- }
+ close(sock);
if (stat == RPC_SUCCESS)
return 1;
-
- out_bad:
- return 0;
+ else
+ return 0;
}
CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
/* contact the mount daemon via TCP */
mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
- *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE);
+ *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, TRUE, FALSE);
switch (mnt_pmap->pm_prot) {
case IPPROTO_UDP:
#include "xio.h"
#define EXPORT_DEFAULT_FLAGS \
- (NFSEXP_READONLY|NFSEXP_ROOTSQUASH|NFSEXP_GATHERED_WRITES)
+ (NFSEXP_READONLY|NFSEXP_ROOTSQUASH|NFSEXP_GATHERED_WRITES|NFSEXP_NOSUBTREECHECK)
int export_errno;
static int parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr);
static int parsesquash(char *list, int **idp, int *lenp, char **ep);
static int parsenum(char **cpp);
-static int parsemaptype(char *type);
static void freesquash(void);
static void syntaxerr(char *msg);
def_ee.e_flags &= ~NFSEXP_ASYNC;
def_ee.e_flags &= ~NFSEXP_GATHERED_WRITES;
}
- def_ee.e_maptype = CLE_MAP_IDENT;
def_ee.e_anonuid = 65534;
def_ee.e_anongid = 65534;
def_ee.e_squids = NULL;
xlog(L_ERROR, "unknown fsloc method for %s:%s",
ep->e_hostname, ep->e_path);
}
- fprintf(fp, "mapping=");
- switch (ep->e_maptype) {
- case CLE_MAP_IDENT:
- fprintf(fp, "identity,");
- break;
- case CLE_MAP_UGIDD:
- fprintf(fp, "ugidd,");
- break;
- case CLE_MAP_FILE:
- fprintf(fp, "file,");
- break;
- default:
- xlog(L_ERROR, "unknown mapping type for %s:%s",
- ep->e_hostname, ep->e_path);
- }
if ((id = ep->e_squids) != NULL) {
fprintf(fp, "squash_uids=");
for (i = 0; i < ep->e_nsquids; i += 2)
static struct exportent ee;
ee.e_flags = EXPORT_DEFAULT_FLAGS;
- ee.e_maptype = CLE_MAP_IDENT;
ee.e_anonuid = 65534;
ee.e_anongid = 65534;
ee.e_squids = NULL;
ep->e_flags &= ~NFSEXP_NOACL;
else if (strcmp(opt, "no_acl") == 0)
ep->e_flags |= NFSEXP_NOACL;
- else if (strncmp(opt, "mapping=", 8) == 0)
- ep->e_maptype = parsemaptype(opt+8);
- else if (strcmp(opt, "map_identity") == 0) /* old style */
- ep->e_maptype = CLE_MAP_IDENT;
- else if (strcmp(opt, "map_daemon") == 0) /* old style */
- ep->e_maptype = CLE_MAP_UGIDD;
else if (strncmp(opt, "anonuid=", 8) == 0) {
char *oe;
ep->e_anonuid = strtol(opt+8, &oe, 10);
out:
if (warn && !had_subtree_opt)
xlog(L_WARNING, "%s [%d]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"%s:%s\".\n"
- " Assuming default behaviour ('subtree_check').\n"
- " NOTE: this default will change with nfs-utils version 1.1.0\n",
+ " Assuming default behaviour ('no_subtree_check').\n"
+ " NOTE: this default has changed since nfs-utils version 1.0.x\n",
flname, flline,
ep->e_hostname, ep->e_path);
return num;
}
-static int
-parsemaptype(char *type)
-{
- if (!strcmp(type, "identity"))
- return CLE_MAP_IDENT;
- if (!strcmp(type, "ugidd"))
- return CLE_MAP_UGIDD;
- if (!strcmp(type, "file"))
- return CLE_MAP_FILE;
- syntaxerr("invalid map type");
- return CLE_MAP_IDENT; /* default */
-}
-
static int
getpath(char *path, int len)
{
struct mntentchn mounttable;
static int got_mtab = 0;
+struct mntentchn fstab;
+static int got_fstab = 0;
static void read_mounttable(void);
+static void read_fstab(void);
-struct mntentchn *
+static struct mntentchn *
mtab_head() {
if (!got_mtab)
read_mounttable();
return &mounttable;
}
+static struct mntentchn *
+fstab_head()
+{
+ if (!got_fstab)
+ read_fstab();
+ return &fstab;
+}
+
+#if 0
static void
my_free(const void *s) {
if (s)
free(mc);
}
}
+#endif
static void
read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
struct mntentchn *mc = mc0;
- nfs_mntent_t *mnt;
+ struct mntent *mnt;
while ((mnt = nfs_getmntent(mfp)) != NULL) {
if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
read_mntentchn(mfp, fnam, mc);
}
+static void
+read_fstab()
+{
+ mntFILE *mfp = NULL;
+ const char *fnam;
+ struct mntentchn *mc = &fstab;
+
+ got_fstab = 1;
+ mc->nxt = mc->prev = NULL;
+
+ fnam = _PATH_FSTAB;
+ mfp = nfs_setmntent (fnam, "r");
+ if (mfp == NULL || mfp->mntent_fp == NULL) {
+ int errsv = errno;
+ nfs_error(_("warning: can't open %s: %s"),
+ _PATH_FSTAB, strerror (errsv));
+ return;
+ }
+ read_mntentchn(mfp, fnam, mc);
+}
+
/*
* Given the directory name NAME, and the place MCPREV we found it last time,
* try to find more occurrences.
return NULL;
}
+/* Find the dir FILE in fstab. */
+struct mntentchn *
+getfsfile (const char *file)
+{
+ struct mntentchn *mc, *mc0;
+
+ mc0 = fstab_head();
+ for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
+ if (streq(mc->m.mnt_dir, file))
+ return mc;
+ return NULL;
+}
+
+/* Find the device SPEC in fstab. */
+struct mntentchn *
+getfsspec (const char *spec)
+{
+ struct mntentchn *mc, *mc0;
+
+ mc0 = fstab_head();
+ for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
+ if (streq(mc->m.mnt_fsname, spec))
+ return mc;
+ return NULL;
+}
+
/* Updating mtab ----------------------------------------------*/
/* Flag for already existing lock file. */
*/
void
-update_mtab (const char *dir, nfs_mntent_t *instead) {
+update_mtab (const char *dir, struct mntent *instead)
+{
mntFILE *mfp, *mftmp;
const char *fnam = MOUNTED;
struct mntentchn mtabhead; /* dummy */
}
}
+#if 0
+ /* the chain might have strings copied from 'instead',
+ * so we cannot safely free it.
+ * And there is no need anyway because we are going to exit
+ * shortly. So just don't call discard_mntentchn....
+ */
discard_mntentchn(mc0);
-
+#endif
if (fchmod (fileno (mftmp->mntent_fp),
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
int errsv = errno;
+++ /dev/null
-/*
- * support/nfs/nfssvc.c
- *
- * Run an NFS daemon.
- *
- * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <nfslib.h>
-
-int
-lockdsvc()
-{
- struct nfsctl_arg arg;
-
- arg.ca_version = NFSCTL_VERSION;
- return nfsctl(LOCKDCTL_SVC, &arg, NULL);
-}
}
int
-nfs_addmntent (mntFILE *mfp, nfs_mntent_t *mnt) {
+nfs_addmntent (mntFILE *mfp, struct mntent *mnt) {
char *m1, *m2, *m3, *m4;
int res;
}
/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
-nfs_mntent_t *
+struct mntent *
nfs_getmntent (mntFILE *mfp) {
static char buf[4096];
- static nfs_mntent_t me;
+ static struct mntent me;
char *s;
again:
sin.sin_port = htons(port);
val = 1;
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0)
- xlog(L_ERROR, "setsockopt failed: %s\n", strerror(errno));
+ if (proto == IPPROTO_TCP)
+ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ &val, sizeof(val)) < 0)
+ xlog(L_ERROR, "setsockopt failed: %s\n",
+ strerror(errno));
#if 0
/* I was told it didn't work with gigabit ethernet.
int
svcudp_socket (u_long number, int reuse)
{
- return svc_socket (number, SOCK_DGRAM, IPPROTO_UDP, reuse);
+ return svc_socket (number, SOCK_DGRAM, IPPROTO_UDP, 0);
}
#ifdef TEST
## Process this file with automake to produce Makefile.in
-SUBDIRS = getiversion locktest rpcdebug rpcgen nlmtest
+OPTDIRS =
+
+if CONFIG_RPCGEN
+OPTDIRS += rpcgen
+endif
+
+SUBDIRS = locktest rpcdebug nlmtest $(OPTDIRS)
MAINTAINERCLEANFILES = Makefile.in
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@CONFIG_RPCGEN_TRUE@am__append_1 = rpcgen
subdir = tools
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
+DIST_SUBDIRS = locktest rpcdebug nlmtest rpcgen
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-SUBDIRS = getiversion locktest rpcdebug rpcgen nlmtest
+OPTDIRS = $(am__append_1)
+SUBDIRS = locktest rpcdebug nlmtest $(OPTDIRS)
MAINTAINERCLEANFILES = Makefile.in
all: all-recursive
+++ /dev/null
-## Process this file with automake to produce Makefile.in
-
-CC=$(CC_FOR_BUILD)
-LIBTOOL = @LIBTOOL@ --tag=CC
-
-noinst_PROGRAMS = getiversion
-getiversion_SOURCES = getiversion.c
-getiversion_CFLAGS=$(CFLAGS_FOR_BUILD)
-getiversion_CPPFLAGS=$(CPPFLAGS_FOR_BUILD) -I$(top_srcdir)/support/include
-getiversion_LDFLAGS=$(LDFLAGS_FOR_BUILD)
-
-MAINTAINERCLEANFILES = Makefile.in
+++ /dev/null
-/*
- * getiversion
- *
- * Get version number for an inode on an ext2 file system.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#include <stdio.h>
-#include <sys/fs/ext2fs.h>
-
-int
-main(int argc, char **argv)
-{
- int i, fd;
- u_int32_t vers;
-
- if (argc <= 1) {
- fprintf(stderr, "usage: getiversion file ...\n");
- return 1;
- }
-
- for (i = 1; i < argc; i++) {
- if ((fd = open(argv[i], O_RDONLY)) < 0
- || ioctl(fd, EXT2_IOC_GETVERSION, &vers) < 0) {
- perror(argv[i]);
- continue;
- } else {
- printf("%-20s %d\n", argv[i], vers);
- }
- close(fd);
- }
- return 0;
-}
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
SUBDIRS = \
exportfs \
- lockd \
mountd \
nfsd \
nfsstat \
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = exportfs lockd mountd nfsd nfsstat showmount statd \
- rquotad idmapd gssd mount
+DIST_SUBDIRS = exportfs mountd nfsd nfsstat showmount statd rquotad \
+ idmapd gssd mount
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(am__append_4)
SUBDIRS = \
exportfs \
- lockd \
mountd \
nfsd \
nfsstat \
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
exp->m_xtabent = 1;
exp->m_mayexport = 1;
exp->m_changed = 1;
+ exp->m_warned = 0;
}
}
}
exp->m_xtabent = 1;
exp->m_mayexport = 1;
exp->m_changed = 1;
+ exp->m_warned = 0;
if (hp) free (hp);
}
c = dumpopt(c, "mountpoint%s%s",
ep->e_mountpoint[0]?"=":"",
ep->e_mountpoint);
- if (ep->e_maptype == CLE_MAP_UGIDD)
- c = dumpopt(c, "mapping=ugidd");
- else if (ep->e_maptype == CLE_MAP_FILE)
- c = dumpopt(c, "mapping=file");
if (ep->e_anonuid != 65534)
c = dumpopt(c, "anonuid=%d", ep->e_anonuid);
if (ep->e_anongid != 65534)
Finally, you can map all user requests to the
anonymous uid by specifying the
.IR all_squash " option.
-'''.PP
-'''For the benefit of installations where uids differ between different
-'''machines,
-'''.I nfsd
-'''provides several mechanism to dynamically map server uids to client
-'''uids and vice versa: static mapping files, NIS-based mapping, and
-'''.IR ugidd -based
-'''mapping.
-'''.PP
-'''.IR ugidd -based
-'''mapping is enabled with the
-'''.I map_daemon
-'''option, and uses the UGID RPC protocol. For this to work, you have to run
-'''the
-'''.IR ugidd (8)
-'''mapping daemon on the client host. It is the least secure of the three methods,
-'''because by running
-'''.IR ugidd ,
-'''everybody can query the client host for a list of valid user names. You
-'''can protect yourself by restricting access to
-'''.I ugidd
-'''to valid hosts only. This can be done by entering the list of valid
-'''hosts into the
-'''.I hosts.allow
-'''or
-'''.I hosts.deny
-'''file. The service name is
-'''.IR ugidd .
-'''For a description of the file's syntax, please read
-'''.IR hosts_access (5).
-'''.PP
-'''Static mapping is enabled by using the
-'''.I map_static
-'''option, which takes a file name as an argument that describes the mapping.
-'''NIS-based mapping queries the client's NIS server to obtain a mapping from
-'''user and group names on the server host to user and group names on the
-'''client.
.PP
Here's the complete list of mapping options:
.TP
.TP
.IR no_root_squash
Turn off root squashing. This option is mainly useful for diskless clients.
-'''.TP
-'''.IR squash_uids " and " squash_gids
-'''This option specifies a list of uids or gids that should be subject to
-'''anonymous mapping. A valid list of ids looks like this:
-'''.IP
-'''.IR squash_uids=0-15,20,25-50
-'''.IP
-'''Usually, your squash lists will look a lot simpler.
.TP
.IR all_squash
Map all uids and gids to the anonymous user. Useful for NFS-exported
is
.IR no_all_squash ,
which is the default setting.
-'''.TP
-'''.IR map_daemon
-'''This option turns on dynamic uid/gid mapping. Each uid in an NFS request
-'''will be translated to the equivalent server uid, and each uid in an
-'''NFS reply will be mapped the other way round. This option requires that
-'''.IR rpc.ugidd (8)
-'''runs on the client host. The default setting is
-'''.IR map_identity ,
-'''which leaves all uids untouched. The normal squash options apply regardless
-'''of whether dynamic mapping is requested or not.
-'''.TP
-'''.IR map_static
-'''This option enables static mapping. It specifies the name of the file
-'''that describes the uid/gid mapping, e.g.
-'''.IP
-'''.IR map_static=/etc/nfs/foobar.map
-'''.IP
-'''The file's format looks like this
-'''.IP
-'''.nf
-'''.ta +3i
-'''# Mapping for client foobar:
-'''# remote local
-'''uid 0-99 - # squash these
-'''uid 100-500 1000 # map 100-500 to 1000-1400
-'''gid 0-49 - # squash these
-'''gid 50-100 700 # map 50-100 to 700-750
-'''.fi
-'''.TP
-'''.IR map_nis
-'''This option enables NIS-based uid/gid mapping. For instance, when
-'''the server encounters the uid 123 on the server, it will obtain the
-'''login name associated with it, and contact the NFS client's NIS server
-'''to obtain the uid the client associates with the name.
-'''.IP
-'''In order to do this, the NFS server must know the client's NIS domain.
-'''This is specified as an argument to the
-'''.I map_nis
-'''options, e.g.
-'''.IP
-'''.I map_nis=foo.com
-'''.IP
-'''Note that it may not be sufficient to simply specify the NIS domain
-'''here; you may have to take additional actions before
-'''.I nfsd
-'''is actually able to contact the server. If your distribution uses
-'''the NYS library, you can specify one or more NIS servers for the
-'''client's domain in
-'''.IR /etc/yp.conf .
-'''If you are using a different NIS library, you may have to obtain a
-'''special
-'''.IR ypbind (8)
-'''daemon that can be configured via
-'''.IR yp.conf .
.TP
.IR anonuid " and " anongid
These options explicitly set the uid and gid of the anonymous account.
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
#include "gss_util.h"
#include "krb5_util.h"
-char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
+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;
int use_memcache = 0;
+int root_uses_machine_creds = 1;
void
sig_die(int signal)
{
/* destroy krb5 machine creds */
- gssd_destroy_krb5_machine_creds();
+ if (root_uses_machine_creds)
+ gssd_destroy_krb5_machine_creds();
printerr(1, "exiting on signal %d\n", signal);
exit(1);
}
static void
usage(char *progname)
{
- fprintf(stderr, "usage: %s [-f] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
+ fprintf(stderr, "usage: %s [-f] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
progname);
exit(1);
}
extern char *optarg;
char *progname;
- while ((opt = getopt(argc, argv, "fvrmMp:k:d:")) != -1) {
+ while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) {
switch (opt) {
case 'f':
fg = 1;
case 'M':
use_memcache = 1;
break;
+ case 'n':
+ root_uses_machine_creds = 0;
+ break;
case 'v':
verbosity++;
break;
rpc_verbosity++;
break;
case 'p':
- strncpy(pipefsdir, optarg, sizeof(pipefsdir));
- if (pipefsdir[sizeof(pipefsdir)-1] != '\0')
+ strncpy(pipefs_dir, optarg, sizeof(pipefs_dir));
+ if (pipefs_dir[sizeof(pipefs_dir)-1] != '\0')
errx(1, "pipefs path name too long");
break;
case 'k':
break;
}
}
- strncat(pipefsdir + strlen(pipefsdir), "/" GSSD_SERVICE_NAME,
- sizeof(pipefsdir)-strlen(pipefsdir));
- if (pipefsdir[sizeof(pipefsdir)-1] != '\0')
- errx(1, "pipefs path name too long");
+ snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s",
+ pipefs_dir, GSSD_SERVICE_NAME);
+ if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
+ errx(1, "pipefs_nfsdir path name too long");
if ((progname = strrchr(argv[0], '/')))
progname++;
signal(SIGHUP, sig_hup);
/* Process keytab file and get machine credentials */
- gssd_refresh_krb5_machine_creds();
+ if (root_uses_machine_creds)
+ gssd_refresh_krb5_machine_creds();
gssd_run();
printerr(0, "gssd_run returned!\n");
-extern char pipefsdir[PATH_MAX];
+extern char pipefs_dir[PATH_MAX];
+extern char pipefs_nfsdir[PATH_MAX];
extern char keytabfile[PATH_MAX];
extern char ccachedir[PATH_MAX];
extern int use_memcache;
+extern int root_uses_machine_creds;
TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list;
.\" rpc.gssd(8)
.\"
.\" Copyright (C) 2003 J. Bruce Fields <bfields@umich.edu>
-.TH rpc.gssd 8 "17 Mar 2003"
+.TH rpc.gssd 8 "14 Mar 2007"
.SH NAME
rpc.gssd \- rpcsec_gss daemon
.SH SYNOPSIS
-.B "rpc.gssd [-f] [-k keytab] [-p pipefsdir] [-v] [-r] [-d ccachedir]"
+.B "rpc.gssd [-f] [-n] [-k keytab] [-p pipefsdir] [-v] [-r] [-d ccachedir]"
.SH DESCRIPTION
The rpcsec_gss protocol gives a means of using the gss-api generic security
api to provide security for protocols using rpc (in particular, nfs). Before
.B rpc.gssd
in the foreground and sends output to stderr (as opposed to syslogd)
.TP
+.B -n
+By default,
+.B rpc.gssd
+treats accesses by the user with UID 0 specially, and uses
+"machine credentials" for all accesses by that user which
+require Kerberos authentication.
+With the \-n option, "machine credentials" will not be used
+for accesses by UID 0. Instead, credentials must be obtained
+manually like all other users. Use of this option means that
+"root" must manually obtain Kerberos credentials before
+attemtpting to mount an nfs filesystem requiring Kerberos
+authentication.
+.TP
.B -k keytab
Tells
.B rpc.gssd
-to use the keys for principals nfs/hostname in
+to use the keys found in
.I keytab
-to obtain machine credentials.
+to obtain "machine credentials".
The default value is "/etc/krb5.keytab".
-.\".TP
-.\".B -m
-.\"Ordinarily,
-.\".B rpc.gssd
-.\"looks for a cached ticket for user $UID in /tmp/krb5cc_$UID.
-.\"With the -m option, the user with uid 0 will be treated specially, and will
-.\"be mapped instead to the credentials for the principal nfs/hostname found in
-.\"the keytab file.
-.\"(This option is now the default and is ignored if specified.)
+Previous versions of
+.B rpc.gssd
+used only "nfs/*" keys found within the keytab.
+Now, the first keytab entry for each distinct Kerberos realm
+within the keytab is used. This means that an NFS client
+no longer needs an "nfs/hostname" principal and keytab entry,
+but can instead use a "host/hostname" (or any other) keytab
+entry that is available.
.TP
.B -p path
Tells
dn_act.sa_flags = SA_SIGINFO;
sigaction(DNOTIFY_SIGNAL, &dn_act, NULL);
- if ((fd = open(pipefsdir, O_RDONLY)) == -1) {
+ if ((fd = open(pipefs_nfsdir, O_RDONLY)) == -1) {
printerr(0, "ERROR: failed to open %s: %s\n",
- pipefsdir, strerror(errno));
+ pipefs_nfsdir, strerror(errno));
exit(1);
}
fcntl(fd, F_SETSIG, DNOTIFY_SIGNAL);
* with an index into pollarray[], and other basic data about that client.
*
* Directory structure: created by the kernel nfs client
- * /pipefsdir/clntXX : one per rpc_clnt struct in the kernel
- * /pipefsdir/clntXX/krb5 : read uid for which kernel wants
- * a context, write the resulting context
- * /pipefsdir/clntXX/info : stores info such as server name
+ * {pipefs_nfsdir}/clntXX : one per rpc_clnt struct in the kernel
+ * {pipefs_nfsdir}/clntXX/krb5 : read uid for which kernel wants
+ * a context, write the resulting context
+ * {pipefs_nfsdir}/clntXX/info : stores info such as server name
*
* Algorithm:
- * Poll all /pipefsdir/clntXX/krb5 files. When ready, data read
+ * Poll all {pipefs_nfsdir}/clntXX/krb5 files. When ready, data read
* is a uid; performs rpcsec_gss context initialization protocol to
* get a cred for that user. Writes result to corresponding krb5 file
* in a form the kernel code will understand.
* In addition, we make sure we are notified whenever anything is
- * created or destroyed in pipefsdir/ or in an of the clntXX directories,
- * and rescan the whole pipefsdir when this happens.
+ * created or destroyed in {pipefs_nfsdir} or in an of the clntXX directories,
+ * and rescan the whole {pipefs_nfsdir} when this happens.
*/
struct pollfd * pollarray;
struct dirent **namelist;
int i, j;
- if (chdir(pipefsdir) < 0) {
+ if (chdir(pipefs_nfsdir) < 0) {
printerr(0, "ERROR: can't chdir to %s: %s\n",
- pipefsdir, strerror(errno));
+ pipefs_nfsdir, strerror(errno));
return -1;
}
- j = scandir(pipefsdir, &namelist, NULL, alphasort);
+ j = scandir(pipefs_nfsdir, &namelist, NULL, alphasort);
if (j < 0) {
printerr(0, "ERROR: can't scandir %s: %s\n",
- pipefsdir, strerror(errno));
+ pipefs_nfsdir, strerror(errno));
return -1;
}
update_old_clients(namelist, j);
gss_buffer_desc token;
char **credlist = NULL;
char **ccname;
+ int create_resp = -1;
printerr(1, "handling krb5 upcall\n");
goto out;
}
- if (uid == 0) {
- int success = 0;
-
- /*
- * Get a list of credential cache names and try each
- * of them until one works or we've tried them all
- */
- if (gssd_get_krb5_machine_cred_list(&credlist)) {
- printerr(0, "WARNING: Failed to obtain machine "
- "credentials for connection to "
- "server %s\n", clp->servername);
- goto out_return_error;
- }
- for (ccname = credlist; ccname && *ccname; ccname++) {
- gssd_setup_krb5_machine_gss_ccache(*ccname);
- if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5)) == 0) {
- /* Success! */
- success++;
- break;
- }
- printerr(2, "WARNING: Failed to create krb5 context "
- "for user with uid %d with credentials "
- "cache %s for server %s\n",
- uid, *ccname, clp->servername);
- }
- gssd_free_krb5_machine_cred_list(credlist);
- if (!success) {
- printerr(0, "WARNING: Failed to create krb5 context "
- "for user with uid %d with any "
- "credentials cache for server %s\n",
- uid, clp->servername);
- goto out_return_error;
- }
- }
- else {
+ 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);
- if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
- AUTHTYPE_KRB5)) != 0) {
+ create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
+ AUTHTYPE_KRB5);
+ }
+ if (create_resp != 0) {
+ if (uid == 0 && root_uses_machine_creds == 1) {
+ int success = 0;
+
+ /*
+ * Get a list of credential cache names and try each
+ * of them until one works or we've tried them all
+ */
+ if (gssd_get_krb5_machine_cred_list(&credlist)) {
+ printerr(0, "WARNING: Failed to obtain machine "
+ "credentials for connection to "
+ "server %s\n", clp->servername);
+ goto out_return_error;
+ }
+ for (ccname = credlist; ccname && *ccname; ccname++) {
+ gssd_setup_krb5_machine_gss_ccache(*ccname);
+ if ((create_auth_rpc_client(clp, &rpc_clnt,
+ &auth, uid,
+ AUTHTYPE_KRB5)) == 0) {
+ /* Success! */
+ success++;
+ break;
+ }
+ printerr(2, "WARNING: Failed to create krb5 context "
+ "for user with uid %d with credentials "
+ "cache %s for server %s\n",
+ uid, *ccname, clp->servername);
+ }
+ gssd_free_krb5_machine_cred_list(credlist);
+ if (!success) {
+ printerr(0, "WARNING: Failed to create krb5 context "
+ "for user with uid %d with any "
+ "credentials cache for server %s\n",
+ uid, clp->servername);
+ goto out_return_error;
+ }
+ } else {
printerr(0, "WARNING: Failed to create krb5 context "
- "for user with uid %d for server %s\n",
+ "for user with uid %d for server %s\n",
uid, clp->servername);
goto out_return_error;
}
namelist[i]->d_name);
snprintf(statname, sizeof(statname),
"%s/%s", ccachedir, namelist[i]->d_name);
- if (stat(statname, &tmp_stat)) {
+ if (lstat(statname, &tmp_stat)) {
printerr(0, "Error doing stat on file '%s'\n",
statname);
free(namelist[i]);
/*
* Process the given keytab file and create a list of principals we
- * might use to perform mount operations.
+ * might use as machine credentials.
*
* Returns:
* 0 => Sucess
/*
* Look through each entry in the keytab file and determine
- * if we might want to use it later to do a mount. If so,
- * save info in the global principal list
- * (gssd_k5_kt_princ_list).
+ * if we might want to use it as machine credentials. If so,
+ * save info in the global principal list (gssd_k5_kt_princ_list).
* Note: (ple == principal list entry)
*/
if ((code = krb5_kt_start_seq_get(context, kt, &cursor))) {
printerr(0, "WARNING: Skipping keytab entry because "
"we failed to unparse principal name: %s\n",
error_message(code));
+ krb5_kt_free_entry(context, &kte);
continue;
}
printerr(2, "Processing keytab entry for principal '%s'\n",
pname);
-#ifdef HAVE_KRB5
- if ( (kte.principal->data[0].length == GSSD_SERVICE_NAME_LEN) &&
- (strncmp(kte.principal->data[0].data, GSSD_SERVICE_NAME,
- GSSD_SERVICE_NAME_LEN) == 0) &&
-#else
- if ( (strlen(kte.principal->name.name_string.val[0]) == GSSD_SERVICE_NAME_LEN) &&
- (strncmp(kte.principal->name.name_string.val[0], GSSD_SERVICE_NAME,
- GSSD_SERVICE_NAME_LEN) == 0) &&
-
-#endif
- (!gssd_have_realm_ple((void *)&kte.principal->realm)) ) {
- printerr(2, "We will use this entry (%s)\n", pname);
+ /* Just use the first keytab entry found for each realm */
+ if ((!gssd_have_realm_ple((void *)&kte.principal->realm)) ) {
+ printerr(2, "We WILL use this entry (%s)\n", pname);
ple = malloc(sizeof(struct gssd_k5_kt_princ));
if (ple == NULL) {
printerr(0, "ERROR: could not allocate storage "
#else
free(pname);
#endif
+ krb5_kt_free_entry(context, &kte);
retval = ENOMEM;
goto out;
}
#else
free(pname);
#endif
+ krb5_kt_free_entry(context, &kte);
retval = ENOMEM;
goto out;
}
#else
free(pname);
#endif
+ krb5_kt_free_entry(context, &kte);
retval = code;
goto out;
}
#else
free(pname);
#endif
+ krb5_kt_free_entry(context, &kte);
}
if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) {
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
+++ /dev/null
-## Process this file with automake to produce Makefile.in
-
-man8_MANS = lockd.man
-EXTRA_DIST = $(man8_MANS)
-
-RPCPREFIX = rpc.
-KPREFIX = @kprefix@
-sbin_PROGRAMS = lockd
-lockd_SOURCES = lockd.c
-lockd_LDADD = ../../support/export/libexport.a \
- ../../support/nfs/libnfs.a \
- ../../support/misc/libmisc.a
-
-MAINTAINERCLEANFILES = Makefile.in
-
-#######################################################################
-# The following allows the current practice of having
-# daemons renamed during the install to include RPCPREFIX
-# and the KPREFIX
-# This could all be done much easier with program_transform_name
-# ( program_transform_name = s/^/$(RPCPREFIX)$(KPREFIX)/ )
-# but that also renames the man pages, which the current
-# practice does not do.
-install-exec-hook:
- (cd $(DESTDIR)$(sbindir) && \
- for p in $(sbin_PROGRAMS); do \
- mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
- done)
-uninstall-hook:
- (cd $(DESTDIR)$(sbindir) && \
- for p in $(sbin_PROGRAMS); do \
- rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
- done)
-
-
-# XXX This makes some assumptions about what automake does.
-# XXX But there is no install-man-hook or install-man-local.
-install-man: install-man8 install-man-links
-uninstall-man: uninstall-man8 uninstall-man-links
-
-install-man-links:
- (cd $(DESTDIR)$(man8dir) && \
- for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \
- inst=`echo $$m | sed -e 's/man$$/8/'`; \
- rm -f $(RPCPREFIX)$$inst ; \
- $(LN_S) $$inst $(RPCPREFIX)$$inst ; \
- done)
-
-uninstall-man-links:
- (cd $(DESTDIR)$(man8dir) && \
- for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \
- inst=`echo $$m | sed -e 's/man$$/8/'`; \
- rm -f $(RPCPREFIX)$$inst ; \
- done)
-
+++ /dev/null
-/*
- * lockd
- *
- * This is the user level part of lockd. This is very primitive, because
- * all the work is now done in the kernel module.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <nfslib.h>
-
-
-
-static void usage(const char *);
-
-int
-main(int argc, char **argv)
-{
- int error;
-
- if (argc > 1)
- usage (argv [0]);
-
- if (chdir(NFS_STATEDIR)) {
- fprintf(stderr, "%s: chdir(%s) failed: %s\n",
- argv [0], NFS_STATEDIR, strerror(errno));
- exit(1);
- }
-
- if ((error = lockdsvc()) < 0) {
- if (errno == EINVAL)
- /* Ignore EINVAL since kernel may start
- lockd automatically. */
- error = 0;
- else
- perror("lockdsvc");
- }
-
- return (error != 0);
-}
-
-static void
-usage(const char *prog)
-{
- fprintf(stderr, "usage:\n%s\n", prog);
- exit(2);
-}
+++ /dev/null
-.\"
-.\" lockd(8)
-.\"
-.\" Copyright (C) 2000 Chip Salzenberg <chip@debian.org>
-.\"
-.TH rpc.lockd 8 "25 Feb 2000"
-.SH NAME
-rpc.lockd \- start kernel lockd process
-.SH SYNOPSIS
-.B "rpc.lockd
-.SH DESCRIPTION
-The
-.B rpc.lockd
-program starts the NFS lock manager (NLM) on kernels that don't start
-it automatically. However, since most kernels \fIdo\fR start it
-automatically,
-.BR rpc.lockd .
-is usually not required. Even so, running it anyway is harmless.
-.SH SEE ALSO
-.BR rpc.statd (8),
-.BR rpc.nfsd (8)
-.SH AUTHORS
-.br
-H.J. Lu <hjl@valinux.com>
## Process this file with automake to produce Makefile.in
+# These binaries go in /sbin (not /usr/sbin), and that cannot be
+# overriden at config time.
+sbindir = /sbin
+
man8_MANS = mount.nfs.man umount.nfs.man
+man5_MANS = nfs.man
sbin_PROGRAMS = mount.nfs
-EXTRA_DIST = nfsmount.x $(man8_MANS)
+EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS)
mount_nfs_SOURCES = mount.c nfsmount.c nfs4mount.c nfsumount.c \
mount_constants.h nfs4_mount.h nfs_mount4.h
install-exec-hook:
(cd $(DESTDIR)$(sbindir) && \
- ln -sf $(sbin_PROGRAMS) mount.nfs4 && \
- ln -sf $(sbin_PROGRAMS) umount.nfs && \
- ln -sf $(sbin_PROGRAMS) umount.nfs4)
+ ln -sf mount.nfs mount.nfs4 && \
+ ln -sf mount.nfs umount.nfs && \
+ ln -sf mount.nfs umount.nfs4 && \
+ chmod 4511 mount.nfs )
uninstall-hook:
(cd $(DESTDIR)$(sbindir) && \
rm -f mount.nfs4 umount.nfs umount.nfs4)
inst=`echo $$m | sed -e 's/man$$/8/'`; \
rm -f $$inst ; \
done)
+ (cd $(DESTDIR)$(man5dir) && \
+ for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+ inst=`echo $$m | sed -e 's/man$$/5/'`; \
+ rm -f $$inst ; \
+ done)
uninstall-man-links:
(cd $(DESTDIR)$(man8dir) && \
inst=`echo $$m | sed -e 's/man$$/8/'`; \
rm -f $$inst ; \
done)
+ (cd $(DESTDIR)$(man5dir) && \
+ for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+ inst=`echo $$m | sed -e 's/man$$/5/'`; \
+ rm -f $$inst ; \
+ done)
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/support/include/config.h
CONFIG_CLEAN_FILES =
-am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
am_mount_nfs_OBJECTS = mount.$(OBJEXT) nfsmount.$(OBJEXT) \
$(LDFLAGS) -o $@
SOURCES = $(mount_nfs_SOURCES)
DIST_SOURCES = $(mount_nfs_SOURCES)
+man5dir = $(mandir)/man5
man8dir = $(mandir)/man8
NROFF = nroff
-MANS = $(man8_MANS)
+MANS = $(man5_MANS) $(man8_MANS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-sbindir = @sbindir@
+
+# These binaries go in /sbin (not /usr/sbin), and that cannot be
+# overriden at config time.
+sbindir = /sbin
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
man8_MANS = mount.nfs.man umount.nfs.man
-EXTRA_DIST = nfsmount.x $(man8_MANS)
+man5_MANS = nfs.man
+EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS)
mount_nfs_SOURCES = mount.c nfsmount.c nfs4mount.c nfsumount.c \
mount_constants.h nfs4_mount.h nfs_mount4.h
clean-libtool:
-rm -rf .libs _libs
+install-man5: $(man5_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)"
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
install-man8: $(man8_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
check: check-am
all-am: Makefile $(PROGRAMS) $(MANS)
installdirs:
- for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-info: install-info-am
-install-man: install-man8
+install-man: install-man5 install-man8
install-pdf: install-pdf-am
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
-uninstall-man: uninstall-man8
+uninstall-man: uninstall-man5 uninstall-man8
.MAKE: install-am install-exec-am install-strip uninstall-am
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-exec-hook \
install-html install-html-am install-info install-info-am \
- install-man install-man8 install-pdf install-pdf-am install-ps \
- install-ps-am install-sbinPROGRAMS install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-hook uninstall-man \
- uninstall-man8 uninstall-sbinPROGRAMS
+ install-man install-man5 install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am uninstall-hook \
+ uninstall-man uninstall-man5 uninstall-man8 \
+ uninstall-sbinPROGRAMS
install-exec-hook:
(cd $(DESTDIR)$(sbindir) && \
- ln -sf $(sbin_PROGRAMS) mount.nfs4 && \
- ln -sf $(sbin_PROGRAMS) umount.nfs && \
- ln -sf $(sbin_PROGRAMS) umount.nfs4)
+ ln -sf mount.nfs mount.nfs4 && \
+ ln -sf mount.nfs umount.nfs && \
+ ln -sf mount.nfs umount.nfs4 && \
+ chmod 4511 mount.nfs )
uninstall-hook:
(cd $(DESTDIR)$(sbindir) && \
rm -f mount.nfs4 umount.nfs umount.nfs4)
inst=`echo $$m | sed -e 's/man$$/8/'`; \
rm -f $$inst ; \
done)
+ (cd $(DESTDIR)$(man5dir) && \
+ for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+ inst=`echo $$m | sed -e 's/man$$/5/'`; \
+ rm -f $$inst ; \
+ done)
uninstall-man-links:
(cd $(DESTDIR)$(man8dir) && \
inst=`echo $$m | sed -e 's/man$$/8/'`; \
rm -f $$inst ; \
done)
+ (cd $(DESTDIR)$(man5dir) && \
+ for m in $(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS); do \
+ inst=`echo $$m | sed -e 's/man$$/5/'`; \
+ rm -f $$inst ; \
+ done)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#include <sys/mount.h>
#include <getopt.h>
#include <mntent.h>
+#include <pwd.h>
#include "fstab.h"
#include "xcommon.h"
int nomtab;
int verbose;
int mounttype;
+int sloppy;
static struct option longopts[] = {
{ "fake", 0, 0, 'f' },
int mask; /* flag mask value */
};
+/* Custom mount options for our own purposes. */
+#define MS_DUMMY 0x00000000
+#define MS_USERS 0x40000000
+#define MS_USER 0x80000000
+
static const struct opt_map opt_map[] = {
{ "defaults", 0, 0, 0 }, /* default options */
{ "ro", 1, 0, MS_RDONLY }, /* read-only */
{ "remount", 0, 0, MS_REMOUNT}, /* Alter flags of mounted FS */
{ "bind", 0, 0, MS_BIND }, /* Remount part of tree elsewhere */
{ "rbind", 0, 0, MS_BIND|MS_REC }, /* Idem, plus mounted subtrees */
+ { "auto", 0, 0, MS_DUMMY }, /* Can be mounted using -a */
+ { "noauto", 0, 0, MS_DUMMY }, /* Can only be mounted explicitly */
+ { "users", 1, 0, MS_USERS }, /* Allow ordinary user to mount */
+ { "nousers", 0, 1, MS_DUMMY }, /* Forbid ordinary user to mount */
+ { "user", 1, 0, MS_USER }, /* Allow ordinary user to mount */
+ { "nouser", 0, 1, MS_DUMMY }, /* Forbid ordinary user to mount */
+ { "owner", 0, 0, MS_DUMMY }, /* Let the owner of the device mount */
+ { "noowner", 0, 0, MS_DUMMY }, /* Device owner has no special privs */
+ { "group", 0, 0, MS_DUMMY }, /* Let the group of the device mount */
+ { "nogroup", 0, 0, MS_DUMMY }, /* Device group has no special privs */
+ { "_netdev", 0, 0, MS_DUMMY}, /* Device requires network */
+ { "comment", 0, 0, MS_DUMMY}, /* fstab comment only (kudzu,_netdev)*/
/* add new options here */
#ifdef MS_NOSUB
{ "mand", 0, 0, MS_MANDLOCK }, /* Allow mandatory locks on this FS */
{ "nomand", 0, 1, MS_MANDLOCK }, /* Forbid mandatory locks on this FS */
#endif
+ { "loop", 1, 0, MS_DUMMY }, /* use a loop device */
#ifdef MS_NOATIME
{ "atime", 0, 1, MS_NOATIME }, /* Update access time */
{ "noatime", 0, 0, MS_NOATIME }, /* Do not update access time */
char *new_opts;
new_opts = xstrdup((flags & MS_RDONLY) ? "ro" : "rw");
+ if (flags & MS_USER) {
+ /* record who mounted this so they can unmount */
+ struct passwd *pw = getpwuid(getuid());
+ if(pw)
+ new_opts = xstrconcat3(new_opts, ",user=", pw->pw_name);
+ }
+ if (flags & MS_USERS)
+ new_opts = xstrconcat3(new_opts, ",users", "");
+
for (om = opt_map; om->opt != NULL; om++) {
if (om->skip)
continue;
int add_mtab(char *fsname, char *mount_point, char *fstype, int flags, char *opts, int freq, int passno)
{
struct mntent ment;
- int fd;
FILE *mtab;
ment.mnt_fsname = fsname;
ment.mnt_freq = 0;
ment.mnt_passno= 0;
+ if(flags & MS_REMOUNT) {
+ update_mtab(ment.mnt_dir, &ment);
+ return 0;
+ }
+
lock_mtab();
if ((mtab = setmntent(MOUNTED, "a+")) == NULL) {
printf("\t-w\t\tMount file system read-write\n");
printf("\t-f\t\tFake mount, don't actually mount\n");
printf("\t-n\t\tDo not update /etc/mtab\n");
+ printf("\t-s\t\tTolerate sloppy mount options rather than failing.\n");
printf("\t-h\t\tPrint this help\n");
printf("\tversion\t\tnfs4 - NFS version 4, nfs - older NFS version supported\n");
printf("\tnfsoptions\tRefer mount.nfs(8) or nfs(5)\n\n");
{
if (options != NULL) {
char *opts = xstrdup(options);
- char *opt;
- int len = strlen(opts) + 20;
+ char *opt, *p;
+ int len = strlen(opts) + 1; /* include room for a null */
+ int open_quote = 0;
*extra_opts = xmalloc(len);
**extra_opts = '\0';
- for (opt = strtok(opts, ","); opt; opt = strtok(NULL, ","))
- parse_opt(opt, flags, *extra_opts, len);
-
+ for (p=opts, opt=NULL; p && *p; p++) {
+ if (!opt)
+ opt = p; /* begin of the option item */
+ if (*p == '"')
+ open_quote ^= 1; /* reverse the status */
+ if (open_quote)
+ continue; /* still in a quoted block */
+ if (*p == ',')
+ *p = '\0'; /* terminate the option item */
+ /* end of option item or last item */
+ if (*p == '\0' || *(p+1) == '\0') {
+ parse_opt(opt, flags, *extra_opts, len);
+ opt = NULL;
+ }
+ }
free(opts);
}
-
}
static void mount_error(char *node)
{
switch(errno) {
case ENOTDIR:
- printf("%s: mount point %s is not a directory\n", progname, node);
+ fprintf(stderr, "%s: mount point %s is not a directory\n", progname, node);
break;
case EBUSY:
- printf("%s: %s is already mounted or busy\n", progname, node);
+ fprintf(stderr, "%s: %s is already mounted or busy\n", progname, node);
break;
case ENOENT:
- printf("%s: mount point %s does not exist\n", progname, node);
+ fprintf(stderr, "%s: mount point %s does not exist\n", progname, node);
break;
default:
- printf("%s: %s\n", progname, strerror(errno));
+ fprintf(stderr, "%s: %s\n", progname, strerror(errno));
}
}
+extern u_short getport(
+ struct sockaddr_in *saddr,
+ u_long prog,
+ u_long vers,
+ u_int prot);
+
+static int probe_statd()
+{
+ struct sockaddr_in addr;
+ u_short port;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ port = getport(&addr, 100024, 1, IPPROTO_UDP);
+
+ if (port == 0)
+ return 0;
+ addr.sin_port = htons(port);
+
+ if (clnt_ping(&addr, 100024, 1, IPPROTO_UDP, NULL) <= 0)
+ return 0;
+
+ return 1;
+}
+
+static int start_statd()
+{
+ /* If /var/run/rpc.statd.pid exists and is non-empty,
+ * assume statd already running.
+ * If START_STATD not defined, or defined to a non-existent file,
+ * don't bother,
+ * else run that file (typically a shell script)
+ */
+ struct stat stb;
+
+ if (probe_statd())
+ return 1;
+#ifdef START_STATD
+ if (stat(START_STATD, &stb) ==0 &&
+ S_ISREG(stb.st_mode) &&
+ (stb.st_mode & S_IXUSR)) {
+ system(START_STATD);
+ if (probe_statd())
+ return 1;
+ }
+#endif
+ return 0;
+}
+
int main(int argc, char *argv[])
{
int c, flags = 0, nfs_mount_vers = 0, mnt_err = 1, fake = 0;
char *spec, *mount_point, *extra_opts = NULL;
char *mount_opts = NULL, *p;
+ uid_t uid = getuid();
progname = argv[0];
+ if (!progname)
+ exit(2);
+
if ((p = strrchr(progname, '/')) != NULL)
progname = p+1;
- if (getuid() != 0) {
- printf("%s: only root can do that.\n", progname);
- exit(1);
- }
-
if(!strncmp(progname, "umount", strlen("umount"))) {
if(argc < 2) {
umount_usage();
exit(1);
}
- return(nfsumount(argc, argv));
+ exit(nfsumount(argc, argv) ? 0 : 1);
}
- if ((argc < 2)) {
- mount_usage();
- exit(1);
- }
-
- if(argv[1][0] == '-') {
+ if(argv[1] && argv[1][0] == '-') {
if(argv[1][1] == 'V')
printf("%s ("PACKAGE_STRING")\n", progname);
else
return 0;
}
- while ((c = getopt_long (argc - 2, argv + 2, "rt:vVwfno:h",
+ if ((argc < 3)) {
+ mount_usage();
+ exit(1);
+ }
+
+ spec = argv[1];
+ mount_point = argv[2];
+
+ argv[2] = argv[0]; /* so that getopt error messages are correct */
+ while ((c = getopt_long (argc - 2, argv + 2, "rt:vVwfno:hs",
longopts, NULL)) != -1) {
switch (c) {
case 'r':
flags |= MS_RDONLY;
break;
case 't':
- nfs_mount_vers = (strncmp(optarg, "nfs4", 4)) ? 0 : 4;
+ if (strcmp(optarg, "nfs4") == 0)
+ nfs_mount_vers = 4;
+ else if (strcmp(optarg, "nfs") == 0)
+ nfs_mount_vers = 0;
+ else {
+ fprintf(stderr, "%s: unknown filesystem type: %s\n",
+ progname, optarg);
+ exit(1);
+ }
break;
case 'v':
++verbose;
else
mount_opts = xstrdup(optarg);
break;
+ case 's':
+ ++sloppy;
+ break;
case 128: /* bind */
mounttype = MS_BIND;
break;
exit(1);
}
}
+ if (optind != argc-2) {
+ /* Extra non-option words at the end... */
+ mount_usage();
+ exit(1);
+ }
- spec = argv[1];
- mount_point = canonicalize(argv[2]);
+ if (strcmp(progname, "mount.nfs4") == 0)
+ nfs_mount_vers = 4;
+
+ if (uid != 0) {
+ /* don't even think about it unless options exactly
+ * match fstab
+ */
+ struct mntentchn *mc;
+
+ if ((mc = getfsfile(mount_point)) == NULL ||
+ strcmp(mc->m.mnt_fsname, spec) != 0 ||
+ strcmp(mc->m.mnt_type, (nfs_mount_vers == 4 ? "nfs4":"nfs")) != 0
+ ) {
+ fprintf(stderr, "%s: permission died - no match for fstab\n",
+ progname);
+ exit(1);
+ }
+ /* 'mount' munges the options from fstab before passing them
+ * to us, so it is non-trivial to test that we have the correct
+ * set of options and we don't want to trust what the user
+ * gave us, so just take whatever is in fstab
+ */
+ mount_opts = strdup(mc->m.mnt_opts);
+ mounttype = 0;
+ }
+
+ mount_point = canonicalize(mount_point);
+ if (mount_point == NULL ||
+ mount_point[0] != '/') {
+ fprintf(stderr, "%s: unknown mount point %s\n",
+ progname, mount_point ? : "");
+ exit(1);
+ }
parse_opts(mount_opts, &flags, &extra_opts);
- if (!strcmp(progname, "mount.nfs4") || nfs_mount_vers == 4) {
- nfs_mount_vers = 4;
- mnt_err = nfs4mount(spec, mount_point, &flags, &extra_opts, &mount_opts, 0);
+ if (uid != 0) {
+ if (! (flags & (MS_USERS | MS_USER))) {
+ fprintf(stderr, "%s: permission denied\n", progname);
+ exit(1);
+ }
}
+
+ if (nfs_mount_vers == 4)
+ mnt_err = nfs4mount(spec, mount_point, &flags, &extra_opts, &mount_opts, 0);
else {
- if (!strcmp(progname, "mount.nfs")) {
- mnt_err = nfsmount(spec, mount_point, &flags,
- &extra_opts, &mount_opts, &nfs_mount_vers, 0);
+ int need_statd = 0;
+ mnt_err = nfsmount(spec, mount_point, &flags,
+ &extra_opts, &mount_opts,
+ 0, &need_statd);
+ if (!mnt_err && !fake && need_statd) {
+ if (!start_statd()) {
+ fprintf(stderr,
+ "%s: rpc.statd is not running but is "
+ "required for remote locking\n"
+ " Either use \"-o nolocks\" to keep "
+ "locks local, or start statd.\n",
+ progname);
+ exit(1);
+ }
}
}
- if (!mnt_err && !fake) {
- mnt_err = do_mount_syscall(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs", flags, mount_opts);
-
- if(mnt_err) {
+ if (mnt_err)
+ exit(EX_FAIL);
+
+ if (!fake) {
+ mnt_err = do_mount_syscall(spec, mount_point,
+ nfs_mount_vers == 4 ? "nfs4" : "nfs",
+ flags & ~(MS_USER|MS_USERS) ,
+ mount_opts);
+
+ if (mnt_err) {
mount_error(mount_point);
- exit(-1);
+ exit(EX_FAIL);
}
-
- if(!nomtab)
- add_mtab(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs",
- flags, extra_opts, 0, 0);
}
+ if (!nomtab)
+ add_mtab(spec, mount_point,
+ nfs_mount_vers == 4 ? "nfs4" : "nfs",
+ flags, extra_opts, 0, 0);
+
return 0;
}
--- /dev/null
+.\" nfs.5 "Rick Sladkey" <jrs@world.std.com>
+.\" Wed Feb 8 12:52:42 1995, faith@cs.unc.edu: updates for Ross Biro's
+.\" patches. "
+.TH NFS 5 "20 November 1993" "Linux 0.99" "Linux Programmer's Manual"
+.SH NAME
+nfs \- nfs and nfs4 fstab format and options
+.SH SYNOPSIS
+.B /etc/fstab
+.SH DESCRIPTION
+The
+.I fstab
+file contains information about which filesystems
+to mount where and with what options.
+For NFS mounts, it contains the server name and
+exported server directory to mount from,
+the local directory that is the mount point,
+and the NFS specific options that control
+the way the filesystem is mounted.
+.P
+Three different versions of the NFS protocol are
+supported by the Linux NFS client:
+NFS version 2, NFS version 3, and NFS version 4.
+To mount via NFS version 2, use the
+.BR nfs
+file system type and specify
+.BR nfsvers=2 .
+To mount via NFS version 3, use the
+.BR nfs
+file system type and specify
+.BR nfsvers=3 .
+Version 3 is the default protocol version for the
+.BR nfs
+file system type when
+.BR nfsvers=
+is not specified on the mount command and both client and server
+support it.
+To mount via NFS version 4, use the
+.BR nfs4
+file system type.
+The
+.BR nfsvers=
+keyword is not supported for the
+.BR nfs4
+file system type.
+.P
+These file system types share similar mount options;
+the differences are listed below.
+.P
+Here is an example from an \fI/etc/fstab\fP file for an NFSv3 mount
+over TCP.
+.sp
+.nf
+.ta 2.5i +0.75i +0.75i +1.0i
+server:/usr/local/pub /pub nfs rsize=32768,wsize=32768,timeo=14,intr
+.fi
+.P
+Here is an example for an NFSv4 mount over TCP using Kerberos
+5 mutual authentication.
+.sp
+.nf
+.ta 2.5i +0.75i +0.75i +1.0i
+server:/usr/local/pub /pub nfs4 proto=tcp,sec=krb5,hard,intr
+.fi
+.DT
+.SS Options for the nfs file system type
+.TP 1.5i
+.I rsize=n
+The number of bytes NFS uses when reading files from an NFS server.
+The rsize is negotiated between the server and client to determine
+the largest block size that both can support.
+The value specified by this option is the maximum size that could
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I wsize=n
+The number of bytes NFS uses when writing files to an NFS server.
+The wsize is negotiated between the server and client to determine
+the largest block size that both can support.
+The value specified by this option is the maximum size that could
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I timeo=n
+The value in tenths of a second before sending the
+first retransmission after an RPC timeout.
+The default value is 7 tenths of a second. After the first timeout,
+the timeout is doubled after each successive timeout until a maximum
+timeout of 60 seconds is reached or the enough retransmissions
+have occured to cause a major timeout. Then, if the filesystem
+is hard mounted, each new timeout cascade restarts at twice the
+initial value of the previous cascade, again doubling at each
+retransmission. The maximum timeout is always 60 seconds.
+Better overall performance may be achieved by increasing the
+timeout when mounting on a busy network, to a slow server, or through
+several routers or gateways.
+.TP 1.5i
+.I retrans=n
+The number of minor timeouts and retransmissions that must occur before
+a major timeout occurs. The default is 3 timeouts. When a major timeout
+occurs, the file operation is either aborted or a "server not responding"
+message is printed on the console.
+.TP 1.5i
+.I acregmin=n
+The minimum time in seconds that attributes of a regular file should
+be cached before requesting fresh information from a server.
+The default is 3 seconds.
+.TP 1.5i
+.I acregmax=n
+The maximum time in seconds that attributes of a regular file can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I acdirmin=n
+The minimum time in seconds that attributes of a directory should
+be cached before requesting fresh information from a server.
+The default is 30 seconds.
+.TP 1.5i
+.I acdirmax=n
+The maximum time in seconds that attributes of a directory can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I actimeo=n
+Using actimeo sets all of
+.I acregmin,
+.I acregmax,
+.I acdirmin,
+and
+.I acdirmax
+to the same value.
+There is no default value.
+.TP 1.5i
+.I retry=n
+The number of minutes to retry an NFS mount operation
+in the foreground or background before giving up.
+The default value for forground mounts is 2 minutes.
+The default value for background mounts is 10000 minutes,
+which is roughly one week.
+.TP 1.5i
+.I namlen=n
+When an NFS server does not support version two of the
+RPC mount protocol, this option can be used to specify
+the maximum length of a filename that is supported on
+the remote filesystem. This is used to support the
+POSIX pathconf functions. The default is 255 characters.
+.TP 1.5i
+.I port=n
+The numeric value of the port to connect to the NFS server on.
+If the port number is 0 (the default) then query the
+remote host's portmapper for the port number to use.
+If the remote host's NFS daemon is not registered with
+its portmapper, the standard NFS port number 2049 is
+used instead.
+.TP 1.5i
+.I mountport=n
+The numeric value of the
+.B mountd
+port.
+.TP 1.5i
+.I mounthost=name
+The name of the host running
+.B mountd .
+.TP 1.5i
+.I mountprog=n
+Use an alternate RPC program number to contact the
+mount daemon on the remote host. This option is useful
+for hosts that can run multiple NFS servers.
+The default value is 100005 which is the standard RPC
+mount daemon program number.
+.TP 1.5i
+.I mountvers=n
+Use an alternate RPC version number to contact the
+mount daemon on the remote host. This option is useful
+for hosts that can run multiple NFS servers.
+The default value depends on which kernel you are using.
+.TP 1.5i
+.I nfsprog=n
+Use an alternate RPC program number to contact the
+NFS daemon on the remote host. This option is useful
+for hosts that can run multiple NFS servers.
+The default value is 100003 which is the standard RPC
+NFS daemon program number.
+.TP 1.5i
+.I nfsvers=n
+Use an alternate RPC version number to contact the
+NFS daemon on the remote host. This option is useful
+for hosts that can run multiple NFS servers.
+The default value depends on which kernel you are using.
+.TP 1.5i
+.I vers=n
+vers is an alternative to nfsvers and is compatible with
+many other operating systems.
+.TP 1.5i
+.I nolock
+Disable NFS locking. Do not start lockd.
+This is appropriate for mounting the root filesystem or
+.B /usr
+or
+.BR /var .
+These filesystems are typically either read-only or not shared, and in
+those cases, remote locking is not needed.
+This also needs to be used with some old NFS servers
+that don't support locking.
+.br
+Note that applications can still get locks on files, but the locks
+only provide exclusion locally. Other clients mounting the same
+filesystem will not be able to detect the locks.
+.TP 1.5i
+.I bg
+If the first NFS mount attempt times out, retry the mount
+in the background.
+After a mount operation is backgrounded, all subsequent mounts
+on the same NFS server will be backgrounded immediately, without
+first attempting the mount.
+A missing mount point is treated as a timeout,
+to allow for nested NFS mounts.
+.TP 1.5i
+.I fg
+If the first NFS mount attempt times out, retry the mount
+in the foreground.
+This is the complement of the
+.I bg
+option, and also the default behavior.
+.TP 1.5i
+.I soft
+If an NFS file operation has a major timeout then report an I/O error to
+the calling program.
+The default is to continue retrying NFS file operations indefinitely.
+.TP 1.5i
+.I hard
+If an NFS file operation has a major timeout then report
+"server not responding" on the console and continue retrying indefinitely.
+This is the default.
+.TP 1.5i
+.I intr
+If an NFS file operation has a major timeout and it is hard mounted,
+then allow signals to interupt the file operation and cause it to
+return EINTR to the calling program. The default is to not
+allow file operations to be interrupted.
+.TP 1.5i
+.I posix
+Mount the NFS filesystem using POSIX semantics. This allows
+an NFS filesystem to properly support the POSIX pathconf
+command by querying the mount server for the maximum length
+of a filename. To do this, the remote host must support version
+two of the RPC mount protocol. Many NFS servers support only
+version one.
+.TP 1.5i
+.I nocto
+Suppress the retrieval of new attributes when creating a file.
+.TP 1.5i
+.I noac
+Disable all forms of attribute caching entirely. This extracts a
+significant performance penalty but it allows two different NFS clients
+to get reasonable results when both clients are actively
+writing to a common export on the server.
+.TP 1.5i
+.I noacl
+Disables Access Control List (ACL) processing.
+.TP 1.5i
+.I sec=mode
+Set the security flavor for this mount to "mode".
+The default setting is \f3sec=sys\f1, which uses local
+unix uids and gids to authenticate NFS operations (AUTH_SYS).
+Other currently supported settings are:
+\f3sec=krb5\f1, which uses Kerberos V5 instead of local unix uids
+and gids to authenticate users;
+\f3sec=krb5i\f1, which uses Kerberos V5 for user authentication
+and performs integrity checking of NFS operations using secure
+checksums to prevent data tampering; and
+\f3sec=krb5p\f1, which uses Kerberos V5 for user authentication
+and integrity checking, and encrypts NFS traffic to prevent
+traffic sniffing (this is the most secure setting).
+Note that there is a performance penalty when using integrity
+or privacy.
+.TP 1.5i
+.I tcp
+Mount the NFS filesystem using the TCP protocol. This is the default
+if it is supported by both client and server. Many NFS servers only
+support UDP.
+.TP 1.5i
+.I udp
+Mount the NFS filesystem using the UDP protocol.
+.TP 1.5i
+.I nordirplus
+Disables NFSv3 READDIRPLUS RPCs. Use this option when
+mounting servers that don't support or have broken
+READDIRPLUS implementations.
+.P
+All of the non-value options have corresponding nooption forms.
+For example, nointr means don't allow file operations to be
+interrupted.
+.SS Options for the nfs4 file system type
+.TP 1.5i
+.I rsize=n
+The number of bytes nfs4 uses when reading files from the server.
+The rsize is negotiated between the server and client to determine
+the largest block size that both can support.
+The value specified by this option is the maximum size that could
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I wsize=n
+The number of bytes nfs4 uses when writing files to the server.
+The wsize is negotiated between the server and client to determine
+the largest block size that both can support.
+The value specified by this option is the maximum size that could
+be used; however, the actual size used may be smaller.
+Note: Setting this size to a value less than the largest supported
+block size will adversely affect performance.
+.TP 1.5i
+.I timeo=n
+The value in tenths of a second before sending the
+first retransmission after an RPC timeout.
+The default value depends on whether
+.IR proto=udp
+or
+.IR proto=tcp
+is in effect (see below).
+The default value for UDP is 7 tenths of a second.
+The default value for TCP is 60 seconds.
+After the first timeout,
+the timeout is doubled after each successive timeout until a maximum
+timeout of 60 seconds is reached or the enough retransmissions
+have occured to cause a major timeout. Then, if the filesystem
+is hard mounted, each new timeout cascade restarts at twice the
+initial value of the previous cascade, again doubling at each
+retransmission. The maximum timeout is always 60 seconds.
+.TP 1.5i
+.I retrans=n
+The number of minor timeouts and retransmissions that must occur before
+a major timeout occurs. The default is 5 timeouts for
+.IR proto=udp
+and 2 timeouts for
+.IR proto=tcp .
+When a major timeout
+occurs, the file operation is either aborted or a "server not responding"
+message is printed on the console.
+.TP 1.5i
+.I acregmin=n
+The minimum time in seconds that attributes of a regular file should
+be cached before requesting fresh information from a server.
+The default is 3 seconds.
+.TP 1.5i
+.I acregmax=n
+The maximum time in seconds that attributes of a regular file can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I acdirmin=n
+The minimum time in seconds that attributes of a directory should
+be cached before requesting fresh information from a server.
+The default is 30 seconds.
+.TP 1.5i
+.I acdirmax=n
+The maximum time in seconds that attributes of a directory can
+be cached before requesting fresh information from a server.
+The default is 60 seconds.
+.TP 1.5i
+.I actimeo=n
+Using actimeo sets all of
+.I acregmin,
+.I acregmax,
+.I acdirmin,
+and
+.I acdirmax
+to the same value.
+There is no default value.
+.TP 1.5i
+.I retry=n
+The number of minutes to retry an NFS mount operation
+in the foreground or background before giving up.
+The default value for forground mounts is 2 minutes.
+The default value for background mounts is 10000 minutes,
+which is roughly one week.
+.TP 1.5i
+.I port=n
+The numeric value of the port to connect to the NFS server on.
+If the port number is 0 (the default) then query the
+remote host's portmapper for the port number to use.
+If the remote host's NFS daemon is not registered with
+its portmapper, the standard NFS port number 2049 is
+used instead.
+.TP 1.5i
+.I proto=n
+Mount the NFS filesystem using a specific network protocol
+instead of the default UDP protocol.
+Many NFS version 4 servers only support TCP.
+Valid protocol types are
+.IR udp
+and
+.IR tcp .
+.TP 1.5i
+.I clientaddr=n
+On a multi-homed client, this
+causes the client to use a specific callback address when
+communicating with an NFS version 4 server.
+This option is currently ignored.
+.TP 1.5i
+.I sec=mode
+Same as \f3sec=mode\f1 for the nfs filesystem type (see above).
+.TP 1.5i
+.I bg
+If an NFS mount attempt times out, retry the mount
+in the background.
+After a mount operation is backgrounded, all subsequent mounts
+on the same NFS server will be backgrounded immediately, without
+first attempting the mount.
+A missing mount point is treated as a timeout,
+to allow for nested NFS mounts.
+.TP 1.5i
+.I fg
+If the first NFS mount attempt times out, retry the mount
+in the foreground.
+This is the complement of the
+.I bg
+option, and also the default behavior.
+.TP 1.5i
+.I soft
+If an NFS file operation has a major timeout then report an I/O error to
+the calling program.
+The default is to continue retrying NFS file operations indefinitely.
+.TP 1.5i
+.I hard
+If an NFS file operation has a major timeout then report
+"server not responding" on the console and continue retrying indefinitely.
+This is the default.
+.TP 1.5i
+.I intr
+If an NFS file operation has a major timeout and it is hard mounted,
+then allow signals to interupt the file operation and cause it to
+return EINTR to the calling program. The default is to not
+allow file operations to be interrupted.
+.TP 1.5i
+.I nocto
+Suppress the retrieval of new attributes when creating a file.
+.TP 1.5i
+.I noac
+Disable attribute caching, and force synchronous writes.
+This extracts a
+server performance penalty but it allows two different NFS clients
+to get reasonable good results when both clients are actively
+writing to common filesystem on the server.
+.P
+All of the non-value options have corresponding nooption forms.
+For example, nointr means don't allow file operations to be
+interrupted.
+.SH FILES
+.I /etc/fstab
+.SH "SEE ALSO"
+.BR fstab "(5), " mount "(8), " umount "(8), " exports (5)
+.SH AUTHOR
+"Rick Sladkey" <jrs@world.std.com>
+.SH BUGS
+.P
+Checking files on NFS filesystem referenced by file descriptors (i.e. the
+.BR fcntl
+and
+.BR ioctl
+families of functions) may lead to inconsistent result due to the lack of
+consistency check in kernel even if noac is used.
#endif
extern int verbose;
+extern int sloppy;
char *IDMAPLCK = DEFAULT_DIR "/rpcidmapd";
#define idmapd_check() do { \
num_flavour = parse_sec(opteq+1, pseudoflavour);
if (!num_flavour)
goto fail;
- } else if (!strcmp(opt, "addr")) {
+ } else if (!strcmp(opt, "addr") || sloppy) {
/* ignore */;
} else {
printf(_("unknown nfs mount parameter: "
nocto = !val;
else if (!strcmp(opt, "ac"))
noac = !val;
- else {
+ else if (!sloppy) {
printf(_("unknown nfs mount option: "
"%s%s\n"), val ? "" : "no", opt);
goto fail;
#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */
#define NFS_MOUNT_NOACL 0x0800 /* 4 */
#define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
+#define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */
/* security pseudoflavors */
#define AUTH_GSS_SPKMP 390011
#endif
-int nfsmount(const char *, const char *, int *, char **, char **, int *, int);
+int nfsmount(const char *, const char *, int *, char **, char **,
+ int, int *);
void mount_errors(char *, int, int);
#endif /* _NFS_MOUNT_H */
static char errbuf[BUFSIZ];
static char *erreob = &errbuf[BUFSIZ];
extern int verbose;
+extern int sloppy;
/* Convert RPC errors into strings */
int rpc_strerror(int);
* instead of reserve ports since reserve ports
* are not needed for pmap requests.
*/
-static u_short
+u_short
getport(
struct sockaddr_in *saddr,
u_long prog,
u_long vers,
u_int prot)
{
- u_short port;
+ u_short port = 0;
int socket;
CLIENT *clnt = NULL;
struct pmap parms;
enum clnt_stat stat;
saddr->sin_port = htons (PMAPPORT);
- socket = get_socket(saddr, prot, FALSE);
+ socket = get_socket(saddr, prot, FALSE, FALSE);
switch (prot) {
case IPPROTO_UDP:
struct pmap *mnt_pmap = &mnt_server->pmap;
struct pmap *nfs_pmap = &nfs_server->pmap;
int len;
- char *opt, *opteq;
+ char *opt, *opteq, *p, *opt_b;
char *mounthost = NULL;
char cbuf[128];
+ int open_quote = 0;
data->flags = 0;
*bg = 0;
len = strlen(new_opts);
- for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
+ for (p=old_opts, opt_b=NULL; p && *p; p++) {
+ if (!opt_b)
+ opt_b = p; /* begin of the option item */
+ if (*p == '"')
+ open_quote ^= 1; /* reverse the status */
+ if (open_quote)
+ continue; /* still in a quoted block */
+ if (*p == ',')
+ *p = '\0'; /* terminate the option item */
+ if (*p == '\0' || *(p+1) == '\0') {
+ opt = opt_b; /* opt is useful now */
+ opt_b = NULL;
+ }
+ else
+ continue; /* still somewhere in the option item */
+
if (strlen(opt) >= sizeof(cbuf))
goto bad_parameter;
if ((opteq = strchr(opt, '=')) && isdigit(opteq[1])) {
} else if (!strcmp(opt, "namlen")) {
if (nfs_mount_version >= 2)
data->namlen = val;
+ else if (sloppy)
+ continue;
else
goto bad_parameter;
#endif
} else if (!strcmp(opt, "addr")) {
/* ignore */;
continue;
- } else
+ } else if (sloppy)
+ continue;
+ else
goto bad_parameter;
sprintf(cbuf, "%s=%s,", opt, opteq+1);
} else if (opteq) {
mnt_pmap->pm_prot = IPPROTO_TCP;
data->flags |= NFS_MOUNT_TCP;
#endif
- } else
+ } else if (sloppy)
+ continue;
+ else
goto bad_parameter;
#if NFS_MOUNT_VERSION >= 5
} else if (!strcmp(opt, "sec")) {
if (nfs_mount_version < 5) {
printf(_("Warning: ignoring sec=%s option\n"), secflavor);
continue;
- } else if (!strcmp(secflavor, "sys"))
+ } else if (!strcmp(secflavor, "none"))
+ data->pseudoflavor = AUTH_NONE;
+ else if (!strcmp(secflavor, "sys"))
data->pseudoflavor = AUTH_SYS;
else if (!strcmp(secflavor, "krb5"))
data->pseudoflavor = AUTH_GSS_KRB5;
data->pseudoflavor = AUTH_GSS_SPKMI;
else if (!strcmp(secflavor, "spkm3p"))
data->pseudoflavor = AUTH_GSS_SPKMP;
+ else if (sloppy)
+ continue;
else {
printf(_("Warning: Unrecognized security flavor %s.\n"),
secflavor);
mounthost=xstrndup(opteq+1,
strcspn(opteq+1," \t\n\r,"));
else if (!strcmp(opt, "context")) {
- char *context = opteq + 1;
-
- if (strlen(context) > NFS_MAX_CONTEXT_LEN) {
- printf(_("context parameter exceeds limit of %d\n"),
- NFS_MAX_CONTEXT_LEN);
+ char *context = opteq + 1;
+ int ctxlen = strlen(context);
+
+ if (ctxlen > NFS_MAX_CONTEXT_LEN) {
+ printf(_("context parameter exceeds limit of %d\n"),
+ NFS_MAX_CONTEXT_LEN);
goto bad_parameter;
- }
- strncpy(data->context, context, NFS_MAX_CONTEXT_LEN);
- } else
+ }
+ /* The context string is in the format of
+ * "system_u:object_r:...". We only want
+ * the context str between the quotes.
+ */
+ if (*context == '"')
+ strncpy(data->context, context+1,
+ ctxlen-2);
+ else
+ strncpy(data->context, context,
+ NFS_MAX_CONTEXT_LEN);
+ } else if (sloppy)
+ continue;
+ else
goto bad_parameter;
sprintf(cbuf, "%s=%s,", opt, opteq+1);
} else {
data->flags &= ~NFS_MOUNT_NOACL;
if (!val)
data->flags |= NFS_MOUNT_NOACL;
+ } else if (!strcmp(opt, "rdirplus")) {
+ data->flags &= ~NFS_MOUNT_NORDIRPLUS;
+ if (!val)
+ data->flags |= NFS_MOUNT_NORDIRPLUS;
#endif
} else {
bad_option:
+ if (sloppy)
+ continue;
printf(_("Unsupported nfs mount option: "
"%s%s\n"), val ? "" : "no", opt);
goto out_bad;
int
nfsmount(const char *spec, const char *node, int *flags,
- char **extra_opts, char **mount_opts, int *nfs_mount_vers,
- int running_bg)
+ char **extra_opts, char **mount_opts,
+ int running_bg, int *need_statd)
{
static char *prev_bg_host;
char hostdir[1024];
*nfs_pmap = &nfs_server.pmap;
struct pmap save_mnt, save_nfs;
- int fsock;
+ int fsock = -1;
mntres_t mntres;
struct stat statbuf;
char *s;
int bg, retry;
- int retval;
+ int retval = EX_FAIL;
time_t t;
time_t prevt;
time_t timeout;
- /* The version to try is either specified or 0
- In case it is 0 we tell the caller what we tried */
- if (!*nfs_mount_vers)
- *nfs_mount_vers = find_kernel_nfs_mount_version();
- nfs_mount_version = *nfs_mount_vers;
+ nfs_mount_version = find_kernel_nfs_mount_version();
- retval = EX_FAIL;
- fsock = -1;
if (strlen(spec) >= sizeof(hostdir)) {
fprintf(stderr, _("mount: "
"excessively long host:dir argument\n"));
#if NFS_MOUNT_VERSION >= 2
data.namlen = NAME_MAX;
#endif
- data.pseudoflavor = AUTH_SYS;
bg = 0;
retry = 10000; /* 10000 minutes ~ 1 week */
#endif
#if NFS_MOUNT_VERSION >= 5
printf("sec = %u ", data.pseudoflavor);
+ printf("readdirplus = %d ", (data.flags & NFS_MOUNT_NORDIRPLUS) != 0);
#endif
printf("\n");
#endif
flavor = mountres->auth_flavors.auth_flavors_val;
while (--i >= 0) {
+ /* If no flavour requested, use first simple
+ * flavour that is offered.
+ */
+ if (! (data.flags & NFS_MOUNT_SECFLAVOUR) &&
+ (flavor[i] == AUTH_SYS ||
+ flavor[i] == AUTH_NONE)) {
+ data.pseudoflavor = flavor[i];
+ data.flags |= NFS_MOUNT_SECFLAVOUR;
+ }
if (flavor[i] == data.pseudoflavor)
yum = 1;
#ifdef NFS_MOUNT_DEBUG
"mount: %s:%s failed, "
"security flavor not supported\n",
hostname, dirname);
- /* server has registered us in mtab, send umount */
+ /* server has registered us in rmtab, send umount */
nfs_call_umount(&mnt_server, &dirname);
goto fail;
}
#endif
}
- /* create nfs socket for kernel */
-
- if (nfs_pmap->pm_prot == IPPROTO_TCP)
- fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- else
- fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (fsock < 0) {
- perror(_("nfs socket"));
- goto fail;
- }
- if (bindresvport(fsock, 0) < 0) {
- perror(_("nfs bindresvport"));
- goto fail;
+ if (nfs_mount_version == 1) {
+ /* create nfs socket for kernel */
+ if (nfs_pmap->pm_prot == IPPROTO_TCP)
+ fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ else
+ fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (fsock < 0) {
+ perror(_("nfs socket"));
+ goto fail;
+ }
+ if (bindresvport(fsock, 0) < 0) {
+ perror(_("nfs bindresvport"));
+ goto fail;
+ }
}
+
#ifdef NFS_MOUNT_DEBUG
printf(_("using port %d for nfs deamon\n"), nfs_pmap->pm_port);
#endif
* to avoid problems with multihomed hosts.
* --Swen
*/
- if (linux_version_code() <= 66314
+ if (linux_version_code() <= 0x01030a && fsock != -1
&& connect(fsock, (struct sockaddr *) nfs_saddr,
sizeof (*nfs_saddr)) < 0) {
perror(_("nfs connect"));
strcat(new_opts, cbuf);
*extra_opts = xstrdup(new_opts);
+ *need_statd = ! (data.flags & NFS_MOUNT_NONLM);
return 0;
/* abort */
*
*/
+#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <getopt.h>
#include <mntent.h>
#include <sys/mount.h>
#include <ctype.h>
+#include <pwd.h>
#include "xcommon.h"
#include "fstab.h"
extern int nfs_gethostbyname(const char *, struct sockaddr_in *);
static inline enum clnt_stat
-nfs3_umount(dirpath *argp, CLIENT *clnt)
+nfs_umount(dirpath *argp, CLIENT *clnt)
{
- static char clnt_res;
- memset (&clnt_res, 0, sizeof(clnt_res));
return clnt_call(clnt, MOUNTPROC_UMNT,
(xdrproc_t) xdr_dirpath, (caddr_t)argp,
- (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
- TIMEOUT);
-}
-
-static inline enum clnt_stat
-nfs2_umount(dirpath *argp, CLIENT *clnt)
-{
- static char clnt_res;
- memset (&clnt_res, 0, sizeof(clnt_res));
- return clnt_call(clnt, MOUNTPROC_UMNT,
- (xdrproc_t) xdr_dirpath, (caddr_t)argp,
- (xdrproc_t) xdr_void, (caddr_t) &clnt_res,
+ (xdrproc_t) xdr_void, NULL,
TIMEOUT);
}
enum clnt_stat res = 0;
int msock;
- clnt = mnt_openclnt(mnt_server, &msock);
- if (!clnt)
- goto out_bad;
switch (mnt_server->pmap.pm_vers) {
case 3:
- res = nfs3_umount(argp, clnt);
- break;
case 2:
case 1:
- res = nfs2_umount(argp, clnt);
+ if (!probe_mntport(mnt_server))
+ goto out_bad;
+ clnt = mnt_openclnt(mnt_server, &msock);
+ if (!clnt)
+ goto out_bad;
+ res = nfs_umount(argp, clnt);
+ mnt_closeclnt(clnt, msock);
+ if (res == RPC_SUCCESS)
+ return 1;
break;
default:
+ res = 1;
break;
}
- mnt_closeclnt(clnt, msock);
- if (res == RPC_SUCCESS)
- return 1;
out_bad:
- return 0;
-}
-
-u_int get_mntproto(const char *);
-u_int
-get_mntproto(const char *dirname)
-{
- FILE *mtab;
- struct mntent mntbuf;
- char tmpbuf[BUFSIZ];
- u_int proto = IPPROTO_TCP; /* assume tcp */
-
- mtab = setmntent ("/proc/mounts", "r");
- if (mtab == NULL)
- mtab = setmntent (_PATH_MOUNTED, "r");
- if (mtab == NULL)
- return proto;
-
- while(getmntent_r(mtab, &mntbuf, tmpbuf, sizeof (tmpbuf))) {
- if (strcmp(mntbuf.mnt_type, "nfs"))
- continue;
- if (strcmp(dirname, mntbuf.mnt_fsname))
- continue;
- if (hasmntopt(&mntbuf, "udp"))
- proto = IPPROTO_UDP;
- break;
- }
- endmntent (mtab);
-
- return proto;
+ return res;
}
/* complain about a failed umount */
}
}
-int add_mtab2(const char *spec, const char *node, const char *type,
- const char *opts, struct mntentchn *mc)
+int del_mtab(const char *spec, const char *node)
{
- int umnt_err, umnt_err2, res;
+ int umnt_err, res;
- umnt_err = umnt_err2 = 0;
+ umnt_err = 0;
if (lazy) {
res = umount2 (node, MNT_DETACH);
if (res < 0)
} else
res = umount (node);
- if (res < 0) {
- umnt_err = errno;
- /* A device might have been mounted on a node that has since
- been deleted or renamed, so if node fails, also try spec. */
- /* Note that this is incorrect in case spec was mounted
- several times. */
- /* if (umnt_err == ENOENT || umnt_err == EINVAL) */
- if (umnt_err != EBUSY && strcmp(node, spec)) {
- if (verbose)
- printf (_("could not umount %s - trying %s instead\n"),
- node, spec);
- res = umount (spec);
- if (res < 0)
- umnt_err2 = errno;
- /* Do not complain about remote NFS mount points */
- if (errno == ENOENT && index(spec, ':'))
- umnt_err2 = 0;
- }
- }
-
- if (res < 0 && remount && (umnt_err == EBUSY || umnt_err2 == EBUSY)) {
+ if (res < 0 && remount && errno == EBUSY && spec) {
/* Umount failed - let us try a remount */
res = mount(spec, node, NULL,
MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
if (res == 0) {
- nfs_mntent_t remnt;
+ struct mntent remnt;
fprintf(stderr,
_("umount: %s busy - remounted read-only\n"),
spec);
if (res >= 0) {
/* Umount succeeded */
if (verbose)
- printf (_("%s umounted\n"), spec);
+ printf (_("%s umounted\n"), spec ? spec : node);
}
writemtab:
if (!nomtab &&
(umnt_err == 0 || umnt_err == EINVAL || umnt_err == ENOENT)) {
- update_mtab (node, NULL);
+ update_mtab(node, NULL);
}
if (res >= 0)
return 0;
- if (umnt_err2)
- complain(umnt_err2, spec);
- if (umnt_err && umnt_err != umnt_err2)
+ if (umnt_err)
complain(umnt_err, node);
return 1;
}
/*
* Returns 1 if everything went well, else 0.
*/
-int _nfsumount(const char *spec, const char *opts)
+int _nfsumount(const char *spec, char *opts)
{
char *hostname;
char *dirname;
clnt_addr_t mnt_server = { &hostname, };
+ struct mntent mnt = { .mnt_opts = opts };
struct pmap *pmap = &mnt_server.pmap;
char *p;
}
pmap->pm_prog = MOUNTPROG;
- pmap->pm_vers = MOUNTVERS;
- pmap->pm_prot = get_mntproto(spec);
+ pmap->pm_vers = MOUNTVERS_NFSV3;
+ pmap->pm_prot = IPPROTO_TCP;
if (opts && (p = strstr(opts, "mountprog=")) && isdigit(*(p+10)))
pmap->pm_prog = atoi(p+10);
if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10)))
pmap->pm_port = atoi(p+10);
- if (opts && (p = strstr(opts, "nfsvers=")) && isdigit(*(p+8)))
- pmap->pm_vers = nfsvers_to_mnt(atoi(p+8));
+ if (opts && hasmntopt(&mnt, "v2"))
+ pmap->pm_vers = nfsvers_to_mnt(2);
+ if (opts && hasmntopt(&mnt, "v3"))
+ pmap->pm_vers = nfsvers_to_mnt(3);
+ if (opts && hasmntopt(&mnt, "v4"))
+ pmap->pm_vers = nfsvers_to_mnt(4);
+ if (opts && (p = strstr(opts, "vers=")) && isdigit(*(p+5)))
+ 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")))
+ pmap->pm_prot = IPPROTO_UDP;
if (!nfs_gethostbyname(hostname, &mnt_server.saddr))
goto out_bad;
- if (!probe_mntport(&mnt_server))
- goto out_bad;
return nfs_call_umount(&mnt_server, &dirname);
out_bad:
- printf("%s: %s: not found or not mounted\n", progname, spec);
+ fprintf(stderr, "%s: %s: not found or not mounted\n", progname, spec);
return 0;
}
argv += 1;
argc -= 1;
+ argv[0] = argv[-1]; /* So that getopt error messages are correct */
while ((c = getopt_long (argc, argv, "fvnrlh",
umount_longopts, NULL)) != -1) {
return 0;
}
}
+ if (optind != argc) {
+ umount_usage();
+ return 0;
+ }
+
+ if (spec == NULL || (*spec != '/' && strchr(spec,':') == NULL)) {
+ printf(_("umount: %s: not found\n"), spec);
+ return 0;
+ }
- mc = getmntdirbackward(spec, NULL);
- if (!mc)
+ if (*spec == '/')
+ mc = getmntdirbackward(spec, NULL);
+ else
mc = getmntdevbackward(spec, NULL);
if (!mc && verbose)
printf(_("Could not find %s in mtab\n"), spec);
- if(mc) {
- ret = _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts);
- if(ret)
- ret = add_mtab2(mc->m.mnt_fsname, mc->m.mnt_dir,
- mc->m.mnt_type, mc->m.mnt_opts, mc);
+ if (mc && strcmp(mc->m.mnt_type, "nfs") != 0 &&
+ strcmp(mc->m.mnt_type, "nfs4") != 0) {
+ fprintf(stderr, "umount.nfs: %s on %s it not an nfs filesystem\n",
+ mc->m.mnt_fsname, mc->m.mnt_dir);
+ exit(1);
}
- else {
- ret = _nfsumount(spec, NULL);
- if(ret)
- ret = add_mtab2(spec, spec, spec, spec, NULL);
+
+ if (getuid() != 0) {
+ /* only permitted if "user=" or "users" is in mount options */
+ if (!mc) {
+ /* umount might call us twice. The second time there will
+ * be no entry in mtab and we should just exit quietly
+ */
+ return 0;
+
+ only_root:
+ fprintf(stderr,"%s: You are not permitted to unmount %s\n",
+ progname, spec);
+ return 0;
+ }
+ if (hasmntopt(&mc->m, "users") == NULL) {
+ char *opt = hasmntopt(&mc->m, "user");
+ struct passwd *pw;
+ char *comma;
+ int len;
+ if (!opt)
+ goto only_root;
+ if (opt[4] != '=')
+ goto only_root;
+ comma = strchr(opt, ',');
+ if (comma)
+ len = comma - (opt + 5);
+ else
+ len = strlen(opt+5);
+ pw = getpwuid(getuid());
+ if (pw == NULL || strlen(pw->pw_name) != len
+ || strncmp(pw->pw_name, opt+5, len) != 0)
+ goto only_root;
+ }
}
+ ret = 0;
+ if (mc) {
+ if (!lazy)
+ _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts);
+ ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
+ } else if (*spec != '/') {
+ if (!lazy)
+ _nfsumount(spec, "tcp,v3");
+ } else
+ ret = del_mtab(NULL, spec);
+
return(ret);
}
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
+#include <mntent.h>
#include "misc.h"
#include "nfslib.h"
#include "exportfs.h"
#include "xmalloc.h"
#include "fsloc.h"
+#ifdef USE_BLKID
#include "blkid/blkid.h"
+#endif
enum nfsd_fsid {
* Record is terminated with newline.
*
*/
-int cache_export_ent(char *domain, struct exportent *exp);
+int cache_export_ent(char *domain, struct exportent *exp, char *p);
char *lbuf = NULL;
free(groups);
}
+#if USE_BLKID
int get_uuid(char *path, char *uuid, int uuidlen, char *u)
{
/* extract hex digits from uuidstr and compose a uuid
}
return 1;
}
-
+#endif
+
+/* Iterate through /etc/mtab, finding mountpoints
+ * at or below a given path
+ */
+static char *next_mnt(void **v, char *p)
+{
+ FILE *f;
+ struct mntent *me;
+ int l = strlen(p);
+ if (*v == NULL) {
+ f = setmntent("/etc/mtab", "r");
+ *v = f;
+ } else
+ f = *v;
+ while ((me = getmntent(f)) != NULL &&
+ (strncmp(me->mnt_dir, p, l) != 0 ||
+ me->mnt_dir[l] != '/'))
+ ;
+ if (me == NULL) {
+ endmntent(f);
+ *v = NULL;
+ return NULL;
+ }
+ return me->mnt_dir;
+}
void nfsd_fh(FILE *f)
{
unsigned int fsidnum=0;
char fsid[32];
struct exportent *found = NULL;
+ char *found_path = NULL;
nfs_export *exp;
int i;
int dev_missing = 0;
/* Now determine export point for this fsid/domain */
for (i=0 ; i < MCL_MAXTYPES; i++) {
- for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ nfs_export *next_exp;
+ for (exp = exportlist[i]; exp; exp = next_exp) {
struct stat stb;
- char u[16];
+ char u[16];
+ char *path;
+
+ if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
+ static nfs_export *prev = NULL;
+ static void *mnt = NULL;
+
+ if (prev == exp) {
+ /* try a submount */
+ path = next_mnt(&mnt, exp->m_export.e_path);
+ if (!path) {
+ next_exp = exp->m_next;
+ prev = NULL;
+ continue;
+ }
+ next_exp = exp;
+ } else {
+ prev = exp;
+ mnt = NULL;
+ path = exp->m_export.e_path;
+ next_exp = exp;
+ }
+ } else {
+ path = exp->m_export.e_path;
+ next_exp = exp->m_next;
+ }
if (!client_member(dom, exp->m_client->m_hostname))
continue;
exp->m_export.e_mountpoint:
exp->m_export.e_path))
dev_missing ++;
- if (stat(exp->m_export.e_path, &stb) != 0)
+ if (stat(path, &stb) != 0)
continue;
switch(fsidtype){
case FSID_DEV:
goto check_uuid;
case FSID_UUID8:
case FSID_UUID16:
- if (!is_mountpoint(exp->m_export.e_path))
+ if (!is_mountpoint(path))
continue;
check_uuid:
+#if USE_BLKID
if (exp->m_export.e_uuid)
get_uuid(NULL, exp->m_export.e_uuid,
uuidlen, u);
- else if (get_uuid(exp->m_export.e_path, NULL,
+ else if (get_uuid(path, NULL,
uuidlen, u) == 0)
continue;
if (memcmp(u, fhuuid, uuidlen) != 0)
continue;
break;
+#else
+ continue;
+#endif
}
/* It's a match !! */
- if (!found)
+ if (!found) {
found = &exp->m_export;
- else if (strcmp(found->e_path, exp->m_export.e_path)!= 0)
+ found_path = strdup(path);
+ } else if (strcmp(found->e_path, exp->m_export.e_path)!= 0)
{
xlog(L_WARNING, "%s and %s have same filehandle for %s, using first",
- found->e_path, exp->m_export.e_path, dom);
+ found_path, path, dom);
}
}
}
}
if (found)
- cache_export_ent(dom, found);
+ if (cache_export_ent(dom, found, found_path) < 0)
+ found = 0;
qword_print(f, dom);
qword_printint(f, fsidtype);
qword_printhex(f, fsid, fsidlen);
- qword_printint(f, time(0)+30*60);
+ /* The fsid -> path lookup can be quite expensive as it
+ * potentially stats and reads lots of devices, and some of those
+ * might have spun-down. The Answer is not likely to
+ * change underneath us, and an 'exportfs -f' can always
+ * remove this from the kernel, so use a really log
+ * timeout. Maybe this should be configurable on the command
+ * line.
+ */
+ qword_printint(f, 0x7fffffff);
if (found)
qword_print(f, found->e_path);
qword_eol(f);
qword_printint(f, exp->e_anongid);
qword_printint(f, exp->e_fsid);
write_fsloc(f, exp, path);
+#if USE_BLKID
if (exp->e_uuid == NULL) {
char u[16];
- if (get_uuid(exp->e_path, NULL, 16, u)) {
+ if (get_uuid(path, NULL, 16, u)) {
qword_print(f, "uuid");
qword_printhex(f, u, 16);
}
qword_print(f, "uuid");
qword_printhex(f, exp->e_uuid, 16);
}
+#endif
}
return qword_eol(f);
}
int i;
char *dom, *path;
nfs_export *exp, *found = NULL;
+ int found_type = 0;
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
for (exp = exportlist[i]; exp; exp = exp->m_next) {
if (!client_member(dom, exp->m_client->m_hostname))
continue;
- if (strcmp(path, exp->m_export.e_path))
+ if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
+ /* if path is a mountpoint below e_path, then OK */
+ int l = strlen(exp->m_export.e_path);
+ if (strcmp(path, exp->m_export.e_path) == 0 ||
+ (strncmp(path, exp->m_export.e_path, l) == 0 &&
+ path[l] == '/' &&
+ is_mountpoint(path)))
+ /* ok */;
+ else
+ continue;
+ } else if (strcmp(path, exp->m_export.e_path) != 0)
continue;
- if (!found)
+ if (!found) {
found = exp;
- else {
- xlog(L_WARNING, "%s exported to both %s and %s in %s",
- path, exp->m_client->m_hostname, found->m_client->m_hostname,
+ found_type = i;
+ continue;
+ }
+ /* If one is a CROSSMOUNT, then prefer the longest path */
+ if (((found->m_export.e_flags & NFSEXP_CROSSMOUNT) ||
+ (found->m_export.e_flags & NFSEXP_CROSSMOUNT)) &&
+ strlen(found->m_export.e_path) !=
+ strlen(found->m_export.e_path)) {
+
+ if (strlen(exp->m_export.e_path) >
+ strlen(found->m_export.e_path)) {
+ found = exp;
+ found_type = i;
+ }
+ continue;
+
+ } else if (found_type == i && found->m_warned == 0) {
+ xlog(L_WARNING, "%s exported to both %s and %s, "
+ "arbitrarily choosing options from first",
+ path, found->m_client->m_hostname, exp->m_client->m_hostname,
dom);
+ found->m_warned = 1;
}
}
}
if (found) {
- dump_to_cache(f, dom, path, &found->m_export);
- mountlist_add(dom, path);
+ if (dump_to_cache(f, dom, path, &found->m_export) < 0)
+ dump_to_cache(f, dom, path, NULL);
+ else
+ mountlist_add(dom, path);
} else {
dump_to_cache(f, dom, path, NULL);
}
* % echo $domain $path $[now+30*60] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel
*/
-int cache_export_ent(char *domain, struct exportent *exp)
+int cache_export_ent(char *domain, struct exportent *exp, char *path)
{
int err;
FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
return -1;
err = dump_to_cache(f, domain, exp->e_path, exp);
- fclose(f);
mountlist_add(domain, exp->e_path);
+
+ while ((exp->e_flags & NFSEXP_CROSSMOUNT) && path) {
+ /* really an 'if', but we can break out of
+ * a 'while' more easily */
+ /* Look along 'path' for other filesystems
+ * and export them with the same options
+ */
+ struct stat stb;
+ int l = strlen(exp->e_path);
+ int dev;
+
+ if (strlen(path) <= l || path[l] != '/' ||
+ strncmp(exp->e_path, path, l) != 0)
+ break;
+ if (stat(exp->e_path, &stb) != 0)
+ break;
+ dev = stb.st_dev;
+ while(path[l] == '/') {
+ char c;
+ int err;
+
+ l++;
+ while (path[l] != '/' && path[l])
+ l++;
+ c = path[l];
+ path[l] = 0;
+ err = lstat(path, &stb);
+ path[l] = c;
+ if (err < 0)
+ break;
+ if (stb.st_dev == dev)
+ continue;
+ dev = stb.st_dev;
+ path[l] = 0;
+ dump_to_cache(f, domain, path, exp);
+ path[l] = c;
+ }
+ break;
+ }
+
+ fclose(f);
return err;
}
-int cache_export(nfs_export *exp)
+int cache_export(nfs_export *exp, char *path)
{
int err;
FILE *f;
- if (exp->m_export.e_maptype != CLE_MAP_IDENT) {
- xlog(L_ERROR, "%s: unsupported mapping; kernel supports only 'identity' (default)",
- exp->m_export.m_path);
- return -1;
- }
-
f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w");
if (!f)
return -1;
fclose(f);
- err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export)
+ err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export, path)
|| err;
return err;
}
extern void cache_open(void);
extern struct nfs_fh_len *cache_get_filehandle(nfs_export *exp, int len, char *p);
-extern int cache_export(nfs_export *exp);
+extern int cache_export(nfs_export *exp, char *path);
extern void my_svc_run(void);
p, strerror(errno));
*error = NFSERR_NOENT;
} else if (estb.st_dev != stb.st_dev
- /* && (!new_cache || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT)) */
+ && (!new_cache || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT))
) {
xlog(L_WARNING, "request to export directory %s below nearest filesystem %s",
p, exp->m_export.e_path);
*/
struct nfs_fh_len *fh;
- if (cache_export(exp)) {
+ if (cache_export(exp, p)) {
*error = NFSERR_ACCES;
return NULL;
}
void cache_set_fds(fd_set *fdset);
int cache_process_req(fd_set *readfds);
+#if LONG_MAX != INT_MAX
+/* bug in glibc 2.3.6 and earlier, we need
+ * our own svc_getreqset
+ */
+static void
+my_svc_getreqset (fd_set *readfds)
+{
+ fd_mask mask;
+ fd_mask *maskp;
+ int setsize;
+ int sock;
+ int bit;
+
+ setsize = _rpc_dtablesize ();
+ if (setsize > FD_SETSIZE)
+ setsize = FD_SETSIZE;
+ maskp = readfds->fds_bits;
+ for (sock = 0; sock < setsize; sock += NFDBITS)
+ for (mask = *maskp++;
+ (bit = ffsl (mask));
+ mask ^= (1L << (bit - 1)))
+ svc_getreq_common (sock + bit - 1);
+}
+#define svc_getreqset my_svc_getreqset
+
+#endif
/*
* The heart of the server. A crib from libc for the most part...
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
## Process this file with automake to produce Makefile.in
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
GENFILES_XDR = rquota_xdr.c
GENFILES_H = rquota.h
MAINTAINERCLEANFILES = Makefile.in
-
+if CONFIG_RPCGEN
+RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
$(RPCGEN):
make -C $(top_srcdir)/tools/rpcgen all
+else
+RPCGEN = @RPCGEN_PATH@
+endif
$(GENFILES_XDR): %_xdr.c: %.x $(RPCGEN)
test -f $@ && rm -rf $@ || true
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
GENFILES_XDR = rquota_xdr.c
GENFILES_H = rquota.h
BUILT_SOURCES = $(GENFILES_H)
-I$(top_srcdir)/support/export
MAINTAINERCLEANFILES = Makefile.in
+@CONFIG_RPCGEN_FALSE@RPCGEN = @RPCGEN_PATH@
+@CONFIG_RPCGEN_TRUE@RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
CLEANFILES = $(GENFILES)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
tags uninstall uninstall-am uninstall-hook uninstall-man \
uninstall-man8 uninstall-sbinPROGRAMS
-
-$(RPCGEN):
- make -C $(top_srcdir)/tools/rpcgen all
+@CONFIG_RPCGEN_TRUE@$(RPCGEN):
+@CONFIG_RPCGEN_TRUE@ make -C $(top_srcdir)/tools/rpcgen all
$(GENFILES_XDR): %_xdr.c: %.x $(RPCGEN)
test -f $@ && rm -rf $@ || true
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
## Process this file with automake to produce Makefile.in
-man8_MANS = statd.man
-
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
+man8_MANS = statd.man sm-notify.man
GENFILES_CLNT = sm_inter_clnt.c
GENFILES_SVC = sm_inter_svc.c
RPCPREFIX = rpc.
KPREFIX = @kprefix@
-sbin_PROGRAMS = statd
-statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c notify.c \
- simu.c stat.c statd.c state.c svc_run.c rmtcall.c \
+sbin_PROGRAMS = statd sm-notify
+dist_sbin_SCRIPTS = start-statd
+statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c \
+ simu.c stat.c statd.c svc_run.c rmtcall.c \
sm_inter_clnt.c sm_inter_svc.c sm_inter_xdr.c log.h \
notlist.h statd.h system.h version.h sm_inter.h
+sm_notify_SOURCES = sm-notify.c
+
BUILT_SOURCES = $(GENFILES)
statd_LDADD = ../../support/export/libexport.a \
../../support/nfs/libnfs.a \
../../support/misc/libmisc.a \
$(LIBWRAP) $(LIBNSL)
+sm_notify_LDADD = $(LIBNSL)
EXTRA_DIST = sim_sm_inter.x sm_inter.x $(man8_MANS) COPYRIGHT simulate.c
+if CONFIG_RPCGEN
+RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
$(RPCGEN):
make -C ../../tools/rpcgen all
+else
+RPCGEN = @RPCGEN_PATH@
+endif
$(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
test -f $@ && rm -rf $@ || true
install-exec-hook:
(cd $(DESTDIR)$(sbindir) && \
for p in $(sbin_PROGRAMS); do \
- mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+ [ $$p = sm-notify ] || mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
done)
uninstall-hook:
(cd $(DESTDIR)$(sbindir) && \
for p in $(sbin_PROGRAMS); do \
- rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+ [ $$p = sm-notify ] || rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
done)
@SET_MAKE@
+
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-sbin_PROGRAMS = statd$(EXEEXT)
+sbin_PROGRAMS = statd$(EXEEXT) sm-notify$(EXEEXT)
subdir = utils/statd
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING TODO
+DIST_COMMON = $(dist_sbin_SCRIPTS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in COPYING TODO
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/aclocal/bsdsignals.m4 \
$(top_srcdir)/aclocal/kerberos5.m4 \
$(top_srcdir)/aclocal/nfs-utils.m4 \
$(top_srcdir)/aclocal/tcp-wrappers.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/support/include/config.h
CONFIG_CLEAN_FILES =
-am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sbindir)" \
+ "$(DESTDIR)$(man8dir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
+am_sm_notify_OBJECTS = sm-notify.$(OBJEXT)
+sm_notify_OBJECTS = $(am_sm_notify_OBJECTS)
+am__DEPENDENCIES_1 =
+sm_notify_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_statd_OBJECTS = callback.$(OBJEXT) notlist.$(OBJEXT) log.$(OBJEXT) \
- misc.$(OBJEXT) monitor.$(OBJEXT) notify.$(OBJEXT) \
- simu.$(OBJEXT) stat.$(OBJEXT) statd.$(OBJEXT) state.$(OBJEXT) \
- svc_run.$(OBJEXT) rmtcall.$(OBJEXT) sm_inter_clnt.$(OBJEXT) \
- sm_inter_svc.$(OBJEXT) sm_inter_xdr.$(OBJEXT)
+ misc.$(OBJEXT) monitor.$(OBJEXT) simu.$(OBJEXT) stat.$(OBJEXT) \
+ statd.$(OBJEXT) svc_run.$(OBJEXT) rmtcall.$(OBJEXT) \
+ sm_inter_clnt.$(OBJEXT) sm_inter_svc.$(OBJEXT) \
+ sm_inter_xdr.$(OBJEXT)
statd_OBJECTS = $(am_statd_OBJECTS)
-am__DEPENDENCIES_1 =
statd_DEPENDENCIES = ../../support/export/libexport.a \
../../support/nfs/libnfs.a ../../support/misc/libmisc.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@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(statd_SOURCES)
-DIST_SOURCES = $(statd_SOURCES)
+SOURCES = $(sm_notify_SOURCES) $(statd_SOURCES)
+DIST_SOURCES = $(sm_notify_SOURCES) $(statd_SOURCES)
man8dir = $(mandir)/man8
NROFF = nroff
MANS = $(man8_MANS)
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
SET_MAKE = @SET_MAKE@
secure_statd = @secure_statd@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
+startstatd = @startstatd@
statduser = @statduser@
statedir = @statedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-man8_MANS = statd.man
-RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
+man8_MANS = statd.man sm-notify.man
GENFILES_CLNT = sm_inter_clnt.c
GENFILES_SVC = sm_inter_svc.c
GENFILES_XDR = sm_inter_xdr.c
GENFILES = $(GENFILES_CLNT) $(GENFILES_SVC) $(GENFILES_XDR) $(GENFILES_H)
RPCPREFIX = rpc.
KPREFIX = @kprefix@
-statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c notify.c \
- simu.c stat.c statd.c state.c svc_run.c rmtcall.c \
+dist_sbin_SCRIPTS = start-statd
+statd_SOURCES = callback.c notlist.c log.c misc.c monitor.c \
+ simu.c stat.c statd.c svc_run.c rmtcall.c \
sm_inter_clnt.c sm_inter_svc.c sm_inter_xdr.c log.h \
notlist.h statd.h system.h version.h sm_inter.h
+sm_notify_SOURCES = sm-notify.c
BUILT_SOURCES = $(GENFILES)
statd_LDADD = ../../support/export/libexport.a \
../../support/nfs/libnfs.a \
../../support/misc/libmisc.a \
$(LIBWRAP) $(LIBNSL)
+sm_notify_LDADD = $(LIBNSL)
EXTRA_DIST = sim_sm_inter.x sm_inter.x $(man8_MANS) COPYRIGHT simulate.c
+@CONFIG_RPCGEN_FALSE@RPCGEN = @RPCGEN_PATH@
+@CONFIG_RPCGEN_TRUE@RPCGEN = $(top_builddir)/tools/rpcgen/rpcgen
MAINTAINERCLEANFILES = Makefile.in
CLEANFILES = $(GENFILES)
all: $(BUILT_SOURCES)
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
+sm-notify$(EXEEXT): $(sm_notify_OBJECTS) $(sm_notify_DEPENDENCIES)
+ @rm -f sm-notify$(EXEEXT)
+ $(LINK) $(sm_notify_OBJECTS) $(sm_notify_LDADD) $(LIBS)
statd$(EXEEXT): $(statd_OBJECTS) $(statd_DEPENDENCIES)
@rm -f statd$(EXEEXT)
$(LINK) $(statd_OBJECTS) $(statd_LDADD) $(LIBS)
+install-dist_sbinSCRIPTS: $(dist_sbin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+ @list='$(dist_sbin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(dist_sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+ $(dist_sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-dist_sbinSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_sbin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+ done
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notlist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmtcall.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simu.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm-notify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm_inter_clnt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm_inter_svc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sm_inter_xdr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statd.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/svc_run.Po@am__quote@
.c.o:
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(PROGRAMS) $(MANS)
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS)
installdirs:
- for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
install-dvi: install-dvi-am
-install-exec-am: install-sbinPROGRAMS
+install-exec-am: install-dist_sbinSCRIPTS install-sbinPROGRAMS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
ps-am:
-uninstall-am: uninstall-man uninstall-sbinPROGRAMS
+uninstall-am: uninstall-dist_sbinSCRIPTS uninstall-man \
+ uninstall-sbinPROGRAMS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
clean-libtool clean-sbinPROGRAMS ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-exec-hook \
- install-html install-html-am install-info install-info-am \
- install-man install-man8 install-pdf install-pdf-am install-ps \
+ install install-am install-data install-data-am \
+ install-dist_sbinSCRIPTS install-dvi install-dvi-am \
+ install-exec install-exec-am install-exec-hook install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man8 install-pdf install-pdf-am install-ps \
install-ps-am install-sbinPROGRAMS install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-hook uninstall-man \
- uninstall-man8 uninstall-sbinPROGRAMS
-
+ tags uninstall uninstall-am uninstall-dist_sbinSCRIPTS \
+ uninstall-hook uninstall-man uninstall-man8 \
+ uninstall-sbinPROGRAMS
-$(RPCGEN):
- make -C ../../tools/rpcgen all
+@CONFIG_RPCGEN_TRUE@$(RPCGEN):
+@CONFIG_RPCGEN_TRUE@ make -C ../../tools/rpcgen all
$(GENFILES_CLNT): %_clnt.c: %.x $(RPCGEN)
test -f $@ && rm -rf $@ || true
install-exec-hook:
(cd $(DESTDIR)$(sbindir) && \
for p in $(sbin_PROGRAMS); do \
- mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+ [ $$p = sm-notify ] || mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
done)
uninstall-hook:
(cd $(DESTDIR)$(sbindir) && \
for p in $(sbin_PROGRAMS); do \
- rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+ [ $$p = sm-notify ] || rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
done)
# XXX This makes some assumptions about what automake does.
{
notify_list *lp, *call;
static char *result = NULL;
+ char *ip_addr = xstrdup(inet_ntoa(svc_getcaller(rqstp->rq_xprt)
+ ->sin_addr));
dprintf(N_DEBUG, "Received SM_NOTIFY from %s, state: %d",
argp->mon_name, argp->state);
* it. Lockd will want to continue monitoring the remote host
* until it issues an SM_UNMON call.
*/
- while ((lp = nlist_gethost(lp, argp->mon_name, 0)) != NULL) {
- if (NL_STATE(lp) != argp->state) {
+ for (lp = rtnl ; lp ; lp = lp->next)
+ if (NL_STATE(lp) != argp->state &&
+ (matchhostname(argp->mon_name, lp->dns_name) ||
+ matchhostname(ip_addr, lp->dns_name))) {
NL_STATE(lp) = argp->state;
call = nlist_clone(lp);
- NL_TYPE(call) = NOTIFY_CALLBACK;
nlist_insert(¬ify, call);
}
- lp = NL_NEXT(lp);
- }
+
return ((void *) &result);
}
#include <sys/stat.h>
#include <errno.h>
#include <arpa/inet.h>
+#include <dirent.h>
#include "misc.h"
#include "statd.h"
#include "notlist.h"
notify_list * rtnl = NULL; /* Run-time notify list. */
+#define LINELEN (4*(8+1)+SM_PRIV_SIZE*2+1)
/*
* Services SM_MON requests.
int fd;
notify_list *clnt;
struct in_addr my_addr;
+ char *dnsname;
#ifdef RESTRICTED_STATD
- struct in_addr mon_addr, caller;
-#else
- struct hostent *hostinfo = NULL;
+ struct in_addr caller;
#endif
+ struct hostent *hostinfo = NULL;
/* Assume that we'll fail. */
result.res_stat = STAT_FAIL;
goto failure;
}
+#if 0
+ This is not usable anymore. Linux-kernel can be configured to use
+ host names with NSM so that multi-homed hosts are handled properly.
+ NeilBrown 15mar2007
+
/* 3. mon_name must be an address in dotted quad.
* Again, specific to the linux kernel lockd.
*/
mon_name);
goto failure;
}
+#endif
#else
+ if (!(hostinfo = gethostbyname(my_name))) {
+ note(N_WARNING, "gethostbyname error for %s", my_name);
+ goto failure;
+ } else
+ my_addr = *(struct in_addr *) hostinfo->h_addr;
+#endif
/*
* Check hostnames. If I can't look them up, I won't monitor. This
* might not be legal, but it adds a little bit of safety and sanity.
*/
/* must check for /'s in hostname! See CERT's CA-96.09 for details. */
- if (strchr(mon_name, '/')) {
- note(N_CRIT, "SM_MON request for hostname containing '/': %s",
- mon_name);
+ if (strchr(mon_name, '/') || mon_name[0] == '.') {
+ note(N_CRIT, "SM_MON request for hostname containing '/' "
+ "or starting '.': %s", mon_name);
note(N_CRIT, "POSSIBLE SPOOF/ATTACK ATTEMPT!");
goto failure;
- } else if (gethostbyname(mon_name) == NULL) {
+ } else if ((hostinfo = gethostbyname(mon_name)) == NULL) {
note(N_WARNING, "gethostbyname error for %s", mon_name);
goto failure;
- } else if (!(hostinfo = gethostbyname(my_name))) {
- note(N_WARNING, "gethostbyname error for %s", my_name);
- goto failure;
- } else
- my_addr = *(struct in_addr *) hostinfo->h_addr;
-#endif
+ }
/*
* Hostnames checked OK.
- * Now check to see if this is a duplicate, and warn if so.
+ * Now choose a hostname to use for matching. We cannot
+ * really trust much in the incoming NOTIFY, so to make
+ * sure that multi-homed hosts work nicely, we get an
+ * FQDN now, and use that for matching
+ */
+ hostinfo = gethostbyaddr(hostinfo->h_addr,
+ hostinfo->h_length,
+ hostinfo->h_addrtype);
+ if (hostinfo)
+ dnsname = xstrdup(hostinfo->h_name);
+ else
+ dnsname = xstrdup(my_name);
+
+ /* Now check to see if this is a duplicate, and warn if so.
* I will also return STAT_FAIL. (I *think* this is how I should
* handle it.)
*
* I'll just do a quickie success return and things should
* be happy.
*/
- if (rtnl) {
- notify_list *temp = rtnl;
-
- while ((temp = nlist_gethost(temp, mon_name, 0))) {
- if (matchhostname(NL_MY_NAME(temp), my_name) &&
- NL_MY_PROC(temp) == id->my_proc &&
- NL_MY_PROG(temp) == id->my_prog &&
- NL_MY_VERS(temp) == id->my_vers) {
- /* Hey! We already know you guys! */
- dprintf(N_DEBUG,
- "Duplicate SM_MON request for %s "
- "from procedure on %s",
- mon_name, my_name);
+ clnt = rtnl;
- /* But we'll let you pass anyway. */
- result.res_stat = STAT_SUCC;
- result.state = MY_STATE;
- return (&result);
- }
- temp = NL_NEXT(temp);
+ while ((clnt = nlist_gethost(clnt, mon_name, 0))) {
+ if (matchhostname(NL_MY_NAME(clnt), my_name) &&
+ NL_MY_PROC(clnt) == id->my_proc &&
+ NL_MY_PROG(clnt) == id->my_prog &&
+ NL_MY_VERS(clnt) == id->my_vers &&
+ memcmp(NL_PRIV(clnt), argp->priv, SM_PRIV_SIZE) == 0) {
+ /* Hey! We already know you guys! */
+ dprintf(N_DEBUG,
+ "Duplicate SM_MON request for %s "
+ "from procedure on %s",
+ mon_name, my_name);
+
+ /* But we'll let you pass anyway. */
+ result.res_stat = STAT_SUCC;
+ result.state = MY_STATE;
+ return (&result);
}
+ clnt = NL_NEXT(clnt);
}
/*
NL_MY_VERS(clnt) = id->my_vers;
NL_MY_PROC(clnt) = id->my_proc;
memcpy(NL_PRIV(clnt), argp->priv, SM_PRIV_SIZE);
+ clnt->dns_name = dnsname;
/*
* Now, Create file on stable storage for host.
*/
- path=xmalloc(strlen(SM_DIR)+strlen(mon_name)+2);
- sprintf(path, "%s/%s", SM_DIR, mon_name);
- if ((fd = open(path, O_WRONLY|O_SYNC|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
+ path=xmalloc(strlen(SM_DIR)+strlen(dnsname)+2);
+ sprintf(path, "%s/%s", SM_DIR, dnsname);
+ if ((fd = open(path, O_WRONLY|O_SYNC|O_CREAT|O_APPEND,
+ S_IRUSR|S_IWUSR)) < 0) {
/* Didn't fly. We won't monitor. */
note(N_ERROR, "creat(%s) failed: %s", path, strerror (errno));
nlist_free(NULL, clnt);
free(path);
goto failure;
}
+ {
+ char buf[LINELEN + 1 + SM_MAXSTRLEN + 2];
+ char *e;
+ int i;
+ e = buf + sprintf(buf, "%08x %08x %08x %08x ",
+ my_addr.s_addr, id->my_prog,
+ id->my_vers, id->my_proc);
+ for (i=0; i<SM_PRIV_SIZE; i++)
+ e += sprintf(e, "%02x", 0xff & (argp->priv[i]));
+ if (e+1-buf != LINELEN) abort();
+ e += sprintf(e, " %s\n", mon_name);
+ write(fd, buf, e-buf);
+ }
+
free(path);
/* PRC: do the HA callout: */
ha_callout("add-client", mon_name, my_name, -1);
return (&result);
}
+void load_state(void)
+{
+ DIR *d;
+ struct dirent *de;
+ char buf[LINELEN + 1 + SM_MAXSTRLEN + 2];
+
+ d = opendir(SM_DIR);
+ if (!d)
+ return;
+ while ((de = readdir(d))) {
+ char *path;
+ FILE *f;
+ int p;
+
+ if (de->d_name[0] == '.')
+ continue;
+ path = xmalloc(strlen(SM_DIR)+strlen(de->d_name)+2);
+ sprintf(path, "%s/%s", SM_DIR, de->d_name);
+ f = fopen(path, "r");
+ free(path);
+ if (f == NULL)
+ continue;
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ int addr, proc, prog, vers;
+ char priv[SM_PRIV_SIZE];
+ char *b;
+ int i;
+ notify_list *clnt;
+
+ buf[sizeof(buf)-1] = 0;
+ b = strchr(buf, '\n');
+ if (b) *b = 0;
+ sscanf(buf, "%x %x %x %x ",
+ &addr, &prog, &vers, &proc);
+ b = buf+36;
+ for (i=0; i<SM_PRIV_SIZE; i++) {
+ sscanf(b, "%2x", &p);
+ priv[i] = p;
+ b += 2;
+ }
+ b++;
+ clnt = nlist_new("127.0.0.1", b, 0);
+ if (!clnt)
+ break;
+ NL_ADDR(clnt).s_addr = addr;
+ NL_MY_PROG(clnt) = prog;
+ NL_MY_VERS(clnt) = vers;
+ NL_MY_PROC(clnt) = proc;
+ clnt->dns_name = xstrdup(de->d_name);
+ memcpy(NL_PRIV(clnt), priv, SM_PRIV_SIZE);
+ nlist_insert(&rtnl, clnt);
+ }
+ fclose(f);
+ }
+ closedir(d);
+}
+
+
+
/*
* Services SM_UNMON requests.
+++ /dev/null
-/*
- * Copyright (C) 1995, 1997-1999 Jeffrey A. Uphoff
- * Modified by Olaf Kirch, Oct. 1996.
- * Modified by H.J. Lu, 1998.
- *
- * NSM for Linux.
- */
-
-/*
- * NSM notify list handling.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <dirent.h>
-#include <errno.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include "misc.h"
-#include "statd.h"
-#include "notlist.h"
-
-/*
- * Initial (startup) notify list.
- */
-notify_list *inl = NULL;
-
-
-/*
- * Get list of hosts from stable storage, build list of hosts to
- * contact. These hosts are added to the global RPC notify list
- * which is processed as soon as statd enters svc_run.
- */
-void
-notify_hosts(void)
-{
- DIR *nld;
- struct dirent *de;
- notify_list *call;
-
- if (!(nld = opendir(SM_BAK_DIR))) {
- perror("opendir");
- exit(errno);
- }
-
- while ((de = readdir(nld))) {
- if (de->d_name[0] == '.')
- continue;
-
- /* The following can happen for loopback NFS mounts
- * (e.g. with cfsd) */
- if (matchhostname(de->d_name, MY_NAME)
- || matchhostname(de->d_name, "localhost")) {
- char *fname;
- fname=xmalloc(strlen(SM_BAK_DIR)+sizeof(de->d_name)+2);
- dprintf(N_DEBUG, "We're on our own notify list?!?");
- sprintf(fname, "%s/%s", SM_BAK_DIR, de->d_name);
- if (unlink(fname))
- note(N_ERROR, "unlink(%s): %s",
- fname, strerror(errno));
- free(fname);
- continue;
- }
-
- call = nlist_new(MY_NAME, de->d_name, -1);
- NL_TYPE(call) = NOTIFY_REBOOT;
- nlist_insert(¬ify, call);
- }
-
- if (closedir(nld) == -1) {
- perror("closedir");
- exit(1);
- }
-}
unsigned short port; /* port number for callback */
short int times; /* Counter used for various things. */
int state; /* For storing notified state for callbacks. */
+ char *dns_name; /* used for matching incoming
+ * NOTIFY requests */
struct notify_list *next; /* Linked list forward pointer. */
struct notify_list *prev; /* Linked list backward pointer. */
u_int32_t xid; /* XID of MS_NOTIFY RPC call */
time_t when; /* notify: timeout for re-xmit */
- int type; /* type of notify (REBOOT/CALLBACK) */
};
typedef struct notify_list notify_list;
-#define NOTIFY_REBOOT 0 /* notify remote of our reboot */
-#define NOTIFY_CALLBACK 1 /* notify client of remote reboot */
-
/*
* Global Variables
*/
#define NL_MY_PROG(L) (NL_MY_ID((L)).my_prog)
#define NL_MY_VERS(L) (NL_MY_ID((L)).my_vers)
#define NL_WHEN(L) ((L)->when)
-#define NL_TYPE(L) ((L)->type)
* Initialize callback socket
*/
int
-statd_get_socket(int port)
+statd_get_socket(void)
{
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
- /*
- * If a local hostname is given (-n option to statd), bind to the address
- * specified. This is required to support clients that ignore the mon_name in
- * the statd protocol but use the source address from the request packet.
- */
- if (MY_NAME) {
- struct hostent *hp = gethostbyname(MY_NAME);
- if (hp)
- sin.sin_addr = *(struct in_addr *) hp->h_addr;
- }
- if (port != 0) {
- sin.sin_port = htons(port);
- if (bind(sockfd, &sin, sizeof(sin)) == 0)
- goto out_success;
- note(N_CRIT, "statd: failed to bind to outgoing port, %d\n"
- " falling back on randomly chosen port\n", port);
- }
+
if (bindresvport(sockfd, &sin) < 0) {
dprintf(N_WARNING,
"process_hosts: can't bind to reserved port\n");
}
-out_success:
return sockfd;
}
-#ifdef HAVE_IFADDRS_H
-/*
- * Using the NL_ADDR(lp), reset (if needed) the hostname
- * that will be put in the SM_NOTIFY to the hostname
- * that is associated with the network interface
- * that was monitored
- */
-static void
-reset_my_name(notify_list *lp)
-{
- struct ifaddrs *ifa = NULL, *ifap;
- struct in_addr netaddr, tmp;
- struct sockaddr_in *sin, *nsin;
- struct hostent *hp;
-
- netaddr.s_addr = inet_netof(NL_ADDR(lp));
- if (getifaddrs(&ifa) >= 0) {
- for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
- if (!(ifap->ifa_flags & IFF_UP))
- continue;
-
- note(N_DEBUG, "ifa_name %s\n", ifap->ifa_name);
- if (ifap->ifa_addr == NULL)
- continue;
- if (ifap->ifa_addr->sa_family != AF_INET)
- continue;
-
- sin = (struct sockaddr_in *)ifap->ifa_addr;
- nsin = (struct sockaddr_in *)ifap->ifa_netmask;
- tmp.s_addr = sin->sin_addr.s_addr & nsin->sin_addr.s_addr;
- if (memcmp(&tmp.s_addr, &netaddr.s_addr, sizeof(netaddr.s_addr)))
- continue;
- hp = gethostbyaddr((char *)&sin->sin_addr,
- sizeof(sin->sin_addr), AF_INET);
- if (hp == NULL)
- continue;
- if (strcmp(NL_MY_NAME(lp), hp->h_name)) {
- free(NL_MY_NAME(lp));
- NL_MY_NAME(lp)= strdup(hp->h_name);
- note(N_DEBUG, "NL_MY_NAME %s\n", NL_MY_NAME(lp));
- }
- }
- }
- return;
-}
-#endif /* HAVE_IFADDRS_H */
-/*
- * Try to resolve host name for notify/callback request
- *
- * When compiled with RESTRICTED_STATD defined, we expect all
- * host names to be dotted quads. See monitor.c for details. --okir
- */
-#ifdef RESTRICTED_STATD
-static int
-try_to_resolve(notify_list *lp)
-{
- char *hname;
-
- if (NL_TYPE(lp) == NOTIFY_REBOOT)
- hname = NL_MON_NAME(lp);
- else
- hname = NL_MY_NAME(lp);
- if (!inet_aton(hname, &(NL_ADDR(lp)))) {
- note(N_ERROR, "%s is not an dotted-quad address", hname);
- NL_TIMES(lp) = 0;
- return 0;
- }
-
- /* XXX: In order to handle multi-homed hosts, we could do
- * a reverse lookup, a forward lookup, and cycle through
- * all the addresses.
- */
- return 1;
-}
-#else
-static int
-try_to_resolve(notify_list *lp)
-{
- struct hostent *hp;
- char *hname;
-
- if (NL_TYPE(lp) == NOTIFY_REBOOT)
- hname = NL_MON_NAME(lp);
- else
- hname = NL_MY_NAME(lp);
-
- dprintf(N_DEBUG, "Trying to resolve %s.", hname);
- if (!(hp = gethostbyname(hname))) {
- herror("gethostbyname");
- NL_TIMES(lp) -= 1;
- return 0;
- }
-
- if (hp->h_addrtype != AF_INET) {
- note(N_ERROR, "%s is not an AF_INET address", hname);
- NL_TIMES(lp) = 0;
- return 0;
- }
-
- /* FIXME: should try all addresses for multi-homed hosts in
- * alternation because one interface might be down/unreachable. */
- NL_ADDR(lp) = *(struct in_addr *) hp->h_addr;
-
- dprintf(N_DEBUG, "address of %s is %s", hname, inet_ntoa(NL_ADDR(lp)));
- return 1;
-}
-#endif
-
static unsigned long
xmit_call(int sockfd, struct sockaddr_in *sin,
u_int32_t prog, u_int32_t vers, u_int32_t proc,
{
struct sockaddr_in sin;
struct status new_status;
- stat_chge new_stat;
xdrproc_t func;
void *objp;
u_int32_t proc, vers, prog;
/* __u32 proc, vers, prog; */
- if (lp->addr.s_addr == INADDR_ANY && !try_to_resolve(lp))
- return NL_TIMES(lp);
if (NL_TIMES(lp) == 0) {
note(N_DEBUG, "Cannot notify %s, giving up.\n",
inet_ntoa(NL_ADDR(lp)));
sin.sin_port = lp->port;
/* LH - moved address into switch */
- switch (NL_TYPE(lp)) {
- case NOTIFY_REBOOT:
- prog = SM_PROG;
- vers = SM_VERS;
- proc = SM_NOTIFY;
-
- /* Use source address for notify replies */
- sin.sin_addr = lp->addr;
- /*
- * Unless a static hostname has been defined
- * set the NL_MY_NAME(lp) hostname to the
- * one associated with the network interface
- */
-#ifdef HAVE_IFADDRS_H
- if (!(run_mode & STATIC_HOSTNAME))
- reset_my_name(lp);
-#endif /* HAVE_IFADDRS_H */
- func = (xdrproc_t) xdr_stat_chge;
- new_stat.state = MY_STATE;
- new_stat.mon_name = NL_MY_NAME(lp);
+ prog = NL_MY_PROG(lp);
+ vers = NL_MY_VERS(lp);
+ proc = NL_MY_PROC(lp);
- objp = &new_stat;
- break;
- case NOTIFY_CALLBACK:
- prog = NL_MY_PROG(lp);
- vers = NL_MY_VERS(lp);
- proc = NL_MY_PROC(lp);
-
- /* __FORCE__ loopback for callbacks to lockd ... */
- /* Just in case we somehow ignored it thus far */
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- func = (xdrproc_t) xdr_status;
- objp = &new_status;
- new_status.mon_name = NL_MON_NAME(lp);
- new_status.state = NL_STATE(lp);
- memcpy(new_status.priv, NL_PRIV(lp), SM_PRIV_SIZE);
- break;
- default:
- note(N_ERROR, "notify_host: unknown notify type %d",
- NL_TYPE(lp));
- return 0;
- }
+ /* __FORCE__ loopback for callbacks to lockd ... */
+ /* Just in case we somehow ignored it thus far */
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ func = (xdrproc_t) xdr_status;
+ objp = &new_status;
+ new_status.mon_name = NL_MON_NAME(lp);
+ new_status.state = NL_STATE(lp);
+ memcpy(new_status.priv, NL_PRIV(lp), SM_PRIV_SIZE);
lp->xid = xmit_call(sockfd, &sin, prog, vers, proc, func, objp);
if (!lp->xid) {
- note(N_WARNING, "notify_host: failed to notify %s\n",
- inet_ntoa(lp->addr));
+ note(N_WARNING, "notify_host: failed to notify port %d\n",
+ ntohs(lp->port));
}
NL_TIMES(lp) -= 1;
return 1;
}
note(N_WARNING, "recv_rply: [%s] service %d not registered",
- inet_ntoa(lp->addr),
- NL_TYPE(lp) == NOTIFY_REBOOT? SM_PROG : NL_MY_PROG(lp));
- } else if (NL_TYPE(lp) == NOTIFY_REBOOT) {
- dprintf(N_DEBUG, "Notification of %s succeeded.",
- NL_MON_NAME(lp));
- xunlink(SM_BAK_DIR, NL_MON_NAME(lp), 0);
+ inet_ntoa(lp->addr), NL_MY_PROG(lp));
} else {
dprintf(N_DEBUG, "Callback to %s (for %d) succeeded.",
NL_MY_NAME(lp), NL_MON_NAME(lp));
time_t now;
int fd;
- if ((fd = statd_get_socket(0)) < 0)
+ if ((fd = statd_get_socket()) < 0)
return 0;
while ((entry = notify) != NULL && NL_WHEN(entry) < time(&now)) {
NL_WHEN(entry) = time(NULL) + NOTIFY_TIMEOUT;
nlist_remove(¬ify, entry);
nlist_insert_timer(¬ify, entry);
- } else if (NL_TYPE(entry) == NOTIFY_CALLBACK) {
+ } else {
note(N_ERROR,
"Can't callback %s (%d,%d), giving up.",
NL_MY_NAME(entry),
NL_MY_PROG(entry),
NL_MY_VERS(entry));
nlist_free(¬ify, entry);
- } else {
- note(N_ERROR,
- "Can't notify %s, giving up.",
- NL_MON_NAME(entry));
- /* PRC: do the HA callout */
- ha_callout("del-client", NL_MON_NAME(entry), NL_MY_NAME(entry), -1);
- xunlink(SM_BAK_DIR, NL_MON_NAME(entry), 0);
- nlist_free(¬ify, entry);
}
}
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <arpa/inet.h>
#include "statd.h"
#include "notlist.h"
{
static char *result = NULL;
+#ifdef RESTRICTED_STATD
+ struct in_addr caller;
+
+ /* 1. Reject anyone not calling from 127.0.0.1.
+ * Ignore the my_name specified by the caller, and
+ * use "127.0.0.1" instead.
+ */
+ caller = svc_getcaller(rqstp->rq_xprt)->sin_addr;
+ if (caller.s_addr != htonl(INADDR_LOOPBACK)) {
+ note(N_WARNING,
+ "Call to statd from non-local host %s",
+ inet_ntoa(caller));
+ goto failure;
+ }
+ if (ntohs(svc_getcaller(rqstp->rq_xprt)->sin_port) >= 1024) {
+ note(N_WARNING,
+ "Call to statd-simu-crash from unprivileged port\n");
+ goto failure;
+ }
+#endif
note (N_WARNING, "*** SIMULATING CRASH! ***");
my_svc_exit ();
if (rtnl)
nlist_kill (&rtnl);
+#ifdef RESTRICTED_STATD
+ failure:
+#endif
return ((void *)&result);
}
--- /dev/null
+/*
+ * Send NSM notify calls to all hosts listed in /var/lib/sm
+ *
+ * Copyright (C) 2004-2006 Olaf Kirch <okir@suse.de>
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/param.h>
+#include <sys/syslog.h>
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <time.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <netdb.h>
+#include <errno.h>
+#include <grp.h>
+
+#ifndef BASEDIR
+# ifdef NFS_STATEDIR
+# define BASEDIR NFS_STATEDIR
+# else
+# define BASEDIR "/var/lib/nfs"
+# endif
+#endif
+
+#define DEFAULT_SM_STATE_PATH BASEDIR "/state"
+#define DEFAULT_SM_DIR_PATH BASEDIR "/sm"
+#define DEFAULT_SM_BAK_PATH DEFAULT_SM_DIR_PATH ".bak"
+
+char *_SM_BASE_PATH = BASEDIR;
+char *_SM_STATE_PATH = DEFAULT_SM_STATE_PATH;
+char *_SM_DIR_PATH = DEFAULT_SM_DIR_PATH;
+char *_SM_BAK_PATH = DEFAULT_SM_BAK_PATH;
+
+#define NSM_PROG 100024
+#define NSM_PROGRAM 100024
+#define NSM_VERSION 1
+#define NSM_TIMEOUT 2
+#define NSM_NOTIFY 6
+#define NSM_MAX_TIMEOUT 120 /* don't make this too big */
+#define MAXMSGSIZE 256
+
+typedef struct sockaddr_storage nsm_address;
+
+struct nsm_host {
+ struct nsm_host * next;
+ char * name;
+ char * path;
+ nsm_address addr;
+ struct addrinfo *ai;
+ time_t last_used;
+ time_t send_next;
+ unsigned int timeout;
+ unsigned int retries;
+ unsigned int xid;
+};
+
+static char nsm_hostname[256];
+static uint32_t nsm_state;
+static int opt_debug = 0;
+static int opt_quiet = 0;
+static int opt_update_state = 1;
+static unsigned int opt_max_retry = 15 * 60;
+static char * opt_srcaddr = 0;
+static uint16_t opt_srcport = 0;
+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 void recv_reply(int);
+static void backup_hosts(const char *, const char *);
+static void get_hosts(const char *);
+static void insert_host(struct nsm_host *);
+struct nsm_host * find_host(uint32_t);
+static int addr_get_port(nsm_address *);
+static void addr_set_port(nsm_address *, int);
+static struct addrinfo *host_lookup(int, const char *);
+void nsm_log(int fac, const char *fmt, ...);
+static int record_pid();
+static void drop_privs(void);
+
+static struct nsm_host * hosts = NULL;
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int force = 0;
+
+ while ((c = getopt(argc, argv, "dm:np:v:qP:f")) != -1) {
+ switch (c) {
+ case 'f':
+ force = 1;
+ break;
+ case 'd':
+ opt_debug++;
+ break;
+ case 'm':
+ opt_max_retry = atoi(optarg) * 60;
+ break;
+ case 'n':
+ opt_update_state = 0;
+ break;
+ case 'p':
+ opt_srcport = atoi(optarg);
+ break;
+ case 'v':
+ opt_srcaddr = optarg;
+ break;
+ case 'q':
+ opt_quiet = 1;
+ break;
+ case 'P':
+ _SM_BASE_PATH = strdup(optarg);
+ _SM_STATE_PATH = malloc(strlen(optarg)+1+sizeof("state"));
+ _SM_DIR_PATH = malloc(strlen(optarg)+1+sizeof("sm"));
+ _SM_BAK_PATH = malloc(strlen(optarg)+1+sizeof("sm.bak"));
+ if (_SM_BASE_PATH == NULL ||
+ _SM_STATE_PATH == NULL ||
+ _SM_DIR_PATH == NULL ||
+ _SM_BAK_PATH == NULL) {
+ nsm_log(LOG_WARNING, "unable to allocate memory");
+ exit(1);
+ }
+ strcat(strcpy(_SM_STATE_PATH, _SM_BASE_PATH), "/state");
+ strcat(strcpy(_SM_DIR_PATH, _SM_BASE_PATH), "/sm");
+ strcat(strcpy(_SM_BAK_PATH, _SM_BASE_PATH), "/sm.bak");
+ break;
+
+ default:
+ goto usage;
+ }
+ }
+
+ if (optind < argc) {
+usage: fprintf(stderr,
+ "Usage: sm-notify [-dfq] [-m max-retry-minutes] [-p srcport]\n"
+ " [-P /path/to/state/directory] [-v my_host_name]\n");
+ return 1;
+ }
+
+ if (strcmp(_SM_BASE_PATH, BASEDIR) == 0) {
+ if (record_pid() == 0 && force == 0 && opt_update_state == 1)
+ /* already run, don't try again */
+ exit(0);
+ }
+
+ if (opt_srcaddr) {
+ strncpy(nsm_hostname, opt_srcaddr, sizeof(nsm_hostname)-1);
+ } else
+ if (gethostname(nsm_hostname, sizeof(nsm_hostname)) < 0) {
+ perror("gethostname");
+ return 1;
+ }
+
+ backup_hosts(_SM_DIR_PATH, _SM_BAK_PATH);
+ get_hosts(_SM_BAK_PATH);
+
+ if (!opt_debug) {
+ if (!opt_quiet)
+ printf("Backgrounding to notify hosts...\n");
+
+ openlog("sm-notify", LOG_PID, LOG_DAEMON);
+ log_syslog = 1;
+
+ if (daemon(0, 0) < 0) {
+ nsm_log(LOG_WARNING, "unable to background: %s",
+ strerror(errno));
+ return 1;
+ }
+
+ close(0);
+ close(1);
+ close(2);
+ }
+
+ /* Get and update the NSM state. This will call sync() */
+ nsm_state = nsm_get_state(opt_update_state);
+
+ notify();
+
+ if (hosts) {
+ struct nsm_host *hp;
+
+ while ((hp = hosts) != 0) {
+ hosts = hp->next;
+ nsm_log(LOG_NOTICE,
+ "Unable to notify %s, giving up",
+ hp->name);
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Notify hosts
+ */
+void
+notify(void)
+{
+ nsm_address local_addr;
+ time_t failtime = 0;
+ int sock = -1;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ perror("socket");
+ exit(1);
+ }
+ fcntl(sock, F_SETFL, O_NONBLOCK);
+
+ memset(&local_addr, 0, sizeof(local_addr));
+ local_addr.ss_family = AF_INET; /* Default to IPv4 */
+
+ /* Bind source IP if provided on command line */
+ if (opt_srcaddr) {
+ struct addrinfo *ai = host_lookup(AF_INET, opt_srcaddr);
+ if (!ai) {
+ nsm_log(LOG_WARNING,
+ "Not a valid hostname or address: \"%s\"\n",
+ opt_srcaddr);
+ exit(1);
+ }
+ memcpy(&local_addr, ai->ai_addr, ai->ai_addrlen);
+ /* We know it's IPv4 at this point */
+ }
+
+ /* Use source port if provided on the command line,
+ * otherwise use bindresvport */
+ if (opt_srcport) {
+ addr_set_port(&local_addr, opt_srcport);
+ if (bind(sock, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0) {
+ perror("bind");
+ exit(1);
+ }
+ } else {
+ (void) bindresvport(sock, (struct sockaddr_in *) &local_addr);
+ }
+
+ if (opt_max_retry)
+ failtime = time(NULL) + opt_max_retry;
+
+ drop_privs();
+
+ while (hosts) {
+ struct pollfd pfd;
+ time_t now = time(NULL);
+ unsigned int sent = 0;
+ struct nsm_host *hp;
+ long wait;
+
+ if (failtime && now >= failtime)
+ break;
+
+ while ((wait = hosts->send_next - now) <= 0) {
+ /* Never send more than 10 packets at once */
+ if (sent++ >= 10)
+ break;
+
+ /* Remove queue head */
+ hp = hosts;
+ hosts = hp->next;
+
+ notify_host(sock, hp);
+
+ /* Set the timeout for this call, using an
+ exponential timeout strategy */
+ wait = hp->timeout;
+ if ((hp->timeout <<= 1) > NSM_MAX_TIMEOUT)
+ hp->timeout = NSM_MAX_TIMEOUT;
+ hp->send_next = now + wait;
+ hp->retries++;
+
+ insert_host(hp);
+ }
+
+ nsm_log(LOG_DEBUG, "Host %s due in %ld seconds",
+ hosts->name, wait);
+
+ pfd.fd = sock;
+ pfd.events = POLLIN;
+
+ wait *= 1000;
+ if (wait < 100)
+ wait = 100;
+ if (poll(&pfd, 1, wait) != 1)
+ continue;
+
+ recv_reply(sock);
+ }
+}
+
+/*
+ * Send notification to a single host
+ */
+void
+notify_host(int sock, struct nsm_host *host)
+{
+ static unsigned int xid = 0;
+ nsm_address dest;
+ uint32_t msgbuf[MAXMSGSIZE], *p;
+ unsigned int len;
+
+ if (!xid)
+ xid = getpid() + time(NULL);
+ if (!host->xid)
+ host->xid = xid++;
+
+ memset(msgbuf, 0, sizeof(msgbuf));
+ p = msgbuf;
+ *p++ = htonl(host->xid);
+ *p++ = 0;
+ *p++ = htonl(2);
+
+ /* If we retransmitted 4 times, reset the port to force
+ * a new portmap lookup (in case statd was restarted).
+ * We also rotate through multiple IP addresses at this
+ * point.
+ */
+ if (host->retries >= 4) {
+ struct addrinfo *hold = host->ai;
+ struct addrinfo **next = &host->ai;
+ *next = hold->ai_next;
+ while ( *next )
+ next = & (*next)->ai_next;
+ *next = hold;
+ hold->ai_next = NULL;
+ memcpy(&host->addr, hold->ai_addr, hold->ai_addrlen);
+ addr_set_port(&host->addr, 0);
+ host->retries = 0;
+ }
+
+ dest = host->addr;
+ if (addr_get_port(&dest) == 0) {
+ /* Build a PMAP packet */
+ nsm_log(LOG_DEBUG, "Sending portmap query to %s", host->name);
+
+ addr_set_port(&dest, 111);
+ *p++ = htonl(100000);
+ *p++ = htonl(2);
+ *p++ = htonl(3);
+
+ /* Auth and verf */
+ *p++ = 0; *p++ = 0;
+ *p++ = 0; *p++ = 0;
+
+ *p++ = htonl(NSM_PROGRAM);
+ *p++ = htonl(NSM_VERSION);
+ *p++ = htonl(IPPROTO_UDP);
+ *p++ = 0;
+ } else {
+ /* Build an SM_NOTIFY packet */
+ nsm_log(LOG_DEBUG, "Sending SM_NOTIFY to %s", host->name);
+
+ *p++ = htonl(NSM_PROGRAM);
+ *p++ = htonl(NSM_VERSION);
+ *p++ = htonl(NSM_NOTIFY);
+
+ /* Auth and verf */
+ *p++ = 0; *p++ = 0;
+ *p++ = 0; *p++ = 0;
+
+ /* state change */
+ len = strlen(nsm_hostname);
+ *p++ = htonl(len);
+ memcpy(p, nsm_hostname, len);
+ p += (len + 3) >> 2;
+ *p++ = htonl(nsm_state);
+ }
+ len = (p - msgbuf) << 2;
+
+ sendto(sock, msgbuf, len, 0, (struct sockaddr *) &dest, sizeof(dest));
+}
+
+/*
+ * Receive reply from remote host
+ */
+void
+recv_reply(int sock)
+{
+ struct nsm_host *hp;
+ uint32_t msgbuf[MAXMSGSIZE], *p, *end;
+ uint32_t xid;
+ int res;
+
+ res = recv(sock, msgbuf, sizeof(msgbuf), 0);
+ if (res < 0)
+ return;
+
+ nsm_log(LOG_DEBUG, "Received packet...");
+
+ p = msgbuf;
+ end = p + (res >> 2);
+
+ xid = ntohl(*p++);
+ if (*p++ != htonl(1) /* must be REPLY */
+ || *p++ != htonl(0) /* must be ACCEPTED */
+ || *p++ != htonl(0) /* must be NULL verifier */
+ || *p++ != htonl(0)
+ || *p++ != htonl(0)) /* must be SUCCESS */
+ return;
+
+ /* Before we look at the data, find the host struct for
+ this reply */
+ if ((hp = find_host(xid)) == NULL)
+ return;
+
+ if (addr_get_port(&hp->addr) == 0) {
+ /* This was a portmap request */
+ unsigned int port;
+
+ port = ntohl(*p++);
+ if (p > end)
+ goto fail;
+
+ hp->send_next = time(NULL);
+ if (port == 0) {
+ /* No binding for statd. Delay the next
+ * portmap query for max timeout */
+ nsm_log(LOG_DEBUG, "No statd on %s", hp->name);
+ hp->timeout = NSM_MAX_TIMEOUT;
+ hp->send_next += NSM_MAX_TIMEOUT;
+ } else {
+ addr_set_port(&hp->addr, port);
+ if (hp->timeout >= NSM_MAX_TIMEOUT / 4)
+ hp->timeout = NSM_MAX_TIMEOUT / 4;
+ }
+ hp->xid = 0;
+ } else {
+ /* Successful NOTIFY call. Server returns void,
+ * so nothing we need to do here (except
+ * check that we didn't read past the end of the
+ * packet)
+ */
+ if (p <= end) {
+ nsm_log(LOG_DEBUG, "Host %s notified successfully", hp->name);
+ unlink(hp->path);
+ free(hp->name);
+ free(hp->path);
+ free(hp);
+ freeaddrinfo(hp->ai);
+ return;
+ }
+ }
+
+fail: /* Re-insert the host */
+ insert_host(hp);
+}
+
+/*
+ * Back up all hosts from the sm directory to sm.bak
+ */
+static void
+backup_hosts(const char *dirname, const char *bakname)
+{
+ struct dirent *de;
+ DIR *dir;
+
+ if (!(dir = opendir(dirname))) {
+ perror(dirname);
+ return;
+ }
+
+ while ((de = readdir(dir)) != NULL) {
+ char src[1024], dst[1024];
+
+ if (de->d_name[0] == '.')
+ continue;
+
+ snprintf(src, sizeof(src), "%s/%s", dirname, de->d_name);
+ snprintf(dst, sizeof(dst), "%s/%s", bakname, de->d_name);
+ if (rename(src, dst) < 0) {
+ nsm_log(LOG_WARNING,
+ "Failed to rename %s -> %s: %m",
+ src, dst);
+ }
+ }
+ closedir(dir);
+}
+
+/*
+ * Get all entries from sm.bak and convert them to host names
+ */
+static void
+get_hosts(const char *dirname)
+{
+ struct nsm_host *host;
+ struct dirent *de;
+ DIR *dir;
+
+ if (!(dir = opendir(dirname))) {
+ perror(dirname);
+ return;
+ }
+
+ host = NULL;
+ while ((de = readdir(dir)) != NULL) {
+ struct stat stb;
+ char path[1024];
+
+ if (de->d_name[0] == '.')
+ continue;
+ if (host == NULL)
+ host = calloc(1, sizeof(*host));
+
+ snprintf(path, sizeof(path), "%s/%s", dirname, de->d_name);
+ 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);
+ host->name = strdup(de->d_name);
+ host->retries = 100; /* force address retry */
+
+ insert_host(host);
+ host = NULL;
+ }
+ closedir(dir);
+
+ if (host)
+ free(host);
+}
+
+/*
+ * Insert host into sorted list
+ */
+void
+insert_host(struct nsm_host *host)
+{
+ struct nsm_host **where, *p;
+
+ where = &hosts;
+ while ((p = *where) != 0) {
+ /* Sort in ascending order of timeout */
+ if (host->send_next < p->send_next)
+ break;
+ /* If we have the same timeout, put the
+ * most recently used host first.
+ * This makes sure that "recent" hosts
+ * get notified first.
+ */
+ if (host->send_next == p->send_next
+ && host->last_used > p->last_used)
+ break;
+ where = &p->next;
+ }
+
+ host->next = *where;
+ *where = host;
+}
+
+/*
+ * Find host given the XID
+ */
+struct nsm_host *
+find_host(uint32_t xid)
+{
+ struct nsm_host **where, *p;
+
+ where = &hosts;
+ while ((p = *where) != 0) {
+ if (p->xid == xid) {
+ *where = p->next;
+ return p;
+ }
+ where = &p->next;
+ }
+ return NULL;
+}
+
+
+/*
+ * Retrieve the current NSM state
+ */
+unsigned int
+nsm_get_state(int update)
+{
+ char newfile[PATH_MAX];
+ int fd, state;
+
+ if ((fd = open(_SM_STATE_PATH, O_RDONLY)) < 0) {
+ if (!opt_quiet) {
+ nsm_log(LOG_WARNING, "%s: %m", _SM_STATE_PATH);
+ nsm_log(LOG_WARNING, "Creating %s, set initial state 1",
+ _SM_STATE_PATH);
+ }
+ state = 1;
+ update = 1;
+ } else {
+ if (read(fd, &state, sizeof(state)) != sizeof(state)) {
+ nsm_log(LOG_WARNING,
+ "%s: bad file size, setting state = 1",
+ _SM_STATE_PATH);
+ state = 1;
+ update = 1;
+ } else {
+ if (!(state & 1))
+ state += 1;
+ }
+ close(fd);
+ }
+
+ if (update) {
+ state += 2;
+ snprintf(newfile, sizeof(newfile),
+ "%s.new", _SM_STATE_PATH);
+ if ((fd = open(newfile, O_CREAT|O_WRONLY, 0644)) < 0) {
+ nsm_log(LOG_WARNING, "Cannot create %s: %m", newfile);
+ exit(1);
+ }
+ if (write(fd, &state, sizeof(state)) != sizeof(state)) {
+ nsm_log(LOG_WARNING,
+ "Failed to write state to %s", newfile);
+ exit(1);
+ }
+ close(fd);
+ if (rename(newfile, _SM_STATE_PATH) < 0) {
+ nsm_log(LOG_WARNING,
+ "Cannot create %s: %m", _SM_STATE_PATH);
+ exit(1);
+ }
+ sync();
+ }
+
+ return state;
+}
+
+/*
+ * Address handling utilities
+ */
+
+int
+addr_get_port(nsm_address *addr)
+{
+ switch (((struct sockaddr *) addr)->sa_family) {
+ case AF_INET:
+ return ntohs(((struct sockaddr_in *) addr)->sin_port);
+ case AF_INET6:
+ return ntohs(((struct sockaddr_in6 *) addr)->sin6_port);
+ }
+ return 0;
+}
+
+static void
+addr_set_port(nsm_address *addr, int port)
+{
+ switch (((struct sockaddr *) addr)->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *) addr)->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *) addr)->sin6_port = htons(port);
+ }
+}
+
+static struct addrinfo *
+host_lookup(int af, const char *name)
+{
+ struct addrinfo hints, *ai;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ hints.ai_protocol = IPPROTO_UDP;
+
+ if (getaddrinfo(name, NULL, &hints, &ai) != 0)
+ return NULL;
+
+ return ai;
+}
+
+/*
+ * Log a message
+ */
+void
+nsm_log(int fac, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (fac == LOG_DEBUG && !opt_debug)
+ return;
+
+ va_start(ap, fmt);
+ if (log_syslog)
+ vsyslog(fac, fmt, ap);
+ else {
+ vfprintf(stderr, fmt, ap);
+ fputs("\n", stderr);
+ }
+ va_end(ap);
+}
+
+/*
+ * Record pid in /var/run/sm-notify.pid
+ * This file should remain until a reboot, even if the
+ * program exits.
+ * If file already exists, fail.
+ */
+static int record_pid()
+{
+ char pid[20];
+ int fd;
+
+ snprintf(pid, 20, "%d\n", getpid());
+ fd = open("/var/run/sm-notify.pid", O_CREAT|O_EXCL|O_WRONLY, 0600);
+ if (fd < 0)
+ return 0;
+ write(fd, pid, strlen(pid));
+ close(fd);
+ return 1;
+}
+
+/* Drop privileges to match owner of state-directory
+ * (in case a reply triggers some unknown bug).
+ */
+static void drop_privs(void)
+{
+ struct stat st;
+
+ if (stat(_SM_DIR_PATH, &st) == -1 &&
+ stat(_SM_BASE_PATH, &st) == -1) {
+ st.st_uid = 0;
+ st.st_gid = 0;
+ }
+
+ if (st.st_uid == 0) {
+ nsm_log(LOG_WARNING,
+ "sm-notify running as root. chown %s to choose different user\n",
+ _SM_DIR_PATH);
+ return;
+ }
+
+ setgroups(0, NULL);
+ if (setgid(st.st_gid) == -1
+ || setuid(st.st_uid) == -1) {
+ nsm_log(LOG_ERR, "Fail to drop privileges");
+ exit(1);
+ }
+}
--- /dev/null
+.\"
+.\" sm-notify(8)
+.\"
+.\" Copyright (C) 2004 Olaf Kirch <okir@suse.de>
+.TH sm-notify 8 "19 Mar 2007
+.SH NAME
+sm-notify \- Send out NSM reboot notifications
+.SH SYNOPSIS
+.BI "/sbin/sm-notify [-dfq] [-m " time "] [-p " port "] [-P " path "] [-v " my_name " ]
+.SH DESCRIPTION
+File locking over NFS (v2 and v3) requires a facility to notify peers in
+case of a reboot, so that clients can reclaim locks after
+a server crash, and/or
+servers can release locks held by the rebooted client.
+.PP
+This is a two-step process: during normal
+operations, a mechanism is required to keep track of which
+hosts need to be informed of a reboot. And of course,
+notifications need to be sent out during reboot.
+The protocol used for this is called NSM, for
+.IR "Network Status Monitor" .
+.PP
+This implementation separates these into separate program.
+.B rpc.statd
+tracks hosts which need to be notified and this
+.B sm-notify
+performs the notification. When
+.B rpc.statd
+is started it will typically started
+.B sm-notify
+but this is configurable.
+.SS Operation
+For each NFS client or server machine to be monitored,
+.B rpc.statd
+creates a file in
+.BR /var/lib/nfs/sm ", "
+and removes the file if monitoring is no longer required.
+.PP
+When the machine is rebooted,
+.B sm-notify
+iterates through these files and notifies the peer
+.B statd
+server on those machines.
+.PP
+Each machine has an
+.I "NSM state" ,
+which is basically an integer counter that is incremented
+each time the machine reboots. This counter is stored
+in
+.BR /var/lib/nfs/state ,
+and updated by
+.BR sm-notify .
+.SS Security
+.B sm-notify
+has little need for root privileges and so drops them as soon as
+possible.
+It continues to need to make changes to the
+.B sm
+and
+.B sm.bak
+directories so to be able to drop privileges, these must be writable
+by a non-privileged user. If these directories are owned by a
+non-root user,
+.B sm-notify
+will drop privilege to match that user once it has created sockets for
+sending out request (for which it needs privileged) but before it
+processes any reply (which is the most likely source of possible
+privilege abuse).
+.SH OPTIONS
+.TP
+.BI -m " failtime
+When notifying hosts,
+.B sm-notify
+will try to contact each host for up to 15 minutes,
+and will give up if unable to reach it within this time
+frame.
+.IP
+Using the
+.B -m
+option, you can override this. A value of 0 tells
+sm-notify to retry indefinitely; any other value is
+interpreted as the maximum retry time in minutes.
+.TP
+.BI -v " ipaddr-or-hostname
+This option tells
+.B sm-notify
+to bind to the specified
+.IR ipaddr ,
+(or the ipaddr of the given
+.IR hostname )
+so that all notification packets originate from this address.
+This is useful for NFS failover. The given name is also used as the
+.I name
+of this host in the NSM request.
+.TP
+.BI -p " port
+instructs
+.B sm-notify
+to bind to the indicated IP
+.IR port
+number. If this option is not given, it will try to bind to
+a randomly chosen privileged port below 1024.
+.TP
+.B -q
+Be quiet. This suppresses all messages except error
+messages while collecting the list of hosts.
+.TP
+.BI -P " /path/to/state/directory
+If
+.B sm-notify
+should look in a no-standard place of state file, the path can be
+given here. The directories
+.B sm
+and
+.B sm.bak
+and the file
+.B state
+must exist in that directory with the standard names.
+.TP
+.B -f
+If the state path has not been reset with
+.BR -P ,
+.B sm-notify
+will normally create a file in
+.B /var/run
+to indicate that it has been
+run. If this file is found when
+.B sm-notify
+starts, it will not run again (as it is normally only needed once per
+reboot).
+If
+.B -f
+(for
+.BR force )
+is given,
+.B sm-notify
+will run even if the file in
+.B /var/run
+is present.
+.TP
+.B -n
+Do not update the NSM state. This is for testing only. Setting this
+flag implies
+.BR -f .
+.TP
+.B -d
+Enables debugging.
+By default,
+.B sm-notify
+forks and puts itself in the background after obtaining the
+list of hosts from
+.BR /var/lib/nfs/sm .
+.SH FILES
+.BR /var/lib/nfs/state
+.br
+.BR /var/lib/nfs/sm/*
+.br
+.BR /var/lib/nfs/sm.bak/*
+.br
+.BR /var/run/sm-notify.pid
+.SH SEE ALSO
+.BR rpc.nfsd(8),
+.BR portmap(8)
+.SH AUTHORS
+.br
+Olaf Kirch <okir@suse.de>
--- /dev/null
+#!/bin/sh
+# nfsmount calls this script when mounting a filesystem with locking
+# enabled, but when statd does not seem to be running (based on
+# /var/run/rpc.statd.pid).
+# It should run run statd with whatever flags are apropriate for this
+# site.
+PATH=/sbin:/usr/sbin
+exec rpc.statd --no-notify
+
#include <rpc/pmap_clnt.h>
#include <rpcmisc.h>
#include <sys/resource.h>
+#include <sys/wait.h>
#include <grp.h>
#include "statd.h"
#include "version.h"
/* ----- end of state directory path stuff ------- */
-short int restart = 0;
int run_mode = 0; /* foreground logging mode */
/* LH - I had these local to main, but it seemed silly to have
{ "state-directory-path", 1, 0, 'P' },
{ "notify-mode", 0, 0, 'N' },
{ "ha-callout", 1, 0, 'H' },
+ { "no-notify", 0, 0, 'L' },
{ NULL, 0, 0, 0 }
};
extern void sm_prog_1 (struct svc_req *, register SVCXPRT *);
-extern int statd_get_socket(int port);
+extern int statd_get_socket(void);
#ifdef SIMULATIONS
extern void simulator (int, char **);
killer (int sig)
{
note (N_FATAL, "Caught signal %d, un-registering and exiting.", sig);
- if (!(run_mode & MODE_NOTIFY_ONLY))
- pmap_unset (SM_PROG, SM_VERS);
+ pmap_unset (SM_PROG, SM_VERS);
exit (0);
}
static void
sigusr (int sig)
{
+ extern void my_svc_exit (void);
dprintf (N_DEBUG, "Caught signal %d, re-notifying (state %d).", sig,
MY_STATE);
- re_notify = 1;
+ my_svc_exit();
}
/*
if (run_mode & MODE_LOG_STDERR)
strcat(buf,"Log-STDERR ");
- if (run_mode & MODE_NOTIFY_ONLY)
- {
- strcat(buf,"Notify-Only ");
- }
note(N_WARNING,buf);
- /* future: IP aliasing
- if (run_mode & MODE_NOTIFY_ONLY)
- {
- dprintf(N_DEBUG,"Notify IP: %s",svr_addr);
- } */
}
/*
fprintf(stderr," -n, --name Specify a local hostname.\n");
fprintf(stderr," -P State directory path.\n");
fprintf(stderr," -N Run in notify only mode.\n");
+ fprintf(stderr," -L, --no-notify Do not perform any notification.\n");
fprintf(stderr," -H Specify a high-availability callout program.\n");
}
}
}
+static void run_sm_notify(int outport)
+{
+ char op[20];
+ char *av[6];
+ int ac = 0;
+
+ av[ac++] = "/usr/sbin/sm-notify";
+ if (run_mode & MODE_NODAEMON)
+ av[ac++] = "-d";
+ if (outport) {
+ sprintf(op, "-p%d", outport);
+ av[ac++] = op;
+ }
+ if (run_mode & STATIC_HOSTNAME) {
+ av[ac++] = "-v";
+ av[ac++] = MY_NAME;
+ }
+ av[ac] = NULL;
+ execv(av[0], av);
+ fprintf(stderr, "%s: failed to run %s\n", name_p, av[0]);
+ exit(2);
+
+}
/*
* Entry routine/main loop.
*/
MY_NAME = NULL;
/* Process command line switches */
- while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:", longopts, NULL)) != EOF) {
+ while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:L", longopts, NULL)) != EOF) {
switch (arg) {
case 'V': /* Version */
case 'v':
case 'N':
run_mode |= MODE_NOTIFY_ONLY;
break;
+ case 'L': /* Listen only */
+ run_mode |= MODE_NO_NOTIFY;
+ break;
case 'd': /* No daemon only - log to stderr */
run_mode |= MODE_LOG_STDERR;
break;
exit(-1);
}
+ if (run_mode & MODE_NOTIFY_ONLY) {
+ fprintf(stderr, "%s: -N deprecated, consider using /usr/sbin/sm-notify directly\n",
+ name_p);
+ run_sm_notify(out_port);
+ }
+
+
if (!(run_mode & MODE_NODAEMON)) {
run_mode &= ~MODE_LOG_STDERR; /* Never log to console in
daemon mode. */
*/
signal(SIGPIPE, SIG_IGN);
- /* initialize out_port */
- statd_get_socket(out_port);
-
create_pidfile();
atexit(truncate_pidfile);
- drop_privs();
- for (;;) {
- if (!(run_mode & MODE_NOTIFY_ONLY)) {
- /* Do not do pmap_unset() when running in notify mode.
- * We may clear the portmapper record for a statd not
- * running in notify mode disabling it.
- * Juan C. Gomez j_carlos_gomez@yahoo.com
- */
- pmap_unset (SM_PROG, SM_VERS);
+ if (! (run_mode & MODE_NO_NOTIFY))
+ switch (pid = fork()) {
+ case 0:
+ run_sm_notify(out_port);
+ break;
+ case -1:
+ break;
+ default:
+ waitpid(pid, NULL, 0);
}
- change_state ();
- shuffle_dirs (); /* Move directory names around */
- /* If we got this far, we have successfully started, so notify parent */
- if (pipefds[1] > 0) {
- status = 0;
- write(pipefds[1], &status, 1);
- close(pipefds[1]);
- pipefds[1] = -1;
- }
+ /* Make sure we have a privilege port for calling into the kernel */
+ statd_get_socket();
+
+ /* If sm-notify didn't take all the state files, load
+ * state information into our notify-list so we can
+ * pass on any SM_NOTIFY that arrives
+ */
+ load_state();
- notify_hosts (); /* Send out notify requests */
- ++restart;
+ pmap_unset (SM_PROG, SM_VERS);
- /* this registers both UDP and TCP services */
- if (!(run_mode & MODE_NOTIFY_ONLY)) {
- rpc_init("statd", SM_PROG, SM_VERS, sm_prog_1, port);
- }
+ /* this registers both UDP and TCP services */
+ rpc_init("statd", SM_PROG, SM_VERS, sm_prog_1, port);
+ /* If we got this far, we have successfully started, so notify parent */
+ if (pipefds[1] > 0) {
+ status = 0;
+ write(pipefds[1], &status, 1);
+ close(pipefds[1]);
+ pipefds[1] = -1;
+ }
+
+ drop_privs();
+
+ for (;;) {
/*
* Handle incoming requests: SM_NOTIFY socket requests, as
* well as callbacks from lockd.
*/
my_svc_run(); /* I rolled my own, Olaf made it better... */
- if ((run_mode & MODE_NOTIFY_ONLY))
- break;
+ /* Only get here when simulating a crash so we should probably
+ * start sm-notify running again. As we have already dropped
+ * privileges, this might not work, but I don't think
+ * responding to SM_SIMU_CRASH is an important use cases to
+ * get perfect.
+ */
+ if (! (run_mode & MODE_NO_NOTIFY))
+ switch (pid = fork()) {
+ case 0:
+ run_sm_notify(out_port);
+ break;
+ case -1:
+ break;
+ default:
+ waitpid(pid, NULL, 0);
+ }
+
}
return 0;
}
extern char * xstrdup(const char *);
extern void * xmalloc(size_t);
extern void xunlink (char *, char *, short int);
+extern void load_state(void);
/*
* Host status structure and macros.
* that just came back up, for ex, when failing over a HA service to
* another host.... */
#define STATIC_HOSTNAME 8 /* Always use the hostname set by -n */
-
+#define MODE_NO_NOTIFY 16 /* Don't notify peers of a reboot */
/*
* Program name and version pointers -- See statd.c for the reasoning
* as to why they're global.
extern char *name_p; /* program basename */
extern const char *version_p; /* program version */
-extern int re_notify; /* time to re-read notify list */
.SH NAME
rpc.statd \- NSM status monitor
.SH SYNOPSIS
-.B "rpc.statd [-F] [-d] [-?] [-n " name "] [-o " port "] [-p " port "] [-H " prog "] [-V]"
+.B "rpc.statd [-FNL] [-d] [-?] [-n " name "] [-o " port "] [-p " port "] [-H " prog "] [-V]"
.SH DESCRIPTION
The
.B rpc.statd
.B rpc.statd
creates a file in
.BR /var/lib/nfs/sm .
-When starting, it iterates through these files and notifies the
+When starting, it normally runs
+.B sm-notify
+to iterate through these files and notify the
peer
.B rpc.statd
on those machines.
statd program will check its state directory, send notifications to any
monitored nodes, and exit once the notifications have been sent. This mode is
used to enable Highly Available NFS implementations (i.e. HA-NFS).
+This mode is deprecated \-
+.B sm-notify
+should be used directly instead.
+.TP
+.BR -L , " --no-notify
+Inhibits the running of
+.BR sm-notify .
+If
+.B sm-notify
+is run by some other script at boot time, there is no need for
+.B statd
+to start sm-notify itself. This can be appropriate if starting of
+statd needs to be delayed until it is actually need. In such cases
+.B sm-notify
+should still be run at boot time.
.TP
.BI "\-H, " "" " \-\-ha-callout " prog
Specify a high availability callout program, which will receive callouts
+++ /dev/null
-/*
- * Copyright (C) 1995-1997, 1999 Jeffrey A. Uphoff
- * Modified by Olaf Kirch, 1996.
- * Modified by H.J. Lu, 1998.
- *
- * NSM for Linux.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include "statd.h"
-
-
-/*
- * Most NSM's keep the status number in an ASCII file. I'm keeping it
- * as an int (4-byte binary) for now...
- */
-void
-change_state (void)
-{
- int fd, size;
-
- if ((fd = open (SM_STAT_PATH, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) == -1)
- die ("open (%s): %s", SM_STAT_PATH, strerror (errno));
-
- if ((size = read (fd, &MY_STATE, sizeof MY_STATE)) == -1)
- die ("read (%s): %s", SM_STAT_PATH, strerror (errno));
-
- if (size != 0 && size != sizeof MY_STATE) {
- note (N_ERROR, "Error in status file format...correcting.");
-
- if (close (fd) == -1)
- die ("close (%s): %s", SM_STAT_PATH, strerror (errno));
-
- if ((fd = creat (SM_STAT_PATH, S_IRUSR | S_IWUSR)) == -1)
- die ("creat (%s): %s", SM_STAT_PATH, strerror (errno));
- }
- note (N_DEBUG, "New state: %u", (++MY_STATE % 2) ? MY_STATE : ++MY_STATE);
-
- if (lseek (fd, 0, SEEK_SET) == -1)
- die ("lseek (%s): %s", SM_STAT_PATH, strerror (errno));
-
- if (write (fd, &MY_STATE, sizeof MY_STATE) != sizeof MY_STATE)
- die ("write (%s): %s", SM_STAT_PATH, strerror (errno));
-
- if (fsync (fd) == -1)
- note (N_ERROR, "fsync (%s): %s", SM_STAT_PATH, strerror (errno));
-
- if (close (fd) == -1)
- note (N_ERROR, "close (%s): %s", SM_STAT_PATH, strerror (errno));
-
- if (MY_NAME == NULL) {
- char fullhost[SM_MAXSTRLEN + 1];
- struct hostent *hostinfo;
-
- if (gethostname (fullhost, SM_MAXSTRLEN) == -1)
- die ("gethostname: %s", strerror (errno));
-
- if ((hostinfo = gethostbyname (fullhost)) == NULL)
- note (N_ERROR, "gethostbyname error for %s", fullhost);
- else {
- strncpy (fullhost, hostinfo->h_name, sizeof (fullhost) - 1);
- fullhost[sizeof (fullhost) - 1] = '\0';
- }
-
- MY_NAME = xstrdup (fullhost);
- }
-}
-
-
-/*
- * Fairly traditional use of two directories for this.
- */
-void
-shuffle_dirs (void)
-{
- DIR *nld;
- struct dirent *de;
- struct stat st;
- char *src, *dst;
- int len1, len2, len;
-
- if (stat (SM_DIR, &st) == -1 && errno != ENOENT)
- die ("stat (%s): %s", SM_DIR, strerror (errno));
-
- if (!S_ISDIR (st.st_mode))
- if (mkdir (SM_DIR, S_IRWXU) == -1)
- die ("mkdir (%s): %s", SM_DIR, strerror (errno));
-
- memset (&st, 0, sizeof st);
-
- if (stat (SM_BAK_DIR, &st) == -1 && errno != ENOENT)
- die ("stat (%s): %s", SM_BAK_DIR, strerror (errno));
-
- if (!S_ISDIR (st.st_mode))
- if (mkdir (SM_BAK_DIR, S_IRWXU) == -1)
- die ("mkdir (%s): %s", SM_BAK_DIR, strerror (errno));
-
- if (!(nld = opendir (SM_DIR)))
- die ("opendir (%s): %s", SM_DIR, strerror (errno));
-
- len1=strlen(SM_DIR);
- len2=strlen(SM_BAK_DIR);
- while ((de = readdir (nld))) {
- if (de->d_name[0] == '.')
- continue;
- len=strlen(de->d_name);
- src=xmalloc(len1+len+2);
- dst=xmalloc(len2+len+2);
- sprintf (src, "%s/%s", SM_DIR, de->d_name);
- sprintf (dst, "%s/%s", SM_BAK_DIR, de->d_name);
- if (rename (src, dst) == -1)
- die ("rename (%s to %s): %s", SM_DIR, SM_BAK_DIR, strerror (errno));
- free(src);
- free(dst);
- }
- if (closedir (nld) == -1)
- note (N_ERROR, "closedir (%s): %s", SM_DIR, strerror (errno));
-}
* requests are put.
*/
notify_list * notify = NULL;
-int re_notify = 0;
/*
* Jump-off function.
for (;;) {
if (svc_stop)
return;
- if (re_notify) {
- change_state();
- dprintf(N_DEBUG, "Notifying...(new state %d)",
- MY_STATE);
- notify_hosts();
- re_notify = 0;
- }
/* Ah, there are some notifications to be processed */
while (notify && NL_WHEN(notify) <= time(&now)) {
tv.tv_sec);
selret = select(FD_SETSIZE, &readfds,
(void *) 0, (void *) 0, &tv);
- } else if (run_mode & MODE_NOTIFY_ONLY)
- return;
- else {
+ } else {
dprintf(N_DEBUG, "Waiting for client connections.");
selret = select(FD_SETSIZE, &readfds,
(void *) 0, (void *) 0, (struct timeval *) 0);