summaryrefslogtreecommitdiffstats
path: root/contrib/amd/amd
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/amd/amd')
-rw-r--r--contrib/amd/amd/.cvsignore1
-rw-r--r--contrib/amd/amd/amd.8488
-rw-r--r--contrib/amd/amd/amd.c7
-rw-r--r--contrib/amd/amd/amq_subr.c13
-rw-r--r--contrib/amd/amd/get_args.c7
-rw-r--r--contrib/amd/amd/ops_autofs.c1279
-rw-r--r--contrib/amd/amd/srvr_nfs.c5
7 files changed, 258 insertions, 1542 deletions
diff --git a/contrib/amd/amd/.cvsignore b/contrib/amd/amd/.cvsignore
deleted file mode 100644
index 70845e0..0000000
--- a/contrib/amd/amd/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile.in
diff --git a/contrib/amd/amd/amd.8 b/contrib/amd/amd/amd.8
index a3967a6..f98bae7 100644
--- a/contrib/amd/amd/amd.8
+++ b/contrib/amd/amd/amd.8
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 1997-2004 Erez Zadok
+.\" Copyright (c) 1997-2003 Erez Zadok
.\" Copyright (c) 1989 Jan-Simon Pendry
.\" Copyright (c) 1989 Imperial College of Science, Technology & Medicine
.\" Copyright (c) 1989 The Regents of the University of California.
@@ -38,320 +38,312 @@
.\"
.\" %W% (Berkeley) %G%
.\"
-.\" $Id: amd.8,v 1.4.2.5 2004/01/06 03:15:16 ezk Exp $
+.\" $Id: amd.8,v 1.4.2.4 2003/03/16 01:46:59 ezk Exp $
+.\" $FreeBSD$
.\"
-.TH AMD 8 "3 November 1989"
-.SH NAME
-amd \- automatically mount file systems
-.SH SYNOPSIS
-.B amd
-.B \-H
-.br
-.B amd
-[
-.BI \-F " conf_file"
-]
-.br
-.B amd
-[
-.B \-nprvHS
-] [
-.BI \-a " mount_point"
-] [
-.BI \-c " duration"
-] [
-.BI \-d " domain"
-] [
-.BI \-k " kernel-arch"
-] [
-.BI \-l " logfile"
-] [
-.BI \-o " op_sys_ver"
-] [
-.BI \-t " interval.interval"
-] [
-.BI \-w " interval"
-] [
-.BI \-x " log-option"
-] [
-.BI \-y " YP-domain"
-] [
-.BI \-C " cluster-name"
-] [
-.BI \-D " option"
-] [
-.BI \-F " conf_file"
-] [
-.BI \-O " op_sys_name"
-] [
-.BI \-T " tag"
-]
-[
-.I directory
-.I mapname
-.RI [ " \-map-options " ]
-] .\|.\|.
-.SH DESCRIPTION
-.B Amd
-is a daemon that automatically mounts filesystems
-whenever a file or directory
-within that filesystem is accessed.
-Filesystems are automatically unmounted when they
-appear to have become quiescent.
-.LP
-.B Amd
+.Dd April 19, 1994
+.Dt AMD 8
+.Os
+.Sh NAME
+.Nm amd
+.Nd automatically mount file systems
+.Sh SYNOPSIS
+.Nm amd
+.Fl H
+.Nm amd
+.Op Fl F Ar conf_file
+.Nm amd
+.Op Fl nprvHS
+.Op Fl a Ar mount_point
+.Op Fl c Ar duration
+.Op Fl d Ar domain
+.Bk -words
+.Op Fl k Ar kernel-arch
+.Ek
+.Op Fl l Ar logfile
+.Op Fl o Ar op_sys_ver
+.Op Fl t Ar timeout.retransmit
+.Bk -words
+.Op Fl w Ar interval
+.Ek
+.Op Fl x Ar log-option
+.Op Fl y Ar YP-domain
+.Bk -words
+.Op Fl C Ar cluster-name
+.Ek
+.Op Fl D Ar option
+.Op Fl F Ar conf_file
+.Op Fl O Ar op_sys_name
+.Op Fl T Ar tag
+.Oo
+.Ar directory mapname
+.Op Fl map-options
+.Oc
+.Ar ...
+.Sh DESCRIPTION
+.Nm Amd
+is a daemon that automatically mounts file systems whenever a file or directory
+within that file system is accessed. File systems are automatically unmounted
+when they appear to be quiescent.
+.Pp
+.Nm Amd
operates by attaching itself as an
-.SM NFS
+.Tn NFS
server to each of the specified
-.IB directories .
+.Ar directories .
Lookups within the specified directories
are handled by
-.BR amd ,
+.Nm amd ,
which uses the map defined by
-.I mapname
-to determine how to resolve the lookup.
-Generally, this will be a host name, some filesystem information
-and some mount options for the given filesystem.
-.LP
+.Ar mapname
+to determine how to resolve the lookup. Generally, this will be a host name,
+some file system information and some mount options for the given file system.
+.Pp
In the first form depicted above,
-.B amd
+.Nm amd
will print a short help string. In the second form, if no options are
-specified, or the
-.B -F
-is used,
-.B amd
-will read configuration parameters from the file
-.I conf_file
+specified, or if the
+.Fl F
+is used,
+.Nm amd
+will read configuration parameters from the file
+.Ar conf_file
which defaults to
-.BR /etc/amd.conf .
+.Pa /etc/amd.conf .
The last form is described below.
-.SH OPTIONS
-
-.\"*******************************************************"
-
-.TP
-.BI \-a " temporary-directory"
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl a Ar temporary-directory
Specify an alternative location for the real mount points.
The default is
-.BR /a .
-
-.TP
-.BI \-c " duration"
+.Pa /.amd_mnt .
+.It Fl c Ar duration
Specify a
-.IR duration ,
+.Ar duration ,
in seconds, that a looked up name remains
cached when not in use. The default is 5 minutes.
-
-.TP
-.BI \-d " domain"
+.It Fl d Ar domain
Specify the local domain name. If this option is not
given the domain name is determined from the hostname.
-
-.TP
-.BI \-k " kernel-arch"
+.It Fl k Ar kernel-arch
Specifies the kernel architecture. This is used solely
to set the ${karch} selector.
-
-.TP
-.BI \-l " logfile"
+.It Fl l Ar logfile
Specify a logfile in which to record mount and unmount events.
If
-.I logfile
+.Ar logfile
is the string
-.B syslog
-then the log messages will be sent to the system log daemon by
-.IR syslog (3).
-The default syslog facility used is LOG_DAEMON. If you
-wish to change it, append its name to the log file name, delimited by a
-single colon. For example, if
-.I logfile
+.Em syslog ,
+the log messages will be sent to the system log daemon by
+.Xr syslog 3 .
+The default syslog facility used is LOG_DAEMON.
+If you wish to change it, append its name to the log file name,
+delimited by a single colon.
+For example, if
+.Ar logfile
is the string
-.B syslog:local7
+.Dq Li syslog:local7
then
-.B Amd
-will log messages via
-.IR syslog (3)
+.Nm amd
+will log messages via
+.Xr syslog 3
using the LOG_LOCAL7 facility (if it exists on the system).
-
-.TP
-.B \-n
+.It Fl n
Normalize hostnames.
-The name refereed to by ${rhost} is normalized relative to the
+The name referred to by ${rhost} is normalized relative to the
host database before being used. The effect is to translate
aliases into ``official'' names.
-
-.TP
-.BI \-o " op_sys_ver"
-Override the compiled-in version number of the operating system. Useful
-when the built in version is not desired for backward compatibility reasons.
-For example, if the build in version is ``2.5.1'', you can override it to
-``5.5.1'', and use older maps that were written with the latter in mind.
-
-.TP
-.B \-p
-Print PID.
+.It Fl o Ar op_sys_ver
+Override the compiled-in version number of the operating system.
+Useful when the built in version is not desired for backward
+compatibility reasons.
+For example, if the build in version is
+.Dq 2.5.1 ,
+you can override it to
+.Dq 5.5.1 ,
+and use older maps that were written with the latter in mind.
+.It Fl p
+Print
+.Em PID .
Outputs the process-id of
-.B amd
+.Nm amd
to standard output where it can be saved into a file.
-
-.TP
-.B \-r
+.It Fl r
Restart existing mounts.
-.B Amd
-will scan the mount file table to determine which filesystems
+.Nm Amd
+will scan the mount file table to determine which file systems
are currently mounted. Whenever one of these would have
been auto-mounted,
-.B amd
-.I inherits
+.Nm amd
+.Em inherits
it.
-
-.TP
-.BI \-t " timeout.retransmit"
+.It Fl t Ar timeout.retransmit
Specify the NFS timeout
-.IR interval ,
-in tenths of a second, between NFS/RPC retries (for UDP only). The default
+.Ar interval ,
+in tenths of a second, between
+.Tn NFS/RPC
+retries (for UDP only). The default
is 0.8 seconds. The second value alters the retransmit counter, which
defaults to 11 retransmissions. Both of these values are used by the kernel
to communicate with amd. Useful defaults are supplied if either or both
values are missing.
-
+.Pp
Amd relies on the kernel RPC retransmit mechanism to trigger mount retries.
The values of these parameters change the overall retry interval. Too long
an interval gives poor interactive response; too short an interval causes
excessive retries.
-
-.TP
-.B \-v
+.It Fl v
Version. Displays version and configuration information on standard error.
-
-.TP
-.BI \-w " interval"
+.It Fl w Ar interval
Specify an
-.IR interval ,
-in seconds, between attempts to dismount
-filesystems that have exceeded their cached times.
-The default is 2 minutes.
-
-.TP
-.BI \-x " options"
-Specify run-time logging options. The options are a comma separated
-list chosen from: fatal, error, user, warn, info, map, stats, all.
-
-.TP
-.BI \-y " domain"
-Specify an alternative NIS domain from which to fetch the NIS maps.
-The default is the system domain name. This option is ignored if NIS
+.Ar interval ,
+in seconds, between attempts to dismount file systems that have exceeded their
+cached times. The default is 2 minutes.
+.It Fl x Ar options
+Specify run-time logging options. The options are a comma separated list
+chosen from: fatal, error, user, warn, info, map, stats, all.
+.It Fl y Ar domain
+Specify an alternative
+.Tn NIS
+domain from which to fetch the
+.Tn NIS
+maps.
+The default is the system domain name.
+This option is ignored if
+.Tn NIS
support is not available.
-
-.TP
-.BI \-C " cluster-name"
+.It Fl C Ar cluster-name
Specify an alternative HP-UX cluster name to use.
-
-.TP
-.BI \-D " option"
+.It Fl D Ar option
Select from a variety of debug options. Prefixing an
-option with the strings
-.B no
+option with the string
+.Em no
reverses the effect of that option. Options are cumulative.
The most useful option is
-.BR all .
+.Ar all .
+.Pp
Since
-.I \-D
+.Fl D
is only used for debugging other options are not documented here:
-the current supported set of options is listed by the \-v option
+the current supported set of options is listed by the
+.Fl v
+option
and a fuller description is available in the program source.
-
-.TP
-.BI \-F " conf_file"
-Specify an amd configuration file to use. See
-.BR amd.conf (5)
+.It Fl F Ar conf_file
+Specify an
+.Nm amd
+configuration file to use. See
+.Xr amd.conf 5
for description of this file's format. This configuration file is used to
specify any options in lieu of typing many of them on the command line. The
-.I amd.conf
-file includes directives for every command line option amd has, and many
-more that are only available via the configuration file facility. The
-configuration file specified by this option is processed after all other
-options had been processed, regardless of the actual location of this option
-on the command line.
-
-.TP
-.B \-H
+.Nm amd.conf
+file includes directives for every command line option amd has,
+and many more that are only available via the configuration file
+facility. The configuration file specified by this option is
+processed after all other options have been processed, regardless
+of the actual location of this option on the command line.
+.It Fl H
Print help and usage string.
-
-.TP
-.BI \-O " op_sys_name"
-Override the compiled-in name of the operating system. Useful when the
-built in name is not desired for backward compatibility reasons. For
-example, if the build in name is ``sunos5'', you can override it to
-``sos5'', and use older maps which were written with the latter in mind.
-
-.TP
-.B \-S
-Do not lock the running executable pages of amd into memory. To improve
-amd's performance, systems that support the
-.BR plock (3)
-call, could lock the amd process into memory. This way there is less chance
-the operating system will schedule, page out, and swap the amd process as
-needed. This tends improves amd's performance, at the cost of reserving the
-memory used by the amd process (making it unavailable for other processes).
+.It Fl O Ar op_sys_name
+Override the compiled-in name of the operating system.
+Useful when the built in name is not desired for backward
+compatibility reasons.
+For example, if the build in name is
+.Dq sunos5 ,
+you can override it to
+.Dq sos5
+and use older maps which were written with the latter in mind.
+.It Fl S
+Do not lock the running executable pages of
+.Nm amd
+into memory. To improve
+.Nm amd's
+performance, systems that support the
+.Xr plock 3
+call, could lock the
+.Nm amd
+process into memory. This way there is less chance the operating system will
+schedule, page out, and swap the
+.Nm amd
+process as needed. This tends to improve
+.Nm amd's
+performance, at the cost of reserving the memory used by the
+.Nm amd
+process
+(making it unavailable for other processes).
If this behavior is not desired, use the
-.B \-S
+.Fl S
option.
-
-.TP
-.BI \-T " tag"
+.It Fl T Ar tag
Specify a tag to use with
-.BR amd.conf (5).
-All map entries tagged with
-.I tag
-will be processed. Map entries that are not tagged are always processed.
+.Xr amd.conf 5 .
+All Map entries tagged with tag will be processed.
+Map entries that are not tagged are always processed.
Map entries that are tagged with a tag other than
-.I tag
+.Ar tag
will not be processed.
-
-.SH FILES
-.PD 0
-.TP 5
-.B /a
-directory under which filesystems are dynamically mounted
-.TP 5
-.B /etc/amd.conf
+.El
+.Sh FILES
+.Bl -tag -width /axx
+.It Pa /.amd_mnt
+directory under which file systems are dynamically mounted
+.It Pa /etc/amd.conf
default configuration file
-.PD
-.SH CAVEATS
+.El
+.Sh CAVEATS
Some care may be required when creating a mount map.
-.LP
-Symbolic links on an NFS filesystem can be incredibly inefficient.
-In most implementations of NFS, their interpolations are not cached
-by the kernel and each time a symlink is encountered during a
-.I lookuppn
-translation it costs an RPC call to the NFS server.
-It would appear that a large improvement in real-time
+.Pp
+Symbolic links on an
+.Tn NFS
+file system can be incredibly inefficient.
+In most implementations of
+.Tn NFS ,
+their interpolations are not cached by
+the kernel and each time a symbolic link is
+encountered during a
+.Em lookuppn
+translation it costs an
+.Tn RPC
+call to the
+.Tn NFS
+server.
+A large improvement in real-time
performance could be gained by adding a cache somewhere.
-Replacing symlinks with a suitable incarnation of the auto-mounter
+Replacing
+.Xr symlink 2
+with a suitable incarnation of the auto-mounter
results in a large real-time speedup, but also causes a large
number of process context switches.
-.LP
+.Pp
A weird imagination is most useful to gain full advantage of all
the features.
-.SH "SEE ALSO"
-.BR amd.conf (5),
-.BR amq (8),
-.BR domainname (1),
-.BR hostname (1),
-.BR automount (8),
-.BR mount (8),
-.BR umount (8),
-.BR mtab (5),
-.BR syslog (3).
-.LP
-.I "Amd \- The 4.4 BSD Automounter"
-.SH AUTHORS
-Jan-Simon Pendry <jsp@doc.ic.ac.uk>, Department of Computing, Imperial College, London, UK.
-.P
-Erez Zadok <ezk@cs.columbia.edu>, Department of Computer Science, Columbia
-University, New York, USA.
-.P
+.Sh SEE ALSO
+.Xr domainname 1 ,
+.Xr hostname 1 ,
+.Xr syslog 3 ,
+.Xr amd.conf 5 ,
+.Xr mtab 5 ,
+.Xr amq 8 ,
+.Xr mount 8 ,
+.Xr umount 8
+.Rs
+.%T Amd \- The 4.4 BSD Automounter
+.Re
+.Pp
+.Pa http://www.cs.columbia.edu/~ezk/am-utils/
+.Sh AUTHORS
+.An Jan-Simon Pendry Aq jsp@doc.ic.ac.uk ,
+Department of Computing, Imperial College, London, UK.
+.Pp
+.An Erez Zadok Aq ezk@cs.columbia.edu ,
+Department of Computer Science, Columbia University,
+New York, USA.
+.Pp
Other authors and contributors to am-utils are listed in the
-.B AUTHORS
+.Pa AUTHORS
file distributed with am-utils.
+.Sh HISTORY
+The
+.Nm amd
+utility first appeared in
+.Bx 4.4 .
diff --git a/contrib/amd/amd/amd.c b/contrib/amd/amd/amd.c
index e2631ae..1cc97b7 100644
--- a/contrib/amd/amd/amd.c
+++ b/contrib/amd/amd/amd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2004 Erez Zadok
+ * Copyright (c) 1997-2003 Erez Zadok
* Copyright (c) 1989 Jan-Simon Pendry
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
* Copyright (c) 1989 The Regents of the University of California.
@@ -38,7 +38,8 @@
*
* %W% (Berkeley) %G%
*
- * $Id: amd.c,v 1.8.2.6 2004/01/06 03:15:16 ezk Exp $
+ * $Id: amd.c,v 1.8.2.5 2002/12/27 22:44:29 ezk Exp $
+ * $FreeBSD$
*
*/
@@ -224,7 +225,7 @@ init_global_options(void)
gopt.arch = HOST_ARCH;
/* automounter temp dir */
- gopt.auto_dir = "/a";
+ gopt.auto_dir = "/.amd_mnt";
/* cluster name */
gopt.cluster = NULL;
diff --git a/contrib/amd/amd/amq_subr.c b/contrib/amd/amd/amq_subr.c
index d0e49ba..6ce7bfa 100644
--- a/contrib/amd/amd/amq_subr.c
+++ b/contrib/amd/amd/amq_subr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2004 Erez Zadok
+ * Copyright (c) 1997-2003 Erez Zadok
* Copyright (c) 1990 Jan-Simon Pendry
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
* Copyright (c) 1990 The Regents of the University of California.
@@ -38,7 +38,8 @@
*
* %W% (Berkeley) %G%
*
- * $Id: amq_subr.c,v 1.6.2.6 2004/01/19 00:25:55 ezk Exp $
+ * $Id: amq_subr.c,v 1.6.2.4 2002/12/27 22:44:33 ezk Exp $
+ * $FreeBSD$
*
*/
/*
@@ -74,7 +75,7 @@ amqproc_mnttree_1_svc(voidp argp, struct svc_req *rqstp)
static am_node *mp;
mp = find_ap(*(char **) argp);
- return (amq_mount_tree_p *) ((void *)&mp);
+ return (amq_mount_tree_p *) &mp;
}
@@ -100,7 +101,7 @@ amqproc_umnt_1_svc(voidp argp, struct svc_req *rqstp)
amq_mount_stats *
amqproc_stats_1_svc(voidp argp, struct svc_req *rqstp)
{
- return (amq_mount_stats *) ((void *)&amd_stats);
+ return (amq_mount_stats *) &amd_stats;
}
@@ -168,7 +169,7 @@ amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp)
amq_mount_info_list *
amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp)
{
- return (amq_mount_info_list *) ((void *)&mfhead); /* XXX */
+ return (amq_mount_info_list *) &mfhead; /* XXX */
}
@@ -285,7 +286,7 @@ xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp)
if (!xdr_amq_mount_tree_node(xdrs, objp)) {
return (FALSE);
}
- if (!xdr_pointer(xdrs, (char **) ((void *)&mnil), sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
+ if (!xdr_pointer(xdrs, (char **) &mnil, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
return (FALSE);
}
if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) {
diff --git a/contrib/amd/amd/get_args.c b/contrib/amd/amd/get_args.c
index df85683..cc9847d 100644
--- a/contrib/amd/amd/get_args.c
+++ b/contrib/amd/amd/get_args.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2004 Erez Zadok
+ * Copyright (c) 1997-2003 Erez Zadok
* Copyright (c) 1990 Jan-Simon Pendry
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
* Copyright (c) 1990 The Regents of the University of California.
@@ -38,7 +38,8 @@
*
* %W% (Berkeley) %G%
*
- * $Id: get_args.c,v 1.7.2.6 2004/01/06 03:15:16 ezk Exp $
+ * $Id: get_args.c,v 1.7.2.5 2002/12/27 22:44:34 ezk Exp $
+ * $FreeBSD$
*
*/
@@ -85,7 +86,7 @@ get_version_string(void)
vers = xmalloc(2048 + wire_buf_len);
sprintf(vers, "%s\n%s\n%s\n%s\n",
- "Copyright (c) 1997-2004 Erez Zadok",
+ "Copyright (c) 1997-2003 Erez Zadok",
"Copyright (c) 1990 Jan-Simon Pendry",
"Copyright (c) 1990 Imperial College of Science, Technology & Medicine",
"Copyright (c) 1990 The Regents of the University of California.");
diff --git a/contrib/amd/amd/ops_autofs.c b/contrib/amd/amd/ops_autofs.c
deleted file mode 100644
index bd0bb12..0000000
--- a/contrib/amd/amd/ops_autofs.c
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * Copyright (c) 1997-2001 Erez Zadok
- * Copyright (c) 1990 Jan-Simon Pendry
- * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry at Imperial College, London.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgment:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * %W% (Berkeley) %G%
- *
- * $Id: ops_autofs.c,v 1.7.2.4 2001/04/24 06:17:40 ib42 Exp $
- *
- */
-
-/*
- * Automounter filesystem
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-#include <am_defs.h>
-#include <amd.h>
-
-/*
- * KLUDGE: wrap whole file in HAVE_FS_AUTOFS, because
- * not all systems with an automounter file system are supported
- * by am-utils yet...
- */
-
-#ifdef HAVE_FS_AUTOFS
-
-/*
- * MACROS:
- */
-#ifndef AUTOFS_NULL
-# define AUTOFS_NULL ((u_long)0)
-#endif /* not AUTOFS_NULL */
-
-/*
- * VARIABLES:
- */
-
-/* forward declarations */
-static int mount_autofs(char *dir, char *opts);
-static int autofs_mount_1_svc(struct mntrequest *mr, struct mntres *result, struct authunix_parms *cred);
-static int autofs_unmount_1_svc(struct umntrequest *ur, struct umntres *result, struct authunix_parms *cred);
-
-/* external declarations */
-extern bool_t xdr_mntrequest(XDR *, mntrequest *);
-extern bool_t xdr_mntres(XDR *, mntres *);
-extern bool_t xdr_umntrequest(XDR *, umntrequest *);
-extern bool_t xdr_umntres(XDR *, umntres *);
-
-/*
- * STRUCTURES:
- */
-
-/* Sun's kernel-based automounter-supporting file system */
-am_ops autofs_ops =
-{
- "autofs",
- amfs_auto_match,
- 0, /* amfs_auto_init */
- autofs_mount,
- 0,
- autofs_umount,
- 0,
- amfs_auto_lookuppn,
- amfs_auto_readdir, /* browsable version of readdir() */
- 0, /* autofs_readlink */
- autofs_mounted,
- 0, /* autofs_umounted */
- find_amfs_auto_srvr,
- FS_MKMNT | FS_NOTIMEOUT | FS_BACKGROUND | FS_AMQINFO | FS_DIRECTORY
-};
-
-
-/****************************************************************************
- *** FUNCTIONS ***
- ****************************************************************************/
-
-/*
- * Mount the top-level using autofs
- */
-int
-autofs_mount(am_node *mp)
-{
- mntfs *mf = mp->am_mnt;
- struct stat stb;
- char opts[256], preopts[256];
- int error;
- char *mnttype;
-
- /*
- * Mounting the automounter.
- * Make sure the mount directory exists, construct
- * the mount options and call the mount_autofs routine.
- */
-
- if (stat(mp->am_path, &stb) < 0) {
- return errno;
- } else if ((stb.st_mode & S_IFMT) != S_IFDIR) {
- plog(XLOG_WARNING, "%s is not a directory", mp->am_path);
- return ENOTDIR;
- }
- if (mf->mf_ops == &autofs_ops)
- mnttype = "indirect";
- else if (mf->mf_ops == &amfs_direct_ops)
- mnttype = "direct";
-#ifdef HAVE_AMU_FS_UNION
- else if (mf->mf_ops == &amfs_union_ops)
- mnttype = "union";
-#endif /* HAVE_AMU_FS_UNION */
- else
- mnttype = "auto";
-
- /*
- * Construct some mount options:
- *
- * Tack on magic map=<mapname> option in mtab to emulate
- * SunOS automounter behavior.
- */
- preopts[0] = '\0';
-#ifdef MNTTAB_OPT_INTR
- strcat(preopts, MNTTAB_OPT_INTR);
- strcat(preopts, ",");
-#endif /* MNTTAB_OPT_INTR */
-#ifdef MNTTAB_OPT_IGNORE
- strcat(preopts, MNTTAB_OPT_IGNORE);
- strcat(preopts, ",");
-#endif /* MNTTAB_OPT_IGNORE */
- sprintf(opts, "%s%s,%s=%d,%s=%d,%s=%d,%s,map=%s",
- preopts,
- MNTTAB_OPT_RW,
- MNTTAB_OPT_PORT, nfs_port,
- MNTTAB_OPT_TIMEO, gopt.amfs_auto_timeo,
- MNTTAB_OPT_RETRANS, gopt.amfs_auto_retrans,
- mnttype, mf->mf_info);
-
- /* now do the mount */
- error = mount_autofs(mf->mf_mount, opts);
- if (error) {
- errno = error;
- plog(XLOG_FATAL, "mount_autofs: %m");
- return error;
- }
- return 0;
-}
-
-
-void
-autofs_mounted(mntfs *mf)
-{
- amfs_auto_mkcacheref(mf);
-}
-
-
-/*
- * Unmount a top-level automount node
- */
-int
-autofs_umount(am_node *mp)
-{
- int error;
- struct stat stb;
-
- /*
- * The lstat is needed if this mount is type=direct. When that happens,
- * the kernel cache gets confused between the underlying type (dir) and
- * the mounted type (link) and so needs to be re-synced before the
- * unmount. This is all because the unmount system call follows links and
- * so can't actually unmount a link (stupid!). It was noted that doing an
- * ls -ld of the mount point to see why things were not working actually
- * fixed the problem - so simulate an ls -ld here.
- */
- if (lstat(mp->am_path, &stb) < 0) {
-#ifdef DEBUG
- dlog("lstat(%s): %m", mp->am_path);
-#endif /* DEBUG */
- }
- error = UMOUNT_FS(mp->am_path, mnttab_file_name);
- if (error == EBUSY && mp->am_flags & AMF_AUTOFS) {
- plog(XLOG_WARNING, "autofs_unmount of %s busy (autofs). exit", mp->am_path);
- error = 0; /* fake unmount was ok */
- }
- return error;
-}
-
-
-/*
- * Mount an automounter directory.
- * The automounter is connected into the system
- * as a user-level NFS server. mount_autofs constructs
- * the necessary NFS parameters to be given to the
- * kernel so that it will talk back to us.
- */
-static int
-mount_autofs(char *dir, char *opts)
-{
- char fs_hostname[MAXHOSTNAMELEN + MAXPATHLEN + 1];
- char *map_opt, buf[MAXHOSTNAMELEN];
- int retry, error, flags;
- struct utsname utsname;
- mntent_t mnt;
- autofs_args_t autofs_args;
- MTYPE_TYPE type = MOUNT_TYPE_AUTOFS;
-
- memset((voidp) &autofs_args, 0, sizeof(autofs_args)); /* Paranoid */
-
- memset((voidp) &mnt, 0, sizeof(mnt));
- mnt.mnt_dir = dir;
- mnt.mnt_fsname = pid_fsname;
- mnt.mnt_opts = opts;
- mnt.mnt_type = type;
-
- retry = hasmntval(&mnt, "retry");
- if (retry <= 0)
- retry = 2; /* XXX */
-
- /*
- * SET MOUNT ARGS
- */
- if (uname(&utsname) < 0) {
- strcpy(buf, "localhost.autofs");
- } else {
- strcpy(buf, utsname.nodename);
- strcat(buf, ".autofs");
- }
-#ifdef HAVE_FIELD_AUTOFS_ARGS_T_ADDR
- autofs_args.addr.buf = buf;
- autofs_args.addr.len = strlen(autofs_args.addr.buf);
- autofs_args.addr.maxlen = autofs_args.addr.len;
-#endif /* HAVE_FIELD_AUTOFS_ARGS_T_ADDR */
-
- autofs_args.path = dir;
- autofs_args.opts = opts;
-
- map_opt = hasmntopt(&mnt, "map");
- if (map_opt) {
- map_opt += sizeof("map="); /* skip the "map=" */
- if (map_opt == NULL) {
- plog(XLOG_WARNING, "map= has a null map name. reset to amd.unknown");
- map_opt = "amd.unknown";
- }
- }
- autofs_args.map = map_opt;
-
- /* XXX: these I set arbitrarily... */
- autofs_args.mount_to = 300;
- autofs_args.rpc_to = 60;
- autofs_args.direct = 0;
-
- /*
- * Make a ``hostname'' string for the kernel
- */
- sprintf(fs_hostname, "pid%ld@%s:%s",
- (long) (foreground ? am_mypid : getppid()),
- am_get_hostname(), dir);
-
- /*
- * Most kernels have a name length restriction.
- */
- if (strlen(fs_hostname) >= MAXHOSTNAMELEN)
- strcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..");
-
- /*
- * Finally we can compute the mount flags set above.
- */
- flags = compute_mount_flags(&mnt);
-
- /*
- * This is it! Here we try to mount amd on its mount points.
- */
- error = mount_fs(&mnt, flags, (caddr_t) &autofs_args, retry, type, 0, NULL, mnttab_file_name);
- return error;
-}
-
-
-/****************************************************************************/
-/* autofs program dispatcher */
-void
-autofs_program_1(struct svc_req *rqstp, SVCXPRT *transp)
-{
- int ret;
- union {
- mntrequest autofs_mount_1_arg;
- umntrequest autofs_umount_1_arg;
- } argument;
- union {
- mntres mount_res;
- umntres umount_res;
- } result;
-
- bool_t (*xdr_argument)(), (*xdr_result)();
- int (*local)();
-
- switch (rqstp->rq_proc) {
-
- case AUTOFS_NULL:
- svc_sendreply(transp,
- (XDRPROC_T_TYPE) xdr_void,
- (SVC_IN_ARG_TYPE) NULL);
- return;
-
- case AUTOFS_MOUNT:
- xdr_argument = xdr_mntrequest;
- xdr_result = xdr_mntres;
- local = (int (*)()) autofs_mount_1_svc;
- break;
-
- case AUTOFS_UNMOUNT:
- xdr_argument = xdr_umntrequest;
- xdr_result = xdr_umntres;
- local = (int (*)()) autofs_unmount_1_svc;
- break;
-
- default:
- svcerr_noproc(transp);
- return;
- }
-
- memset((char *) &argument, 0, sizeof(argument));
- if (!svc_getargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) &argument)) {
- plog(XLOG_ERROR,
- "AUTOFS xdr decode failed for %d %d %d",
- (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
- svcerr_decode(transp);
- return;
- }
-
- ret = (*local) (&argument, &result, rqstp);
- if (!svc_sendreply(transp,
- (XDRPROC_T_TYPE) xdr_result,
- (SVC_IN_ARG_TYPE) &result)) {
- svcerr_systemerr(transp);
- }
-
- if (!svc_freeargs(transp,
- (XDRPROC_T_TYPE) xdr_argument,
- (SVC_IN_ARG_TYPE) &argument)) {
- plog(XLOG_FATAL, "unable to free rpc arguments in autofs_program_1");
- going_down(1);
- }
-}
-
-
-static int
-autofs_mount_1_svc(struct mntrequest *mr, struct mntres *result, struct authunix_parms *cred)
-{
- int err = 0;
- am_node *anp, *anp2;
-
- plog(XLOG_INFO, "XXX: autofs_mount_1_svc: %s:%s:%s:%s",
- mr->map, mr->name, mr->opts, mr->path);
-
- /* look for map (eg. "/home") */
- anp = find_ap(mr->path);
- if (!anp) {
- plog(XLOG_ERROR, "map %s not found", mr->path);
- err = ENOENT;
- goto out;
- }
- /* turn on autofs in map flags */
- if (!(anp->am_flags & AMF_AUTOFS)) {
- plog(XLOG_INFO, "turning on AMF_AUTOFS for node %s", mr->path);
- anp->am_flags |= AMF_AUTOFS;
- }
-
- /*
- * Look for (and create if needed) the new node.
- *
- * If an error occurred, return it. If a -1 was returned, that indicates
- * that a mount is in progress, so sleep a while (while the backgrounded
- * mount is happening), and then signal the autofs to retry the mount.
- *
- * There's something I don't understand. I was thinking that this code
- * here is the one which will succeed eventually and will send an RPC
- * reply to the kernel, but apparently that happens somewhere else, not
- * here. It works though, just that I don't know how. Arg. -Erez.
- * */
- err = 0;
- anp2 = autofs_lookuppn(anp, mr->name, &err, VLOOK_CREATE);
- if (!anp2) {
- if (err == -1) { /* then tell autofs to retry */
- sleep(1);
- err = EAGAIN;
- }
- goto out;
- }
-
-out:
- result->status = err;
- return err;
-}
-
-
-static int
-autofs_unmount_1_svc(struct umntrequest *ur, struct umntres *result, struct authunix_parms *cred)
-{
- int err = 0;
-
-#ifdef HAVE_FIELD_UMNTREQUEST_RDEVID
- plog(XLOG_INFO, "XXX: autofs_unmount_1_svc: %d:%lu:%lu:0x%lx",
- ur->isdirect, (unsigned long) ur->devid, (unsigned long) ur->rdevid,
- (unsigned long) ur->next);
-#else /* HAVE_FIELD_UMNTREQUEST_RDEVID */
- plog(XLOG_INFO, "XXX: autofs_unmount_1_svc: %d:%lu:0x%lx",
- ur->isdirect, (unsigned long) ur->devid,
- (unsigned long) ur->next);
-#endif /* HAVE_FIELD_UMNTREQUEST_RDEVID */
-
- err = EINVAL; /* XXX: not implemented yet */
- goto out;
-
-out:
- result->status = err;
- return err;
-}
-
-
-/*
- * Pick a file system to try mounting and
- * do that in the background if necessary
- *
- For each location:
- if it is new -defaults then
- extract and process
- continue;
- fi
- if it is a cut then
- if a location has been tried then
- break;
- fi
- continue;
- fi
- parse mount location
- discard previous mount location if required
- find matching mounted filesystem
- if not applicable then
- this_error = No such file or directory
- continue
- fi
- if the filesystem failed to be mounted then
- this_error = error from filesystem
- elif the filesystem is mounting or unmounting then
- this_error = -1
- elif the fileserver is down then
- this_error = -1
- elif the filesystem is already mounted
- this_error = 0
- break
- fi
- if no error on this mount then
- this_error = initialize mount point
- fi
- if no error on this mount and mount is delayed then
- this_error = -1
- fi
- if this_error < 0 then
- retry = true
- fi
- if no error on this mount then
- make mount point if required
- fi
- if no error on this mount then
- if mount in background then
- run mount in background
- return -1
- else
- this_error = mount in foreground
- fi
- fi
- if an error occurred on this mount then
- update stats
- save error in mount point
- fi
- endfor
- */
-static int
-autofs_bgmount(struct continuation *cp, int mpe)
-{
- mntfs *mf = cp->mp->am_mnt; /* Current mntfs */
- mntfs *mf_retry = 0; /* First mntfs which needed retrying */
- int this_error = -1; /* Per-mount error */
- int hard_error = -1;
- int mp_error = mpe;
-
- /*
- * Try to mount each location.
- * At the end:
- * hard_error == 0 indicates something was mounted.
- * hard_error > 0 indicates everything failed with a hard error
- * hard_error < 0 indicates nothing could be mounted now
- */
- for (; this_error && *cp->ivec; cp->ivec++) {
- am_ops *p;
- am_node *mp = cp->mp;
- char *link_dir;
- int dont_retry;
-
- if (hard_error < 0)
- hard_error = this_error;
-
- this_error = -1;
-
- if (**cp->ivec == '-') {
- /*
- * Pick up new defaults
- */
- if (cp->auto_opts && *cp->auto_opts)
- cp->def_opts = str3cat(cp->def_opts, cp->auto_opts, ";", *cp->ivec + 1);
- else
- cp->def_opts = strealloc(cp->def_opts, *cp->ivec + 1);
-#ifdef DEBUG
- dlog("Setting def_opts to \"%s\"", cp->def_opts);
-#endif /* DEBUG */
- continue;
- }
- /*
- * If a mount has been attempted, and we find
- * a cut then don't try any more locations.
- */
- if (STREQ(*cp->ivec, "/") || STREQ(*cp->ivec, "||")) {
- if (cp->tried) {
-#ifdef DEBUG
- dlog("Cut: not trying any more locations for %s",
- mp->am_path);
-#endif /* DEBUG */
- break;
- }
- continue;
- }
-
- /* match the operators */
- p = ops_match(&cp->fs_opts, *cp->ivec, cp->def_opts, mp->am_path, cp->key, mp->am_parent->am_mnt->mf_info);
-
- /*
- * Find a mounted filesystem for this node.
- */
- mp->am_mnt = mf = realloc_mntfs(mf, p, &cp->fs_opts,
- cp->fs_opts.opt_fs,
- cp->fs_opts.fs_mtab,
- cp->auto_opts,
- cp->fs_opts.opt_opts,
- cp->fs_opts.opt_remopts);
-
- p = mf->mf_ops;
-#ifdef DEBUG
- dlog("Got a hit with %s", p->fs_type);
-#endif /* DEBUG */
-
- /*
- * Note whether this is a real mount attempt
- */
- if (p == &amfs_error_ops) {
- plog(XLOG_MAP, "Map entry %s for %s did not match", *cp->ivec, mp->am_path);
- if (this_error <= 0)
- this_error = ENOENT;
- continue;
- } else {
- if (cp->fs_opts.fs_mtab) {
- plog(XLOG_MAP, "Trying mount of %s on \"%s\" fstype %s",
- cp->fs_opts.fs_mtab, mp->am_path, p->fs_type);
- }
- cp->tried = TRUE;
- }
-
- this_error = 0;
- dont_retry = FALSE;
-
- if (mp->am_link) {
- XFREE(mp->am_link);
- mp->am_link = 0;
- }
- link_dir = mf->mf_fo->opt_sublink;
-
- if (link_dir && *link_dir) {
- if (*link_dir == '/') {
- mp->am_link = strdup(link_dir);
- } else {
- /*
- * try getting fs option from continuation, not mountpoint!
- * Don't try logging the string from mf, since it may be bad!
- */
- if (cp->fs_opts.opt_fs != mf->mf_fo->opt_fs)
- plog(XLOG_ERROR, "use %s instead of 0x%lx",
- cp->fs_opts.opt_fs, (unsigned long) mf->mf_fo->opt_fs);
-
- mp->am_link = str3cat((char *) 0,
- cp->fs_opts.opt_fs, "/", link_dir);
-
- normalize_slash(mp->am_link);
- }
- }
-
- if (mf->mf_error > 0) {
- this_error = mf->mf_error;
- } else if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) {
- /*
- * Still mounting - retry later
- */
-#ifdef DEBUG
- dlog("Duplicate pending mount fstype %s", p->fs_type);
-#endif /* DEBUG */
- this_error = -1;
- } else if (FSRV_ISDOWN(mf->mf_server)) {
- /*
- * Would just mount from the same place
- * as a hung mount - so give up
- */
-#ifdef DEBUG
- dlog("%s is already hung - giving up", mf->mf_mount);
-#endif /* DEBUG */
- mp_error = EWOULDBLOCK;
- dont_retry = TRUE;
- this_error = -1;
- } else if (mf->mf_flags & MFF_MOUNTED) {
-#ifdef DEBUG
- dlog("duplicate mount of \"%s\" ...", mf->mf_info);
-#endif /* DEBUG */
-
- /*
- * Just call mounted()
- */
- am_mounted(mp);
-
- this_error = 0;
- break;
- }
-
- /*
- * Will usually need to play around with the mount nodes
- * file attribute structure. This must be done here.
- * Try and get things initialized, even if the fileserver
- * is not known to be up. In the common case this will
- * progress things faster.
- */
- if (!this_error) {
- /*
- * Fill in attribute fields.
- */
- if (mf->mf_ops->fs_flags & FS_DIRECTORY)
- mk_fattr(mp, NFDIR);
- else
- mk_fattr(mp, NFLNK);
-
- if (p->fs_init)
- this_error = (*p->fs_init) (mf);
- }
-
- /*
- * Make sure the fileserver is UP before doing any more work
- */
- if (!FSRV_ISUP(mf->mf_server)) {
-#ifdef DEBUG
- dlog("waiting for server %s to become available", mf->mf_server->fs_host);
-#endif /* DEBUG */
- this_error = -1;
- }
-
- if (!this_error && mf->mf_fo->opt_delay) {
- /*
- * If there is a delay timer on the mount
- * then don't try to mount if the timer
- * has not expired.
- */
- int i = atoi(mf->mf_fo->opt_delay);
- if (i > 0 && clocktime() < (cp->start + i)) {
-#ifdef DEBUG
- dlog("Mount of %s delayed by %lds", mf->mf_mount, i - clocktime() + cp->start);
-#endif /* DEBUG */
- this_error = -1;
- }
- }
-
- if (this_error < 0 && !dont_retry) {
- if (!mf_retry)
- mf_retry = dup_mntfs(mf);
- cp->retry = TRUE;
- }
-
- if (!this_error) {
- if (p->fs_flags & FS_MBACKGROUND) {
- mf->mf_flags |= MFF_MOUNTING; /* XXX */
-#ifdef DEBUG
- dlog("backgrounding mount of \"%s\"", mf->mf_mount);
-#endif /* DEBUG */
- if (cp->callout) {
- untimeout(cp->callout);
- cp->callout = 0;
- }
- run_task(try_mount, (voidp) mp, amfs_auto_cont, (voidp) cp);
- mf->mf_flags |= MFF_MKMNT; /* XXX */
- if (mf_retry)
- free_mntfs(mf_retry);
- return -1;
- } else {
-#ifdef DEBUG
- dlog("foreground mount of \"%s\" ...", mf->mf_info);
-#endif /* DEBUG */
- this_error = try_mount((voidp) mp);
- if (this_error < 0) {
- if (!mf_retry)
- mf_retry = dup_mntfs(mf);
- cp->retry = TRUE;
- }
- }
- }
-
- if (this_error >= 0) {
- if (this_error > 0) {
- amd_stats.d_merr++;
- if (mf != mf_retry) {
- mf->mf_error = this_error;
- mf->mf_flags |= MFF_ERROR;
- }
- }
-
- /*
- * Wakeup anything waiting for this mount
- */
- wakeup((voidp) mf);
- }
- }
-
- if (this_error && cp->retry) {
- free_mntfs(mf);
- mf = cp->mp->am_mnt = mf_retry;
- /*
- * Not retrying again (so far)
- */
- cp->retry = FALSE;
- cp->tried = FALSE;
- /*
- * Start at the beginning.
- * Rewind the location vector and
- * reset the default options.
- */
- cp->ivec = cp->xivec;
- cp->def_opts = strealloc(cp->def_opts, cp->auto_opts);
- /*
- * Arrange that autofs_bgmount is called
- * after anything else happens.
- */
-#ifdef DEBUG
- dlog("Arranging to retry mount of %s", cp->mp->am_path);
-#endif /* DEBUG */
- sched_task(amfs_auto_retry, (voidp) cp, (voidp) mf);
- if (cp->callout)
- untimeout(cp->callout);
- cp->callout = timeout(RETRY_INTERVAL, wakeup, (voidp) mf);
-
- cp->mp->am_ttl = clocktime() + RETRY_INTERVAL;
-
- /*
- * Not done yet - so don't return anything
- */
- return -1;
- }
-
- if (hard_error < 0 || this_error == 0)
- hard_error = this_error;
-
- /*
- * Discard handle on duff filesystem.
- * This should never happen since it
- * should be caught by the case above.
- */
- if (mf_retry) {
- if (hard_error)
- plog(XLOG_ERROR, "discarding a retry mntfs for %s", mf_retry->mf_mount);
- free_mntfs(mf_retry);
- }
-
- /*
- * If we get here, then either the mount succeeded or
- * there is no more mount information available.
- */
- if (hard_error < 0 && mp_error)
- hard_error = cp->mp->am_error = mp_error;
- if (hard_error > 0) {
- /*
- * Set a small(ish) timeout on an error node if
- * the error was not a time out.
- */
- switch (hard_error) {
- case ETIMEDOUT:
- case EWOULDBLOCK:
- cp->mp->am_timeo = 17;
- break;
- default:
- cp->mp->am_timeo = 5;
- break;
- }
- new_ttl(cp->mp);
- }
-
- /*
- * Make sure that the error value in the mntfs has a
- * reasonable value.
- */
- if (mf->mf_error < 0) {
- mf->mf_error = hard_error;
- if (hard_error)
- mf->mf_flags |= MFF_ERROR;
- }
-
- /*
- * In any case we don't need the continuation any more
- */
- free_continuation(cp);
-
- return hard_error;
-}
-
-
-/*
- * Automount interface to RPC lookup routine
- * Find the corresponding entry and return
- * the file handle for it.
- */
-am_node *
-autofs_lookuppn(am_node *mp, char *fname, int *error_return, int op)
-{
- am_node *ap, *new_mp, *ap_hung;
- char *info; /* Mount info - where to get the file system */
- char **ivec, **xivec; /* Split version of info */
- char *auto_opts; /* Automount options */
- int error = 0; /* Error so far */
- char path_name[MAXPATHLEN]; /* General path name buffer */
- char apath[MAXPATHLEN]; /* autofs path (added space) */
- char *pfname; /* Path for database lookup */
- struct continuation *cp; /* Continuation structure if need to mount */
- int in_progress = 0; /* # of (un)mount in progress */
- char *dflts;
- mntfs *mf;
-
-#ifdef DEBUG
- dlog("in autofs_lookuppn");
-#endif /* DEBUG */
-
- /*
- * If the server is shutting down
- * then don't return information
- * about the mount point.
- */
- if (amd_state == Finishing) {
-#ifdef DEBUG
- if ((mf = mp->am_mnt) == 0 || mf->mf_ops == &amfs_direct_ops) {
- dlog("%s mount ignored - going down", fname);
- } else {
- dlog("%s/%s mount ignored - going down", mp->am_path, fname);
- }
-#endif /* DEBUG */
- ereturn(ENOENT);
- }
-
- /*
- * Handle special case of "." and ".."
- */
- if (fname[0] == '.') {
- if (fname[1] == '\0')
- return mp; /* "." is the current node */
- if (fname[1] == '.' && fname[2] == '\0') {
- if (mp->am_parent) {
-#ifdef DEBUG
- dlog(".. in %s gives %s", mp->am_path, mp->am_parent->am_path);
-#endif /* DEBUG */
- return mp->am_parent; /* ".." is the parent node */
- }
- ereturn(ESTALE);
- }
- }
-
- /*
- * Check for valid key name.
- * If it is invalid then pretend it doesn't exist.
- */
- if (!valid_key(fname)) {
- plog(XLOG_WARNING, "Key \"%s\" contains a disallowed character", fname);
- ereturn(ENOENT);
- }
-
- /*
- * Expand key name.
- * fname is now a private copy.
- */
- fname = expand_key(fname);
-
- for (ap_hung = 0, ap = mp->am_child; ap; ap = ap->am_osib) {
- /*
- * Otherwise search children of this node
- */
- if (FSTREQ(ap->am_name, fname)) {
- mf = ap->am_mnt;
- if (ap->am_error) {
- error = ap->am_error;
- continue;
- }
- /*
- * If the error code is undefined then it must be
- * in progress.
- */
- if (mf->mf_error < 0)
- goto in_progrss;
-
- /*
- * Check for a hung node
- */
- if (FSRV_ISDOWN(mf->mf_server)) {
-#ifdef DEBUG
- dlog("server hung");
-#endif /* DEBUG */
- error = ap->am_error;
- ap_hung = ap;
- continue;
- }
- /*
- * If there was a previous error with this node
- * then return that error code.
- */
- if (mf->mf_flags & MFF_ERROR) {
- error = mf->mf_error;
- continue;
- }
- if (!(mf->mf_flags & MFF_MOUNTED) || (mf->mf_flags & MFF_UNMOUNTING)) {
- in_progrss:
- /*
- * If the fs is not mounted or it is unmounting then there
- * is a background (un)mount in progress. In this case
- * we just drop the RPC request (return nil) and
- * wait for a retry, by which time the (un)mount may
- * have completed.
- */
-#ifdef DEBUG
- dlog("ignoring mount of %s in %s -- flags (%x) in progress",
- fname, mf->mf_mount, mf->mf_flags);
-#endif /* DEBUG */
- in_progress++;
- continue;
- }
-
- /*
- * Otherwise we have a hit: return the current mount point.
- */
-#ifdef DEBUG
- dlog("matched %s in %s", fname, ap->am_path);
-#endif /* DEBUG */
- XFREE(fname);
- return ap;
- }
- }
-
- if (in_progress) {
-#ifdef DEBUG
- dlog("Waiting while %d mount(s) in progress", in_progress);
-#endif /* DEBUG */
- XFREE(fname);
- ereturn(-1);
- }
-
- /*
- * If an error occurred then return it.
- */
- if (error) {
-#ifdef DEBUG
- errno = error; /* XXX */
- dlog("Returning error: %m");
-#endif /* DEBUG */
- XFREE(fname);
- ereturn(error);
- }
-
- /*
- * If doing a delete then don't create again!
- */
- switch (op) {
- case VLOOK_DELETE:
- ereturn(ENOENT);
-
- case VLOOK_CREATE:
- break;
-
- default:
- plog(XLOG_FATAL, "Unknown op to autofs_lookuppn: 0x%x", op);
- ereturn(EINVAL);
- }
-
- /*
- * If the server is going down then just return,
- * don't try to mount any more file systems
- */
- if ((int) amd_state >= (int) Finishing) {
-#ifdef DEBUG
- dlog("not found - server going down anyway");
-#endif /* DEBUG */
- XFREE(fname);
- ereturn(ENOENT);
- }
-
- /*
- * If we get there then this is a reference to an,
- * as yet, unknown name so we need to search the mount
- * map for it.
- */
- if (mp->am_pref) {
- sprintf(path_name, "%s%s", mp->am_pref, fname);
- pfname = path_name;
- } else {
- pfname = fname;
- }
-
- mf = mp->am_mnt;
-
-#ifdef DEBUG
- dlog("will search map info in %s to find %s", mf->mf_info, pfname);
-#endif /* DEBUG */
- /*
- * Consult the oracle for some mount information.
- * info is malloc'ed and belongs to this routine.
- * It ends up being free'd in free_continuation().
- *
- * Note that this may return -1 indicating that information
- * is not yet available.
- */
- error = mapc_search((mnt_map *) mf->mf_private, pfname, &info);
- if (error) {
- if (error > 0)
- plog(XLOG_MAP, "No map entry for %s", pfname);
- else
- plog(XLOG_MAP, "Waiting on map entry for %s", pfname);
- XFREE(fname);
- ereturn(error);
- }
-#ifdef DEBUG
- dlog("mount info is %s", info);
-#endif /* DEBUG */
-
- /*
- * Split info into an argument vector.
- * The vector is malloc'ed and belongs to
- * this routine. It is free'd in free_continuation()
- */
- xivec = ivec = strsplit(info, ' ', '\"');
-
- /*
- * Default error code...
- */
- if (ap_hung)
- error = EWOULDBLOCK;
- else
- error = ENOENT;
-
- /*
- * Allocate a new map
- */
- new_mp = exported_ap_alloc();
- if (new_mp == 0) {
- XFREE(xivec);
- XFREE(info);
- XFREE(fname);
- ereturn(ENOSPC);
- }
- if (mf->mf_auto)
- auto_opts = mf->mf_auto;
- else
- auto_opts = "";
-
- auto_opts = strdup(auto_opts);
-
-#ifdef DEBUG
- dlog("searching for /defaults entry");
-#endif /* DEBUG */
- if (mapc_search((mnt_map *) mf->mf_private, "/defaults", &dflts) == 0) {
- char *dfl;
- char **rvec;
-#ifdef DEBUG
- dlog("/defaults gave %s", dflts);
-#endif /* DEBUG */
- if (*dflts == '-')
- dfl = dflts + 1;
- else
- dfl = dflts;
-
- /*
- * Chop the defaults up
- */
- rvec = strsplit(dfl, ' ', '\"');
-
- if (gopt.flags & CFM_SELECTORS_IN_DEFAULTS) {
- /*
- * Pick whichever first entry matched the list of selectors.
- * Strip the selectors from the string, and assign to dfl the
- * rest of the string.
- */
- if (rvec) {
- am_opts ap;
- am_ops *pt;
- char **sp = rvec;
- while (*sp) { /* loop until you find something, if any */
- memset((char *) &ap, 0, sizeof(am_opts));
- pt = ops_match(&ap, *sp, "", mp->am_path, "/defaults",
- mp->am_parent->am_mnt->mf_info);
- free_opts(&ap); /* don't leak */
- if (pt == &amfs_error_ops) {
- plog(XLOG_MAP, "did not match defaults for \"%s\"", *sp);
- } else {
- dfl = strip_selectors(*sp, "/defaults");
- plog(XLOG_MAP, "matched default selectors \"%s\"", dfl);
- break;
- }
- ++sp;
- }
- }
- } else { /* not selectors_in_defaults */
- /*
- * Extract first value
- */
- dfl = rvec[0];
- }
-
- /*
- * If there were any values at all...
- */
- if (dfl) {
- /*
- * Log error if there were other values
- */
- if (!(gopt.flags & CFM_SELECTORS_IN_DEFAULTS) && rvec[1]) {
-# ifdef DEBUG
- dlog("/defaults chopped into %s", dfl);
-# endif /* DEBUG */
- plog(XLOG_USER, "More than a single value for /defaults in %s", mf->mf_info);
- }
-
- /*
- * Prepend to existing defaults if they exist,
- * otherwise just use these defaults.
- */
- if (*auto_opts && *dfl) {
- char *nopts = (char *) xmalloc(strlen(auto_opts) + strlen(dfl) + 2);
- sprintf(nopts, "%s;%s", dfl, auto_opts);
- XFREE(auto_opts);
- auto_opts = nopts;
- } else if (*dfl) {
- auto_opts = strealloc(auto_opts, dfl);
- }
- }
- XFREE(dflts);
- /*
- * Don't need info vector any more
- */
- XFREE(rvec);
- }
-
- /*
- * Fill it in
- */
- init_map(new_mp, fname);
-
- /*
- * Turn on autofs flag if needed.
- */
- if (mp->am_flags & AMF_AUTOFS) {
- new_mp->am_flags |= AMF_AUTOFS;
- }
-
- /*
- * Put it in the table
- */
- insert_am(new_mp, mp);
-
- /*
- * Fill in some other fields,
- * path and mount point.
- *
- * bugfix: do not prepend old am_path if direct map
- * <wls@astro.umd.edu> William Sebok
- */
-
- strcpy(apath, fname);
- strcat(apath, " ");
- new_mp->am_path = str3cat(new_mp->am_path,
- mf->mf_ops == &amfs_direct_ops ? "" : mp->am_path,
- *fname == '/' ? "" : "/",
- apath);
-
-#ifdef DEBUG
- dlog("setting path to \"%s\"", new_mp->am_path);
-#endif /* DEBUG */
-
- /*
- * Take private copy of pfname
- */
- pfname = strdup(pfname);
-
- /*
- * Construct a continuation
- */
- cp = ALLOC(struct continuation);
- cp->callout = 0;
- cp->mp = new_mp;
- cp->xivec = xivec;
- cp->ivec = ivec;
- cp->info = info;
- cp->key = pfname;
- cp->auto_opts = auto_opts;
- cp->retry = FALSE;
- cp->tried = FALSE;
- cp->start = clocktime();
- cp->def_opts = strdup(auto_opts);
- memset((voidp) &cp->fs_opts, 0, sizeof(cp->fs_opts));
-
- /*
- * Try and mount the file system. If this succeeds immediately (possible
- * for a ufs file system) then return the attributes, otherwise just
- * return an error.
- */
- error = autofs_bgmount(cp, error);
- reschedule_timeout_mp();
- if (!error) {
- XFREE(fname);
- return new_mp;
- }
-
- /*
- * Code for quick reply. If nfs_program_2_transp is set, then
- * its the transp that's been passed down from nfs_program_2().
- * If new_mp->am_transp is not already set, set it by copying in
- * nfs_program_2_transp. Once am_transp is set, quick_reply() can
- * use it to send a reply to the client that requested this mount.
- */
- if (nfs_program_2_transp && !new_mp->am_transp) {
- new_mp->am_transp = (SVCXPRT *) xmalloc(sizeof(SVCXPRT));
- *(new_mp->am_transp) = *nfs_program_2_transp;
- }
- if (error && (new_mp->am_mnt->mf_ops == &amfs_error_ops))
- new_mp->am_error = error;
-
- assign_error_mntfs(new_mp);
-
- XFREE(fname);
-
- ereturn(error);
-}
-#endif /* HAVE_FS_AUTOFS */
diff --git a/contrib/amd/amd/srvr_nfs.c b/contrib/amd/amd/srvr_nfs.c
index 48e0789..d745519 100644
--- a/contrib/amd/amd/srvr_nfs.c
+++ b/contrib/amd/amd/srvr_nfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2004 Erez Zadok
+ * Copyright (c) 1997-2003 Erez Zadok
* Copyright (c) 1990 Jan-Simon Pendry
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
* Copyright (c) 1990 The Regents of the University of California.
@@ -38,7 +38,8 @@
*
* %W% (Berkeley) %G%
*
- * $Id: srvr_nfs.c,v 1.7.2.11 2004/01/06 03:15:16 ezk Exp $
+ * $Id: srvr_nfs.c,v 1.7.2.10 2002/12/29 01:55:43 ib42 Exp $
+ * $FreeBSD$
*
*/
OpenPOWER on IntegriCloud