138494Sobrien/*
2174313Sobrien * Copyright (c) 1997-2006 Erez Zadok
338494Sobrien * Copyright (c) 1990 Jan-Simon Pendry
438494Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
538494Sobrien * Copyright (c) 1990 The Regents of the University of California.
638494Sobrien * All rights reserved.
738494Sobrien *
838494Sobrien * This code is derived from software contributed to Berkeley by
938494Sobrien * Jan-Simon Pendry at Imperial College, London.
1038494Sobrien *
1138494Sobrien * Redistribution and use in source and binary forms, with or without
1238494Sobrien * modification, are permitted provided that the following conditions
1338494Sobrien * are met:
1438494Sobrien * 1. Redistributions of source code must retain the above copyright
1538494Sobrien *    notice, this list of conditions and the following disclaimer.
1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1738494Sobrien *    notice, this list of conditions and the following disclaimer in the
1838494Sobrien *    documentation and/or other materials provided with the distribution.
1938494Sobrien * 3. All advertising materials mentioning features or use of this software
2042629Sobrien *    must display the following acknowledgment:
2138494Sobrien *      This product includes software developed by the University of
2238494Sobrien *      California, Berkeley and its contributors.
2338494Sobrien * 4. Neither the name of the University nor the names of its contributors
2438494Sobrien *    may be used to endorse or promote products derived from this software
2538494Sobrien *    without specific prior written permission.
2638494Sobrien *
2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3038494Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3738494Sobrien * SUCH DAMAGE.
3838494Sobrien *
3938494Sobrien *
40174313Sobrien * File: am-utils/libamu/mount_fs.c
4138494Sobrien *
4238494Sobrien */
4338494Sobrien
4438494Sobrien#ifdef HAVE_CONFIG_H
4538494Sobrien# include <config.h>
4638494Sobrien#endif /* HAVE_CONFIG_H */
4738494Sobrien#include <am_defs.h>
4838494Sobrien#include <amu.h>
4938494Sobrien
5038494Sobrien
5138494Sobrien/* ensure that mount table options are delimited by a comma */
52174313Sobrien#define append_opts(old, l, new) { \
53174313Sobrien	if (*(old) != '\0') \
54174313Sobrien	  xstrlcat(old, ",", l); \
55174313Sobrien	xstrlcat(old, new, l); }
5638494Sobrien
5738494Sobrien/*
5838494Sobrien * Standard mount flags
5938494Sobrien */
6038494Sobrienstruct opt_tab mnt_flags[] =
6138494Sobrien{
6238494Sobrien#if defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO)
6338494Sobrien  {MNTTAB_OPT_RO, MNT2_GEN_OPT_RDONLY},
6438494Sobrien#endif /* defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO) */
6538494Sobrien
6638494Sobrien#if defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE)
6738494Sobrien  {MNTTAB_OPT_NOCACHE, MNT2_GEN_OPT_NOCACHE},
6838494Sobrien#endif /* defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE) */
6938494Sobrien
7038494Sobrien  /* the "grpid" mount option can be offered as generic of NFS */
7138494Sobrien#ifdef MNTTAB_OPT_GRPID
7238494Sobrien# ifdef MNT2_GEN_OPT_GRPID
7338494Sobrien  {MNTTAB_OPT_GRPID, MNT2_GEN_OPT_GRPID},
7438494Sobrien# endif /* MNT2_GEN_OPT_GRPID */
7538494Sobrien# ifdef MNT2_NFS_OPT_GRPID
7638494Sobrien  {MNTTAB_OPT_GRPID, MNT2_NFS_OPT_GRPID},
7738494Sobrien# endif /* MNT2_NFS_OPT_GRPID */
7838494Sobrien#endif /* MNTTAB_OPT_GRPID */
7938494Sobrien
8038494Sobrien#if defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI)
8138494Sobrien  {MNTTAB_OPT_MULTI, MNT2_GEN_OPT_MULTI},
8238494Sobrien#endif /* defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI) */
8338494Sobrien
8438494Sobrien#if defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV)
8538494Sobrien  {MNTTAB_OPT_NODEV, MNT2_GEN_OPT_NODEV},
8638494Sobrien#endif /* defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV) */
8738494Sobrien
8838494Sobrien#if defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC)
8938494Sobrien  {MNTTAB_OPT_NOEXEC, MNT2_GEN_OPT_NOEXEC},
9038494Sobrien#endif /* defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC) */
9138494Sobrien
9238494Sobrien#if defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB)
9338494Sobrien  {MNTTAB_OPT_NOSUB, MNT2_GEN_OPT_NOSUB},
9438494Sobrien#endif /* defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB) */
9538494Sobrien
9638494Sobrien#if defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID)
9738494Sobrien  {MNTTAB_OPT_NOSUID, MNT2_GEN_OPT_NOSUID},
9838494Sobrien#endif /* defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID) */
9938494Sobrien
10038494Sobrien#if defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC)
10138494Sobrien  {MNTTAB_OPT_SYNC, MNT2_GEN_OPT_SYNC},
10238494Sobrien#endif /* defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC) */
10338494Sobrien
10438494Sobrien#if defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY)
10538494Sobrien  {MNTTAB_OPT_OVERLAY, MNT2_GEN_OPT_OVERLAY},
10638494Sobrien#endif /* defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY) */
10738494Sobrien
108119682Smbr  /*
109119682Smbr   * Do not define MNT2_NFS_OPT_* entries here!  This is for generic
110174313Sobrien   * mount(2) options only, not for NFS mount options.  If you need to put
111174313Sobrien   * something here, it's probably not the right place: see
112174313Sobrien   * include/am_compat.h.
113119682Smbr   */
11482809Sobrien
11538494Sobrien  {0, 0}
11638494Sobrien};
11738494Sobrien
11838494Sobrien
11951300Sobrien/* compute generic mount flags */
12038494Sobrienint
12138494Sobriencompute_mount_flags(mntent_t *mntp)
12238494Sobrien{
12338494Sobrien  struct opt_tab *opt;
124119682Smbr  int flags = 0;
12538494Sobrien
12638494Sobrien#ifdef MNT2_GEN_OPT_NEWTYPE
127174313Sobrien  flags |= MNT2_GEN_OPT_NEWTYPE;
128119682Smbr#endif /* MNT2_GEN_OPT_NEWTYPE */
129119682Smbr#ifdef MNT2_GEN_OPT_AUTOMOUNTED
130119682Smbr  flags |= MNT2_GEN_OPT_AUTOMOUNTED;
131119682Smbr#endif /* not MNT2_GEN_OPT_AUTOMOUNTED */
13238494Sobrien
13338494Sobrien  /*
13438494Sobrien   * Crack basic mount options
13538494Sobrien   */
13638494Sobrien  for (opt = mnt_flags; opt->opt; opt++) {
137174313Sobrien    flags |= amu_hasmntopt(mntp, opt->opt) ? opt->flag : 0;
13838494Sobrien  }
13938494Sobrien
14038494Sobrien  return flags;
14138494Sobrien}
14238494Sobrien
14338494Sobrien
14451300Sobrien/* compute generic mount flags for automounter mounts */
14538494Sobrienint
14651300Sobriencompute_automounter_mount_flags(mntent_t *mntp)
14751300Sobrien{
14851300Sobrien  int flags = 0;
14951300Sobrien
15051300Sobrien#ifdef MNT2_GEN_OPT_IGNORE
15151300Sobrien  flags |= MNT2_GEN_OPT_IGNORE;
15251300Sobrien#endif /* not MNT2_GEN_OPT_IGNORE */
15351595Sobrien#ifdef MNT2_GEN_OPT_AUTOMNTFS
15451595Sobrien  flags |= MNT2_GEN_OPT_AUTOMNTFS;
15551595Sobrien#endif /* not MNT2_GEN_OPT_AUTOMNTFS */
15651300Sobrien
15751300Sobrien  return flags;
15851300Sobrien}
15951300Sobrien
16051300Sobrien
16151300Sobrienint
162174313Sobrienmount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, u_long nfs_version, const char *nfs_proto, const char *mnttabname, int on_autofs)
16338494Sobrien{
16438494Sobrien  int error = 0;
16538494Sobrien#ifdef MOUNT_TABLE_ON_FILE
16638494Sobrien  char *zopts = NULL, *xopts = NULL;
167174313Sobrien  size_t l;
16838494Sobrien#endif /* MOUNT_TABLE_ON_FILE */
169174313Sobrien  char *mnt_dir = 0;
17038494Sobrien
171174313Sobrien#ifdef NEED_AUTOFS_SPACE_HACK
172174313Sobrien  char *old_mnt_dir = 0;
173174313Sobrien  /* perform space hack */
174174313Sobrien  if (on_autofs) {
175174313Sobrien    old_mnt_dir = mnt->mnt_dir;
176174313Sobrien    mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir);
177174313Sobrien  } else
178174313Sobrien#endif /* NEED_AUTOFS_SPACE_HACK */
179174313Sobrien    mnt_dir = strdup(mnt->mnt_dir);
18038494Sobrien
181174313Sobrien  dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)",
182174313Sobrien       mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
183174313Sobrien
18438494Sobrienagain:
18538494Sobrien  error = MOUNT_TRAP(type, mnt, flags, mnt_data);
18638494Sobrien
18738494Sobrien  if (error < 0) {
188174313Sobrien    plog(XLOG_ERROR, "'%s': mount: %m", mnt_dir);
18938494Sobrien    /*
19038494Sobrien     * The following code handles conditions which shouldn't
19138494Sobrien     * occur.  They are possible either because amd screws up
19238494Sobrien     * in preparing for the mount, or because some human
19338494Sobrien     * messed with the mount point.  Both have been known to
19438494Sobrien     * happen. -- stolcke 2/22/95
19538494Sobrien     */
196174313Sobrien    if (errno == EBUSY) {
19738494Sobrien      /*
19838494Sobrien       * Also, sometimes unmount isn't called, e.g., because
19938494Sobrien       * our mountlist is garbled.  This leaves old mount
20038494Sobrien       * points around which need to be removed before we
20138494Sobrien       * can mount something new in their place.
20238494Sobrien       */
203174313Sobrien      errno = umount_fs(mnt_dir, mnttabname, on_autofs);
20438494Sobrien      if (errno != 0)
205174313Sobrien	plog(XLOG_ERROR, "'%s': umount: %m", mnt_dir);
20638494Sobrien      else {
207174313Sobrien	plog(XLOG_WARNING, "extra umount required for '%s'", mnt_dir);
20838494Sobrien	error = MOUNT_TRAP(type, mnt, flags, mnt_data);
20938494Sobrien      }
21038494Sobrien    }
21138494Sobrien  }
21238494Sobrien
21338494Sobrien  if (error < 0 && --retry > 0) {
21438494Sobrien    sleep(1);
21538494Sobrien    goto again;
21638494Sobrien  }
217174313Sobrien
218174313Sobrien#ifdef NEED_AUTOFS_SPACE_HACK
219174313Sobrien  /* Undo space hack */
220174313Sobrien  if (on_autofs)
221174313Sobrien    mnt->mnt_dir = old_mnt_dir;
222174313Sobrien#endif /* NEED_AUTOFS_SPACE_HACK */
223174313Sobrien
22438494Sobrien  if (error < 0) {
225174313Sobrien    error = errno;
226174313Sobrien    goto out;
22738494Sobrien  }
22838494Sobrien
22938494Sobrien#ifdef MOUNT_TABLE_ON_FILE
23038494Sobrien  /*
23138494Sobrien   * Allocate memory for options:
23238494Sobrien   *        dev=..., vers={2,3}, proto={tcp,udp}
23338494Sobrien   */
234174313Sobrien  l = strlen(mnt->mnt_opts) + 48;
235174313Sobrien  zopts = (char *) xmalloc(l);
23638494Sobrien
23738494Sobrien  /* copy standard options */
23838494Sobrien  xopts = mnt->mnt_opts;
23938494Sobrien
240174313Sobrien  xstrlcpy(zopts, xopts, l);
24138494Sobrien
24238494Sobrien# ifdef MNTTAB_OPT_DEV
243174313Sobrien  {
244174313Sobrien    /* add the extra dev= field to the mount table */
245174313Sobrien    struct stat stb;
246174313Sobrien    if (lstat(mnt_dir, &stb) == 0) {
247174313Sobrien      char optsbuf[48];
248174313Sobrien      if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */
249174313Sobrien	xsnprintf(optsbuf, sizeof(optsbuf), "%s=%04lx",
250174313Sobrien		  MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff);
251174313Sobrien      else			/* e.g. System Vr4 */
252174313Sobrien	xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx",
253174313Sobrien		  MNTTAB_OPT_DEV, (u_long) stb.st_dev);
254174313Sobrien      append_opts(zopts, l, optsbuf);
255174313Sobrien    }
25638494Sobrien  }
25738494Sobrien# endif /* MNTTAB_OPT_DEV */
25838494Sobrien
25938494Sobrien# if defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)
26038494Sobrien  /*
26138494Sobrien   * add the extra vers={2,3} field to the mount table,
26238494Sobrien   * unless already specified by user
26338494Sobrien   */
26438494Sobrien   if (nfs_version == NFS_VERSION3 &&
26538494Sobrien       hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) {
266174313Sobrien     char optsbuf[48];
267174313Sobrien     xsnprintf(optsbuf, sizeof(optsbuf),
268174313Sobrien	       "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3);
269174313Sobrien     append_opts(zopts, l, optsbuf);
27038494Sobrien   }
27138494Sobrien# endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */
27238494Sobrien
27338494Sobrien# ifdef MNTTAB_OPT_PROTO
27438494Sobrien  /*
27538494Sobrien   * add the extra proto={tcp,udp} field to the mount table,
27638494Sobrien   * unless already specified by user.
27738494Sobrien   */
278174313Sobrien  if (nfs_proto && !amu_hasmntopt(mnt, MNTTAB_OPT_PROTO)) {
279174313Sobrien    char optsbuf[48];
280174313Sobrien    xsnprintf(optsbuf, sizeof(optsbuf), "%s=%s", MNTTAB_OPT_PROTO, nfs_proto);
281174313Sobrien    append_opts(zopts, l, optsbuf);
28238494Sobrien  }
28338494Sobrien# endif /* MNTTAB_OPT_PROTO */
28438494Sobrien
28538494Sobrien  /* finally, store the options into the mount table structure */
28638494Sobrien  mnt->mnt_opts = zopts;
28738494Sobrien
28838494Sobrien  /*
28938494Sobrien   * Additional fields in mntent_t
29038494Sobrien   * are fixed up here
29138494Sobrien   */
292119682Smbr# ifdef HAVE_MNTENT_T_MNT_CNODE
29338494Sobrien  mnt->mnt_cnode = 0;
294119682Smbr# endif /* HAVE_MNTENT_T_MNT_CNODE */
29538494Sobrien
296119682Smbr# ifdef HAVE_MNTENT_T_MNT_RO
297174313Sobrien  mnt->mnt_ro = (amu_hasmntopt(mnt, MNTTAB_OPT_RO) != NULL);
298119682Smbr# endif /* HAVE_MNTENT_T_MNT_RO */
29938494Sobrien
300119682Smbr# ifdef HAVE_MNTENT_T_MNT_TIME
301119682Smbr#  ifdef HAVE_MNTENT_T_MNT_TIME_STRING
30238494Sobrien  {				/* allocate enough space for a long */
303174313Sobrien    size_t l = 13 * sizeof(char);
304174313Sobrien    char *str = (char *) xmalloc(l);
305174313Sobrien    xsnprintf(str, l, "%ld", time((time_t *) NULL));
30638494Sobrien    mnt->mnt_time = str;
30738494Sobrien  }
308119682Smbr#  else /* not HAVE_MNTENT_T_MNT_TIME_STRING */
30938494Sobrien  mnt->mnt_time = time((time_t *) NULL);
310119682Smbr#  endif /* not HAVE_MNTENT_T_MNT_TIME_STRING */
311119682Smbr# endif /* HAVE_MNTENT_T_MNT_TIME */
31238494Sobrien
31338494Sobrien  write_mntent(mnt, mnttabname);
31438494Sobrien
31538494Sobrien# ifdef MNTTAB_OPT_DEV
31638494Sobrien  if (xopts) {
31738494Sobrien    XFREE(mnt->mnt_opts);
31838494Sobrien    mnt->mnt_opts = xopts;
31938494Sobrien  }
32038494Sobrien# endif /* MNTTAB_OPT_DEV */
32138494Sobrien#endif /* MOUNT_TABLE_ON_FILE */
32238494Sobrien
323174313Sobrien out:
324174313Sobrien  XFREE(mnt_dir);
325174313Sobrien  return error;
32638494Sobrien}
32738494Sobrien
32838494Sobrien
32938494Sobrien/*
330174313Sobrien * Compute all NFS attribute cache related flags separately.  Note that this
331174313Sobrien * function now computes attribute-cache flags for both Amd's automount
332174313Sobrien * points (NFS) as well as any normal NFS mount that Amd performs.  Edit
333174313Sobrien * with caution.
334174313Sobrien */
335174313Sobrienstatic void
336174313Sobriencompute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp)
337174313Sobrien{
338174313Sobrien  int acval = 0;
339174313Sobrien  int err_acval = 1;		/* 1 means we found no 'actimeo' value */
340174313Sobrien#if defined(HAVE_NFS_ARGS_T_ACREGMIN) || defined(HAVE_NFS_ARGS_T_ACREGMAX) || defined(HAVE_NFS_ARGS_T_ACDIRMIN) || defined(HAVE_NFS_ARGS_T_ACDIRMAX)
341174313Sobrien  int err_acrdmm;		/* for ac{reg,dir}{min,max} */
342174313Sobrien#endif /* HAVE_NFS_ARGS_T_AC{REG,DIR}{MIN,MAX} */
343174313Sobrien
344174313Sobrien  /************************************************************************/
345174313Sobrien  /***	ATTRIBUTE CACHES						***/
346174313Sobrien  /************************************************************************/
347174313Sobrien  /*
348174313Sobrien   * acval is set to 0 at the top of the function.  If actimeo mount option
349174313Sobrien   * exists and defined in mntopts, then its acval is set to it.
350174313Sobrien   * If the value is non-zero, then we set all attribute cache fields to it.
351174313Sobrien   * If acval is zero, it means it was never defined in mntopts or the
352174313Sobrien   * actimeo mount option does not exist, in which case we check for
353174313Sobrien   * individual mount options per attribute cache.
354174313Sobrien   * Regardless of the value of acval, mount flags are set based directly
355174313Sobrien   * on the values of the attribute caches.
356174313Sobrien   */
357174313Sobrien#ifdef MNTTAB_OPT_ACTIMEO
358174313Sobrien  err_acval = hasmntvalerr(mntp, MNTTAB_OPT_ACTIMEO, &acval);	/* attr cache timeout (sec) */
359174313Sobrien#endif /* MNTTAB_OPT_ACTIMEO */
360174313Sobrien
361174313Sobrien  /*** acregmin ***/
362174313Sobrien#ifdef HAVE_NFS_ARGS_T_ACREGMIN
363174313Sobrien  err_acrdmm = 1;		/* 1 means we found no acregmin value */
364174313Sobrien  if (!err_acval) {
365174313Sobrien    nap->acregmin = acval;	/* min ac timeout for reg files (sec) */
366174313Sobrien  } else {
367174313Sobrien# ifdef MNTTAB_OPT_ACREGMIN
368174313Sobrien    err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, (int *) &nap->acregmin);
369174313Sobrien# else /* not MNTTAB_OPT_ACREGMIN */
370174313Sobrien    nap->acregmin = 0;
371174313Sobrien# endif /* not MNTTAB_OPT_ACREGMIN */
372174313Sobrien  }
373174313Sobrien  /* set this flag iff we changed acregmin (possibly to zero) */
374174313Sobrien# ifdef MNT2_NFS_OPT_ACREGMIN
375174313Sobrien  if (!err_acval || !err_acrdmm)
376174313Sobrien    nap->flags |= MNT2_NFS_OPT_ACREGMIN;
377174313Sobrien# endif /* MNT2_NFS_OPT_ACREGMIN */
378174313Sobrien#endif /* HAVE_NFS_ARGS_T_ACREGMIN */
379174313Sobrien
380174313Sobrien  /*** acregmax ***/
381174313Sobrien#ifdef HAVE_NFS_ARGS_T_ACREGMAX
382174313Sobrien  err_acrdmm = 1;		/* 1 means we found no acregmax value */
383174313Sobrien  if (!err_acval) {
384174313Sobrien    nap->acregmax = acval;	/* max ac timeout for reg files (sec) */
385174313Sobrien  } else {
386174313Sobrien# ifdef MNTTAB_OPT_ACREGMAX
387174313Sobrien    err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, (int *) &nap->acregmax);
388174313Sobrien# else /* not MNTTAB_OPT_ACREGMAX */
389174313Sobrien    nap->acregmax = 0;
390174313Sobrien# endif /* not MNTTAB_OPT_ACREGMAX */
391174313Sobrien  }
392174313Sobrien  /* set this flag iff we changed acregmax (possibly to zero) */
393174313Sobrien# ifdef MNT2_NFS_OPT_ACREGMAX
394174313Sobrien  if (!err_acval || !err_acrdmm)
395174313Sobrien    nap->flags |= MNT2_NFS_OPT_ACREGMAX;
396174313Sobrien# endif /* MNT2_NFS_OPT_ACREGMAX */
397174313Sobrien#endif /* HAVE_NFS_ARGS_T_ACREGMAX */
398174313Sobrien
399174313Sobrien  /*** acdirmin ***/
400174313Sobrien#ifdef HAVE_NFS_ARGS_T_ACDIRMIN
401174313Sobrien  err_acrdmm = 1;		/* 1 means we found no acdirmin value */
402174313Sobrien  if (!err_acval) {
403174313Sobrien    nap->acdirmin = acval;	/* min ac timeout for dirs (sec) */
404174313Sobrien  } else {
405174313Sobrien# ifdef MNTTAB_OPT_ACDIRMIN
406174313Sobrien    err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, (int *) &nap->acdirmin);
407174313Sobrien# else /* not MNTTAB_OPT_ACDIRMIN */
408174313Sobrien    nap->acdirmin = 0;
409174313Sobrien# endif /* not MNTTAB_OPT_ACDIRMIN */
410174313Sobrien  }
411174313Sobrien  /* set this flag iff we changed acdirmin (possibly to zero) */
412174313Sobrien# ifdef MNT2_NFS_OPT_ACDIRMIN
413174313Sobrien  if (!err_acval || !err_acrdmm)
414174313Sobrien    nap->flags |= MNT2_NFS_OPT_ACDIRMIN;
415174313Sobrien# endif /* MNT2_NFS_OPT_ACDIRMIN */
416174313Sobrien#endif /* HAVE_NFS_ARGS_T_ACDIRMIN */
417174313Sobrien
418174313Sobrien  /*** acdirmax ***/
419174313Sobrien#ifdef HAVE_NFS_ARGS_T_ACDIRMAX
420174313Sobrien  err_acrdmm = 1;		/* 1 means we found no acdirmax value */
421174313Sobrien  if (!err_acval) {
422174313Sobrien    nap->acdirmax = acval;	/* max ac timeout for dirs (sec) */
423174313Sobrien  } else {
424174313Sobrien# ifdef MNTTAB_OPT_ACDIRMAX
425174313Sobrien    err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, (int *) &nap->acdirmax);
426174313Sobrien# else /* not MNTTAB_OPT_ACDIRMAX */
427174313Sobrien    nap->acdirmax = 0;
428174313Sobrien# endif /* not MNTTAB_OPT_ACDIRMAX */
429174313Sobrien  }
430174313Sobrien  /* set this flag iff we changed acdirmax (possibly to zero) */
431174313Sobrien# ifdef MNT2_NFS_OPT_ACDIRMAX
432174313Sobrien  if (!err_acval || !err_acrdmm)
433174313Sobrien    nap->flags |= MNT2_NFS_OPT_ACDIRMAX;
434174313Sobrien# endif /* MNT2_NFS_OPT_ACDIRMAX */
435174313Sobrien#endif /* HAVE_NFS_ARGS_T_ACDIRMAX */
436174313Sobrien
437174313Sobrien
438174313Sobrien  /* don't cache attributes */
439174313Sobrien#if defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC)
440174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_NOAC) != NULL)
441174313Sobrien    nap->flags |= MNT2_NFS_OPT_NOAC;
442174313Sobrien#endif /* defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) */
443174313Sobrien}
444174313Sobrien
445174313Sobrien
446174313Sobrien/*
44738494Sobrien * Fill in the many possible fields and flags of struct nfs_args.
44838494Sobrien *
44942629Sobrien * nap:		pre-allocated structure to fill in.
45038494Sobrien * mntp:	mount entry structure (includes options)
45138494Sobrien * genflags:	generic mount flags already determined
45238494Sobrien * nfsncp:	(TLI only) netconfig entry for this NFS mount
45338494Sobrien * ip_addr:	IP address of file server
45438494Sobrien * nfs_version:	2, 3, (4 in the future), or 0 if unknown
45538494Sobrien * nfs_proto:	"udp", "tcp", or NULL.
45638494Sobrien * fhp:		file handle structure pointer
45738494Sobrien * host_name:	name of remote NFS host
45838494Sobrien * fs_name:	remote file system name to mount
45938494Sobrien */
46038494Sobrienvoid
461174313Sobriencompute_nfs_args(nfs_args_t *nap,
462174313Sobrien		 mntent_t *mntp,
463174313Sobrien		 int genflags,
464174313Sobrien		 struct netconfig *nfsncp,
465174313Sobrien		 struct sockaddr_in *ip_addr,
466174313Sobrien		 u_long nfs_version,
467174313Sobrien		 char *nfs_proto,
468174313Sobrien		 am_nfs_handle_t *fhp,
469174313Sobrien		 char *host_name,
470174313Sobrien		 char *fs_name)
47138494Sobrien{
47238494Sobrien  /* initialize just in case */
47338494Sobrien  memset((voidp) nap, 0, sizeof(nfs_args_t));
47438494Sobrien
475174313Sobrien  /* compute all of the NFS attribute-cache flags */
476174313Sobrien  compute_nfs_attrcache_flags(nap, mntp);
477174313Sobrien
47838494Sobrien  /************************************************************************/
47938494Sobrien  /***	FILEHANDLE DATA AND LENGTH					***/
48038494Sobrien  /************************************************************************/
48138494Sobrien#ifdef HAVE_FS_NFS3
48238494Sobrien  if (nfs_version == NFS_VERSION3) {
483119682Smbr# if defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN)
48438494Sobrien    /*
48538494Sobrien     * Some systems (Irix/bsdi3) have a separate field in nfs_args for
48638494Sobrien     * the length of the file handle for NFS V3.  They insist that
48738494Sobrien     * the file handle set in nfs_args be plain bytes, and not
48838494Sobrien     * include the length field.
48938494Sobrien     */
490174313Sobrien    NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3.am_fh3_data);
491119682Smbr# else /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
492174313Sobrien    NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3);
493119682Smbr# endif /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
49438494Sobrien# ifdef MNT2_NFS_OPT_NFSV3
49538494Sobrien    nap->flags |= MNT2_NFS_OPT_NFSV3;
49638494Sobrien# endif /* MNT2_NFS_OPT_NFSV3 */
49782809Sobrien# ifdef MNT2_NFS_OPT_VER3
49882809Sobrien    nap->flags |= MNT2_NFS_OPT_VER3;
49982809Sobrien# endif /* MNT2_NFS_OPT_VER3 */
50038494Sobrien  } else
50138494Sobrien#endif /* HAVE_FS_NFS3 */
502174313Sobrien    NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v2);
50338494Sobrien
504119682Smbr#ifdef HAVE_NFS_ARGS_T_FHSIZE
50538494Sobrien# ifdef HAVE_FS_NFS3
50638494Sobrien  if (nfs_version == NFS_VERSION3)
507174313Sobrien    nap->fhsize = fhp->v3.am_fh3_length;
50838494Sobrien  else
50938494Sobrien# endif /* HAVE_FS_NFS3 */
51038494Sobrien    nap->fhsize = FHSIZE;
511119682Smbr#endif /* HAVE_NFS_ARGS_T_FHSIZE */
51238494Sobrien
51338494Sobrien  /* this is the version of the nfs_args structure, not of NFS! */
514119682Smbr#ifdef HAVE_NFS_ARGS_T_FH_LEN
51538494Sobrien# ifdef HAVE_FS_NFS3
51638494Sobrien  if (nfs_version == NFS_VERSION3)
517174313Sobrien    nap->fh_len = fhp->v3.am_fh3_length;
51838494Sobrien  else
51938494Sobrien# endif /* HAVE_FS_NFS3 */
52038494Sobrien    nap->fh_len = FHSIZE;
521119682Smbr#endif /* HAVE_NFS_ARGS_T_FH_LEN */
52238494Sobrien
52338494Sobrien  /************************************************************************/
52438494Sobrien  /***	HOST NAME							***/
52538494Sobrien  /************************************************************************/
526174313Sobrien  /*
527174313Sobrien   * XXX: warning, using xstrlcpy in NFS_HN_DREF, which may corrupt a
528174313Sobrien   * struct nfs_args, or truncate our concocted "hostname:/path"
529174313Sobrien   * string prematurely.
530174313Sobrien   */
53138494Sobrien  NFS_HN_DREF(nap->hostname, host_name);
53238494Sobrien#ifdef MNT2_NFS_OPT_HOSTNAME
53338494Sobrien  nap->flags |= MNT2_NFS_OPT_HOSTNAME;
53438494Sobrien#endif /* MNT2_NFS_OPT_HOSTNAME */
53538494Sobrien
53638494Sobrien  /************************************************************************/
53738494Sobrien  /***	IP ADDRESS OF REMOTE HOST					***/
53838494Sobrien  /************************************************************************/
53938494Sobrien  if (ip_addr) {
54038494Sobrien#ifdef HAVE_TRANSPORT_TYPE_TLI
54138494Sobrien    nap->addr = ALLOC(struct netbuf); /* free()'ed at end of mount_nfs_fh() */
54238494Sobrien#endif /* HAVE_TRANSPORT_TYPE_TLI */
54338494Sobrien    NFS_SA_DREF(nap, ip_addr);
54438494Sobrien  }
54538494Sobrien
54638494Sobrien  /************************************************************************/
54738494Sobrien  /***	NFS PROTOCOL (UDP, TCP) AND VERSION				***/
54838494Sobrien  /************************************************************************/
54938494Sobrien#ifdef MNT2_NFS_OPT_TCP
55038494Sobrien  if (nfs_proto && STREQ(nfs_proto, "tcp"))
55138494Sobrien    nap->flags |= MNT2_NFS_OPT_TCP;
55238494Sobrien#endif /* MNT2_NFS_OPT_TCP */
55338494Sobrien
554119682Smbr#ifdef HAVE_NFS_ARGS_T_SOTYPE
55538494Sobrien  /* bsdi3 uses this */
55638494Sobrien  if (nfs_proto) {
55738494Sobrien    if (STREQ(nfs_proto, "tcp"))
55838494Sobrien      nap->sotype = SOCK_STREAM;
55938494Sobrien    else if (STREQ(nfs_proto, "udp"))
56038494Sobrien      nap->sotype = SOCK_DGRAM;
56138494Sobrien  }
562119682Smbr#endif /* HAVE_NFS_ARGS_T_SOTYPE */
56338494Sobrien
564119682Smbr#ifdef HAVE_NFS_ARGS_T_PROTO
56538494Sobrien  nap->proto = 0;		/* bsdi3 sets this field to zero  */
56638494Sobrien# ifdef IPPROTO_TCP
56738494Sobrien  if (nfs_proto) {
56838494Sobrien    if (STREQ(nfs_proto, "tcp"))	/* AIX 4.2.x needs this */
56938494Sobrien      nap->proto = IPPROTO_TCP;
57038494Sobrien    else if (STREQ(nfs_proto, "udp"))
57138494Sobrien      nap->proto = IPPROTO_UDP;
57238494Sobrien  }
57338494Sobrien# endif /* IPPROTO_TCP */
574119682Smbr#endif /* HAVE_NFS_ARGS_T_SOTYPE */
57538494Sobrien
576119682Smbr#ifdef HAVE_NFS_ARGS_T_VERSION
57738494Sobrien# ifdef NFS_ARGSVERSION
57838494Sobrien  nap->version = NFS_ARGSVERSION; /* BSDI 3.0 and OpenBSD 2.2 */
57938494Sobrien# endif /* NFS_ARGSVERSION */
58038494Sobrien# ifdef DG_MOUNT_NFS_VERSION
58138494Sobrien  nap->version = DG_MOUNT_NFS_VERSION; /* dg-ux */
58238494Sobrien# endif /* DG_MOUNT_NFS_VERSION */
583119682Smbr#endif /* HAVE_NFS_ARGS_VERSION */
58438494Sobrien
58538494Sobrien  /************************************************************************/
58638494Sobrien  /***	OTHER NFS SOCKET RELATED OPTIONS AND FLAGS			***/
58738494Sobrien  /************************************************************************/
58838494Sobrien#ifdef MNT2_NFS_OPT_NOCONN
58938494Sobrien  /* check if user specified to use unconnected or connected sockets */
590174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL)
59138494Sobrien    nap->flags |= MNT2_NFS_OPT_NOCONN;
592174313Sobrien  else if (amu_hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL)
59338494Sobrien    nap->flags &= ~MNT2_NFS_OPT_NOCONN;
59438494Sobrien  else {
59538494Sobrien    /*
59638494Sobrien     * Some OSs want you to set noconn always.  Some want you to always turn
59738494Sobrien     * it off.  Others want you to turn it on/off only if NFS V.3 is used.
59838494Sobrien     * And all of that changes from revision to another.  This is
59938494Sobrien     * particularly true of OpenBSD, NetBSD, and FreeBSD.  So, rather than
60038494Sobrien     * attempt to auto-detect this, I'm forced to "fix" it in the individual
60138494Sobrien     * conf/nfs_prot/nfs_prot_*.h files.
60238494Sobrien     */
60338494Sobrien# ifdef USE_UNCONNECTED_NFS_SOCKETS
60443158Sobrien    if (!(nap->flags & MNT2_NFS_OPT_NOCONN)) {
60543158Sobrien      nap->flags |= MNT2_NFS_OPT_NOCONN;
60643158Sobrien      plog(XLOG_WARNING, "noconn option not specified, and was just turned ON (OS override)! (May cause NFS hangs on some systems...)");
60743158Sobrien    }
60838494Sobrien# endif /* USE_UNCONNECTED_NFS_SOCKETS */
60938494Sobrien# ifdef USE_CONNECTED_NFS_SOCKETS
61043158Sobrien    if (nap->flags & MNT2_NFS_OPT_NOCONN) {
61143158Sobrien      nap->flags &= ~MNT2_NFS_OPT_NOCONN;
61243158Sobrien      plog(XLOG_WARNING, "noconn option specified, and was just turned OFF (OS override)! (May cause NFS hangs on some systems...)");
61343158Sobrien    }
61438494Sobrien# endif /* USE_CONNECTED_NFS_SOCKETS */
61538494Sobrien  }
61638494Sobrien#endif /* MNT2_NFS_OPT_NOCONN */
61738494Sobrien
61838494Sobrien#ifdef MNT2_NFS_OPT_RESVPORT
61938494Sobrien# ifdef MNTTAB_OPT_RESVPORT
620174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_RESVPORT) != NULL)
62138494Sobrien    nap->flags |= MNT2_NFS_OPT_RESVPORT;
62238494Sobrien# else /* not MNTTAB_OPT_RESVPORT */
62338494Sobrien  nap->flags |= MNT2_NFS_OPT_RESVPORT;
62438494Sobrien# endif /* not MNTTAB_OPT_RESVPORT */
62538494Sobrien#endif /* MNT2_NFS_OPT_RESVPORT */
62638494Sobrien
62738494Sobrien  /************************************************************************/
62838494Sobrien  /***	OTHER FLAGS AND OPTIONS						***/
62938494Sobrien  /************************************************************************/
63038494Sobrien
63138494Sobrien#ifdef HAVE_TRANSPORT_TYPE_TLI
63238494Sobrien  /* set up syncaddr field */
63338494Sobrien  nap->syncaddr = (struct netbuf *) NULL;
63438494Sobrien
63538494Sobrien  /* set up knconf field */
63638494Sobrien  if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) {
63738494Sobrien    plog(XLOG_FATAL, "cannot fill knetconfig structure for nfs_args");
63838494Sobrien    going_down(1);
63938494Sobrien  }
64038494Sobrien  /* update the flags field for knconf */
64138494Sobrien  nap->flags |= MNT2_NFS_OPT_KNCONF;
64238494Sobrien#endif /* HAVE_TRANSPORT_TYPE_TLI */
64338494Sobrien
64438494Sobrien#ifdef MNT2_NFS_OPT_FSNAME
64538494Sobrien  nap->fsname = fs_name;
64638494Sobrien  nap->flags |= MNT2_NFS_OPT_FSNAME;
64738494Sobrien#endif /* MNT2_NFS_OPT_FSNAME */
64838494Sobrien
64938494Sobrien  nap->rsize = hasmntval(mntp, MNTTAB_OPT_RSIZE);
65038494Sobrien#ifdef MNT2_NFS_OPT_RSIZE
65138494Sobrien  if (nap->rsize)
65238494Sobrien    nap->flags |= MNT2_NFS_OPT_RSIZE;
65338494Sobrien#endif /* MNT2_NFS_OPT_RSIZE */
654174313Sobrien  if (nfs_version == NFS_VERSION && nap->rsize > 8192)
655174313Sobrien    nap->rsize = 8192;
65638494Sobrien
65738494Sobrien  nap->wsize = hasmntval(mntp, MNTTAB_OPT_WSIZE);
65838494Sobrien#ifdef MNT2_NFS_OPT_WSIZE
65938494Sobrien  if (nap->wsize)
66038494Sobrien    nap->flags |= MNT2_NFS_OPT_WSIZE;
66138494Sobrien#endif /* MNT2_NFS_OPT_WSIZE */
662174313Sobrien  if (nfs_version == NFS_VERSION && nap->wsize > 8192)
663174313Sobrien    nap->wsize = 8192;
66438494Sobrien
66538494Sobrien  nap->timeo = hasmntval(mntp, MNTTAB_OPT_TIMEO);
66638494Sobrien#ifdef MNT2_NFS_OPT_TIMEO
66738494Sobrien  if (nap->timeo)
66838494Sobrien    nap->flags |= MNT2_NFS_OPT_TIMEO;
66938494Sobrien#endif /* MNT2_NFS_OPT_TIMEO */
67038494Sobrien
67138494Sobrien  nap->retrans = hasmntval(mntp, MNTTAB_OPT_RETRANS);
67238494Sobrien#ifdef MNT2_NFS_OPT_RETRANS
67338494Sobrien  if (nap->retrans)
67438494Sobrien    nap->flags |= MNT2_NFS_OPT_RETRANS;
67538494Sobrien#endif /* MNT2_NFS_OPT_RETRANS */
67638494Sobrien
67738494Sobrien#ifdef MNT2_NFS_OPT_BIODS
67838494Sobrien  if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS)))
67938494Sobrien    nap->flags |= MNT2_NFS_OPT_BIODS;
68038494Sobrien#endif /* MNT2_NFS_OPT_BIODS */
68138494Sobrien
682174313Sobrien#ifdef MNT2_NFS_OPT_SOFT
683174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL)
68438494Sobrien    nap->flags |= MNT2_NFS_OPT_SOFT;
685174313Sobrien#endif /* MNT2_NFS_OPT_SOFT */
68638494Sobrien
68738494Sobrien#ifdef MNT2_NFS_OPT_SPONGY
688174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) {
68938494Sobrien    nap->flags |= MNT2_NFS_OPT_SPONGY;
69038494Sobrien    if (nap->flags & MNT2_NFS_OPT_SOFT) {
69138494Sobrien      plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored");
69238494Sobrien      nap->flags &= ~MNT2_NFS_OPT_SOFT;
69338494Sobrien    }
69438494Sobrien  }
69538494Sobrien#endif /* MNT2_NFS_OPT_SPONGY */
69638494Sobrien
69738494Sobrien#if defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY)
69838494Sobrien  /* Ultrix has separate generic and NFS ro flags */
69938494Sobrien  if (genflags & MNT2_GEN_OPT_RONLY)
70038494Sobrien    nap->flags |= MNT2_NFS_OPT_RONLY;
70138494Sobrien#endif /* defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) */
70238494Sobrien
70338494Sobrien#ifdef MNTTAB_OPT_INTR
704174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL)
70538494Sobrien    /*
70638494Sobrien     * Either turn on the "allow interrupts" option, or
70738494Sobrien     * turn off the "disallow interrupts" option"
70838494Sobrien     */
70982809Sobrien# ifdef MNT2_NFS_OPT_INTR
71082809Sobrien    nap->flags |= MNT2_NFS_OPT_INTR;
71182809Sobrien# endif /* MNT2_NFS_OPT_INTR */
71282809Sobrien# ifdef MNT2_NFS_OPT_NOINTR
71382809Sobrien    nap->flags &= ~MNT2_NFS_OPT_NOINTR;
71482809Sobrien# endif /* MNT2_NFS_OPT_NOINTR */
71538494Sobrien# ifdef MNT2_NFS_OPT_INT
71638494Sobrien    nap->flags |= MNT2_NFS_OPT_INT;
71738494Sobrien# endif /* MNT2_NFS_OPT_INT */
71838494Sobrien# ifdef MNT2_NFS_OPT_NOINT
71938494Sobrien    nap->flags &= ~MNT2_NFS_OPT_NOINT;
72038494Sobrien# endif /* MNT2_NFS_OPT_NOINT */
72138494Sobrien#endif /* MNTTAB_OPT_INTR */
72238494Sobrien
72338494Sobrien#ifdef MNTTAB_OPT_NODEVS
724174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL)
72538494Sobrien    nap->flags |= MNT2_NFS_OPT_NODEVS;
72638494Sobrien#endif /* MNTTAB_OPT_NODEVS */
72738494Sobrien
72838494Sobrien#ifdef MNTTAB_OPT_COMPRESS
729174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_COMPRESS) != NULL)
73038494Sobrien    nap->flags |= MNT2_NFS_OPT_COMPRESS;
73138494Sobrien#endif /* MNTTAB_OPT_COMPRESS */
73238494Sobrien
73338494Sobrien#ifdef MNTTAB_OPT_PRIVATE	/* mount private, single-client tree */
734174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL)
73538494Sobrien    nap->flags |= MNT2_NFS_OPT_PRIVATE;
73638494Sobrien#endif /* MNTTAB_OPT_PRIVATE */
73738494Sobrien
73838494Sobrien#ifdef MNTTAB_OPT_SYMTTL	/* symlink cache time-to-live */
73938494Sobrien  if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL)))
74038494Sobrien    nap->flags |= MNT2_NFS_OPT_SYMTTL;
74138494Sobrien#endif /* MNTTAB_OPT_SYMTTL */
74238494Sobrien
74338494Sobrien#ifdef MNT2_NFS_OPT_PGTHRESH	/* paging threshold */
74438494Sobrien  if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH)))
74538494Sobrien    nap->flags |= MNT2_NFS_OPT_PGTHRESH;
74638494Sobrien#endif /* MNT2_NFS_OPT_PGTHRESH */
74738494Sobrien
74838494Sobrien#if defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO)
749174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL)
75038494Sobrien    nap->flags |= MNT2_NFS_OPT_NOCTO;
75138494Sobrien#endif /* defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) */
75238494Sobrien
75338494Sobrien#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
754174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) {
75538494Sobrien    nap->flags |= MNT2_NFS_OPT_POSIX;
75638494Sobrien    nap->pathconf = NULL;
75738494Sobrien  }
75838494Sobrien#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
75938494Sobrien
76082809Sobrien#if defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST)
761174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL)
76282809Sobrien    nap->flags |= MNT2_NFS_OPT_PROPLIST;
76382809Sobrien#endif /* defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) */
76482809Sobrien
76538494Sobrien#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
76638494Sobrien  nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
767174313Sobrien  if (nap->maxgrouplist != 0)
76838494Sobrien    nap->flags |= MNT2_NFS_OPT_MAXGRPS;
76938494Sobrien#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
77038494Sobrien
771119682Smbr#if defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK)
772174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL)
773119682Smbr    nap->flags |= MNT2_NFS_OPT_NONLM;
774119682Smbr#endif /* defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) */
775119682Smbr
776174313Sobrien#if defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE)
777174313Sobrien  if (amu_hasmntopt(mntp, MNTTAB_OPT_XLATECOOKIE) != NULL)
778174313Sobrien    nap->flags |= MNT2_NFS_OPT_XLATECOOKIE;
779174313Sobrien#endif /* defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) */
780174313Sobrien
781119682Smbr#ifdef HAVE_NFS_ARGS_T_OPTSTR
78238494Sobrien  nap->optstr = mntp->mnt_opts;
783119682Smbr#endif /* HAVE_NFS_ARGS_T_OPTSTR */
78438494Sobrien
78538494Sobrien  /************************************************************************/
78638494Sobrien  /***	FINAL ACTIONS							***/
78738494Sobrien  /************************************************************************/
78838494Sobrien
789119682Smbr#ifdef HAVE_NFS_ARGS_T_GFS_FLAGS
79038494Sobrien  /* Ultrix stores generic flags in nfs_args.gfs_flags. */
79138494Sobrien  nap->gfs_flags = genflags;
792119682Smbr#endif /* HAVE_NFS_ARGS_T_FLAGS */
79338494Sobrien
79438494Sobrien  return;			/* end of compute_nfs_args() function */
79538494Sobrien}
79638494Sobrien
79738494Sobrien
79838494Sobrien/*
79938494Sobrien * Fill in special values for flags and fields of nfs_args, for an
80038494Sobrien * automounter NFS mount.
80138494Sobrien */
80238494Sobrienvoid
80338494Sobriencompute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp)
80438494Sobrien{
80538494Sobrien#ifdef MNT2_NFS_OPT_SYMTTL
80638494Sobrien  /*
80738494Sobrien   * Don't let the kernel cache symbolic links we generate, or else lookups
80838494Sobrien   * will bypass amd and fail to remount stuff as needed.
80938494Sobrien   */
81082809Sobrien  plog(XLOG_INFO, "turning on NFS option symttl and setting value to 0");
81138494Sobrien  nap->flags |= MNT2_NFS_OPT_SYMTTL;
81238494Sobrien  nap->symttl = 0;
81338494Sobrien#endif /* MNT2_NFS_OPT_SYMTTL */
81438494Sobrien
81538494Sobrien  /*
81651595Sobrien   * This completes the flags for the HIDE_MOUNT_TYPE  code in the
81751595Sobrien   * mount_amfs_toplvl() function in amd/amfs_toplvl.c.
81838494Sobrien   * Some systems don't have a mount type, but a mount flag.
81938494Sobrien   */
82038494Sobrien#ifdef MNT2_NFS_OPT_AUTO
82138494Sobrien  nap->flags |= MNT2_NFS_OPT_AUTO;
82238494Sobrien#endif /* MNT2_NFS_OPT_AUTO */
82338494Sobrien#ifdef MNT2_NFS_OPT_IGNORE
82438494Sobrien  nap->flags |= MNT2_NFS_OPT_IGNORE;
82538494Sobrien#endif /* MNT2_NFS_OPT_IGNORE */
82651595Sobrien#ifdef MNT2_GEN_OPT_AUTOMNTFS
82751595Sobrien  nap->flags |= MNT2_GEN_OPT_AUTOMNTFS;
82851595Sobrien#endif /* not MNT2_GEN_OPT_AUTOMNTFS */
82938494Sobrien
83038494Sobrien#ifdef MNT2_NFS_OPT_DUMBTIMR
83138494Sobrien  /*
83282809Sobrien   * Don't let the kernel start computing throughput of Amd.  The numbers
83382809Sobrien   * will be meaningless because of the way Amd does mount retries.
83438494Sobrien   */
83538494Sobrien  plog(XLOG_INFO, "%s: disabling nfs congestion window", mntp->mnt_dir);
83638494Sobrien  nap->flags |= MNT2_NFS_OPT_DUMBTIMR;
83738494Sobrien#endif /* MNT2_NFS_OPT_DUMBTIMR */
83838494Sobrien
839174313Sobrien  /* compute all of the NFS attribute-cache flags */
840174313Sobrien  compute_nfs_attrcache_flags(nap, mntp);
841174313Sobrien
84238494Sobrien  /*
84351300Sobrien   * Provide a slight bit more security by requiring the kernel to use
84451300Sobrien   * reserved ports.
84551300Sobrien   */
84651300Sobrien#ifdef MNT2_NFS_OPT_RESVPORT
84751300Sobrien  nap->flags |= MNT2_NFS_OPT_RESVPORT;
84851300Sobrien#endif /* MNT2_NFS_OPT_RESVPORT */
84938494Sobrien}
85038494Sobrien
85138494Sobrien
85238494Sobrien#ifdef DEBUG
85338494Sobrien/* get string version (in hex) of identifier */
85438494Sobrienstatic char *
85538494Sobrienget_hex_string(u_int len, const char *fhdata)
85638494Sobrien{
857174313Sobrien  u_int i;
85838494Sobrien  static char buf[128];		/* better not go over it! */
85938494Sobrien  char str[16];
86038494Sobrien  short int arr[64];
86138494Sobrien
86238494Sobrien  if (!fhdata)
86338494Sobrien    return NULL;
86438494Sobrien  buf[0] = '\0';
86538494Sobrien  memset(&arr[0], 0, (64 * sizeof(short int)));
86638494Sobrien  memcpy(&arr[0], &fhdata[0], len);
867174313Sobrien  for (i=0; i<len/sizeof(unsigned short int); i++) {
868174313Sobrien    xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i]));
869174313Sobrien    xstrlcat(buf, str, sizeof(buf));
87038494Sobrien  }
87138494Sobrien  return buf;
87238494Sobrien}
87338494Sobrien
87438494Sobrien
87538494Sobrien/*
87638494Sobrien * print a subset of fields from "struct nfs_args" that are otherwise
87738494Sobrien * not being provided anywhere else.
87838494Sobrien */
87938494Sobrienvoid
88038494Sobrienprint_nfs_args(const nfs_args_t *nap, u_long nfs_version)
88138494Sobrien{
882174313Sobrien  int fhlen = 32;	/* default: NFS V.2 file handle length is 32 */
88338494Sobrien#ifdef HAVE_TRANSPORT_TYPE_TLI
88438494Sobrien  struct netbuf *nbp;
88538494Sobrien  struct knetconfig *kncp;
88638494Sobrien#else /* not HAVE_TRANSPORT_TYPE_TLI */
88738494Sobrien  struct sockaddr_in *sap;
88838494Sobrien#endif /* not HAVE_TRANSPORT_TYPE_TLI */
88938494Sobrien
89038494Sobrien  if (!nap) {
89138494Sobrien    plog(XLOG_DEBUG, "NULL nfs_args!");
89238494Sobrien    return;
89338494Sobrien  }
89438494Sobrien
89538494Sobrien  /* override default file handle size */
89638494Sobrien#ifdef FHSIZE
89738494Sobrien   fhlen = FHSIZE;
89838494Sobrien#endif /* FHSIZE */
89938494Sobrien#ifdef NFS_FHSIZE
90038494Sobrien   fhlen = NFS_FHSIZE;
90138494Sobrien#endif /* NFS_FHSIZE */
90238494Sobrien
90338494Sobrien#ifdef HAVE_TRANSPORT_TYPE_TLI
90438494Sobrien  nbp = nap->addr;
90538494Sobrien  plog(XLOG_DEBUG, "NA->addr {netbuf} (maxlen=%d, len=%d) = \"%s\"",
90638494Sobrien       nbp->maxlen, nbp->len,
90738494Sobrien       get_hex_string(nbp->len, nbp->buf));
90838494Sobrien  nbp = nap->syncaddr;
909174313Sobrien  plog(XLOG_DEBUG, "NA->syncaddr {netbuf} %p", nbp);
91038494Sobrien  kncp = nap->knconf;
911119682Smbr  plog(XLOG_DEBUG, "NA->knconf->semantics %lu", (u_long) kncp->knc_semantics);
91238494Sobrien  plog(XLOG_DEBUG, "NA->knconf->protofmly \"%s\"", kncp->knc_protofmly);
91338494Sobrien  plog(XLOG_DEBUG, "NA->knconf->proto \"%s\"", kncp->knc_proto);
914119682Smbr  plog(XLOG_DEBUG, "NA->knconf->rdev %lu", (u_long) kncp->knc_rdev);
91538494Sobrien  /* don't print knconf->unused field */
91638494Sobrien#else /* not HAVE_TRANSPORT_TYPE_TLI */
917174313Sobrien# ifdef NFS_ARGS_T_ADDR_IS_POINTER
918174313Sobrien    sap = (struct sockaddr_in *) nap->addr;
919174313Sobrien# else /* not NFS_ARGS_T_ADDR_IS_POINTER */
920174313Sobrien    sap = (struct sockaddr_in *) &nap->addr;
921174313Sobrien# endif /* not NFS_ARGS_T_ADDR_IS_POINTER */
92238494Sobrien  plog(XLOG_DEBUG, "NA->addr {sockaddr_in} (len=%d) = \"%s\"",
92351300Sobrien       (int) sizeof(struct sockaddr_in),
92438494Sobrien       get_hex_string(sizeof(struct sockaddr_in), (const char *)sap));
925119682Smbr#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
926174313Sobrien  /* as per POSIX, sin_len need not be set (used internally by kernel) */
927174313Sobrien  plog(XLOG_DEBUG, "NA->addr.sin_len = %d", sap->sin_len);
928119682Smbr#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
929174313Sobrien  plog(XLOG_DEBUG, "NA->addr.sin_family = %d", sap->sin_family);
930174313Sobrien  plog(XLOG_DEBUG, "NA->addr.sin_port = %d", sap->sin_port);
93138494Sobrien  plog(XLOG_DEBUG, "NA->addr.sin_addr = \"%s\"",
93238494Sobrien       get_hex_string(sizeof(struct in_addr), (const char *) &sap->sin_addr));
93338494Sobrien#endif /* not HAVE_TRANSPORT_TYPE_TLI */
934174313Sobrien#ifdef HAVE_NFS_ARGS_T_ADDRLEN
935174313Sobrien  plog(XLOG_DEBUG, "NA->addrlen = %d", nap->addrlen);
936174313Sobrien#endif /* ifdef HAVE_NFS_ARGS_T_ADDRLEN */
93738494Sobrien
93838494Sobrien  plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname ? nap->hostname : "null");
939119682Smbr#ifdef HAVE_NFS_ARGS_T_NAMLEN
94051300Sobrien  plog(XLOG_DEBUG, "NA->namlen = %d", nap->namlen);
941119682Smbr#endif /* HAVE_NFS_ARGS_T_NAMLEN */
94251300Sobrien
94338494Sobrien#ifdef MNT2_NFS_OPT_FSNAME
94438494Sobrien  plog(XLOG_DEBUG, "NA->fsname = \"%s\"", nap->fsname ? nap->fsname : "null");
94538494Sobrien#endif /* MNT2_NFS_OPT_FSNAME */
94638494Sobrien
947119682Smbr#ifdef HAVE_NFS_ARGS_T_FHSIZE
94838494Sobrien  plog(XLOG_DEBUG, "NA->fhsize = %d", nap->fhsize);
94938494Sobrien  fhlen = nap->fhsize;
950119682Smbr#endif /* HAVE_NFS_ARGS_T_FHSIZE */
951119682Smbr#ifdef HAVE_NFS_ARGS_T_FH_LEN
95238494Sobrien  plog(XLOG_DEBUG, "NA->fh_len = %d", nap->fh_len);
95338494Sobrien  fhlen = nap->fh_len;
954119682Smbr#endif /* HAVE_NFS_ARGS_T_FH_LEN */
95538494Sobrien
95638494Sobrien  /*
95738494Sobrien   * XXX: need to figure out how to correctly print file handles,
95838494Sobrien   * since some times they are pointers, and sometimes the real structure
95938494Sobrien   * is stored in nfs_args.  Even if it is a pointer, it can be the actual
96038494Sobrien   * char[] array, or a structure containing multiple fields.
96138494Sobrien   */
96238494Sobrien  plog(XLOG_DEBUG, "NA->filehandle = \"%s\"",
96338494Sobrien       get_hex_string(fhlen, (const char *) &nap->NFS_FH_FIELD));
96438494Sobrien
965119682Smbr#ifdef HAVE_NFS_ARGS_T_SOTYPE
96638494Sobrien  plog(XLOG_DEBUG, "NA->sotype = %d", nap->sotype);
967119682Smbr#endif /* HAVE_NFS_ARGS_T_SOTYPE */
968119682Smbr#ifdef HAVE_NFS_ARGS_T_PROTO
96951595Sobrien  plog(XLOG_DEBUG, "NA->proto = %d", (int) nap->proto);
970119682Smbr#endif /* HAVE_NFS_ARGS_T_PROTO */
971119682Smbr#ifdef HAVE_NFS_ARGS_T_VERSION
97238494Sobrien  plog(XLOG_DEBUG, "NA->version = %d", nap->version);
973119682Smbr#endif /* HAVE_NFS_ARGS_T_VERSION */
97438494Sobrien
97551595Sobrien  plog(XLOG_DEBUG, "NA->flags = 0x%x", (int) nap->flags);
97638494Sobrien
97751595Sobrien  plog(XLOG_DEBUG, "NA->rsize = %d", (int) nap->rsize);
97851595Sobrien  plog(XLOG_DEBUG, "NA->wsize = %d", (int) nap->wsize);
979119682Smbr#ifdef HAVE_NFS_ARGS_T_BSIZE
98051300Sobrien  plog(XLOG_DEBUG, "NA->bsize = %d", nap->bsize);
981119682Smbr#endif /* HAVE_NFS_ARGS_T_BSIZE */
98251595Sobrien  plog(XLOG_DEBUG, "NA->timeo = %d", (int) nap->timeo);
98351595Sobrien  plog(XLOG_DEBUG, "NA->retrans = %d", (int) nap->retrans);
98438494Sobrien
985119682Smbr#ifdef HAVE_NFS_ARGS_T_ACREGMIN
98651595Sobrien  plog(XLOG_DEBUG, "NA->acregmin = %d", (int) nap->acregmin);
98751595Sobrien  plog(XLOG_DEBUG, "NA->acregmax = %d", (int) nap->acregmax);
98851595Sobrien  plog(XLOG_DEBUG, "NA->acdirmin = %d", (int) nap->acdirmin);
98951595Sobrien  plog(XLOG_DEBUG, "NA->acdirmax = %d", (int) nap->acdirmax);
990119682Smbr#endif /* HAVE_NFS_ARGS_T_ACREGMIN */
99138494Sobrien#ifdef MNTTAB_OPT_SYMTTL
99238494Sobrien  plog(XLOG_DEBUG, "NA->symttl = %d", nap->symttl);
99338494Sobrien#endif /* MNTTAB_OPT_SYMTTL */
99438494Sobrien#ifdef MNTTAB_OPT_PG_THRESH
99538494Sobrien  plog(XLOG_DEBUG, "NA->pg_thresh = %d", nap->pg_thresh);
99638494Sobrien#endif /* MNTTAB_OPT_PG_THRESH */
99738494Sobrien
99838494Sobrien#ifdef MNT2_NFS_OPT_BIODS
99938494Sobrien  plog(XLOG_DEBUG, "NA->biods = %d", nap->biods);
100038494Sobrien#endif /* MNT2_NFS_OPT_BIODS */
100138494Sobrien
100238494Sobrien}
100338494Sobrien#endif /* DEBUG */
1004