1*4da6d876Schristos /* $NetBSD: mount_fs.c,v 1.3 2015/01/17 17:46:31 christos Exp $ */
2a53f50b9Schristos
3a53f50b9Schristos /*
4*4da6d876Schristos * Copyright (c) 1997-2014 Erez Zadok
5a53f50b9Schristos * Copyright (c) 1990 Jan-Simon Pendry
6a53f50b9Schristos * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
7a53f50b9Schristos * Copyright (c) 1990 The Regents of the University of California.
8a53f50b9Schristos * All rights reserved.
9a53f50b9Schristos *
10a53f50b9Schristos * This code is derived from software contributed to Berkeley by
11a53f50b9Schristos * Jan-Simon Pendry at Imperial College, London.
12a53f50b9Schristos *
13a53f50b9Schristos * Redistribution and use in source and binary forms, with or without
14a53f50b9Schristos * modification, are permitted provided that the following conditions
15a53f50b9Schristos * are met:
16a53f50b9Schristos * 1. Redistributions of source code must retain the above copyright
17a53f50b9Schristos * notice, this list of conditions and the following disclaimer.
18a53f50b9Schristos * 2. Redistributions in binary form must reproduce the above copyright
19a53f50b9Schristos * notice, this list of conditions and the following disclaimer in the
20a53f50b9Schristos * documentation and/or other materials provided with the distribution.
21*4da6d876Schristos * 3. Neither the name of the University nor the names of its contributors
22a53f50b9Schristos * may be used to endorse or promote products derived from this software
23a53f50b9Schristos * without specific prior written permission.
24a53f50b9Schristos *
25a53f50b9Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26a53f50b9Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27a53f50b9Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28a53f50b9Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29a53f50b9Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30a53f50b9Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31a53f50b9Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32a53f50b9Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33a53f50b9Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34a53f50b9Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35a53f50b9Schristos * SUCH DAMAGE.
36a53f50b9Schristos *
37a53f50b9Schristos *
38a53f50b9Schristos * File: am-utils/libamu/mount_fs.c
39a53f50b9Schristos *
40a53f50b9Schristos */
41a53f50b9Schristos
42a53f50b9Schristos #ifdef HAVE_CONFIG_H
43a53f50b9Schristos # include <config.h>
44a53f50b9Schristos #endif /* HAVE_CONFIG_H */
45a53f50b9Schristos #include <am_defs.h>
46a53f50b9Schristos #include <amu.h>
47*4da6d876Schristos #include <nfs_common.h>
48a53f50b9Schristos
49a53f50b9Schristos
50a53f50b9Schristos /* ensure that mount table options are delimited by a comma */
51a53f50b9Schristos #define append_opts(old, l, new) { \
52a53f50b9Schristos if (*(old) != '\0') \
53a53f50b9Schristos xstrlcat(old, ",", l); \
54a53f50b9Schristos xstrlcat(old, new, l); }
55a53f50b9Schristos
56a53f50b9Schristos /*
57a53f50b9Schristos * Standard mount flags
58a53f50b9Schristos */
59a53f50b9Schristos struct opt_tab mnt_flags[] =
60a53f50b9Schristos {
61a53f50b9Schristos #if defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO)
62a53f50b9Schristos {MNTTAB_OPT_RO, MNT2_GEN_OPT_RDONLY},
63a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO) */
64a53f50b9Schristos
65a53f50b9Schristos #if defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE)
66a53f50b9Schristos {MNTTAB_OPT_NOCACHE, MNT2_GEN_OPT_NOCACHE},
67a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE) */
68a53f50b9Schristos
69a53f50b9Schristos /* the "grpid" mount option can be offered as generic of NFS */
70a53f50b9Schristos #ifdef MNTTAB_OPT_GRPID
71a53f50b9Schristos # ifdef MNT2_GEN_OPT_GRPID
72a53f50b9Schristos {MNTTAB_OPT_GRPID, MNT2_GEN_OPT_GRPID},
73a53f50b9Schristos # endif /* MNT2_GEN_OPT_GRPID */
74a53f50b9Schristos # ifdef MNT2_NFS_OPT_GRPID
75a53f50b9Schristos {MNTTAB_OPT_GRPID, MNT2_NFS_OPT_GRPID},
76a53f50b9Schristos # endif /* MNT2_NFS_OPT_GRPID */
77a53f50b9Schristos #endif /* MNTTAB_OPT_GRPID */
78a53f50b9Schristos
79a53f50b9Schristos #if defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI)
80a53f50b9Schristos {MNTTAB_OPT_MULTI, MNT2_GEN_OPT_MULTI},
81a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI) */
82a53f50b9Schristos
83a53f50b9Schristos #if defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV)
84a53f50b9Schristos {MNTTAB_OPT_NODEV, MNT2_GEN_OPT_NODEV},
85a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV) */
86a53f50b9Schristos
87a53f50b9Schristos #if defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC)
88a53f50b9Schristos {MNTTAB_OPT_NOEXEC, MNT2_GEN_OPT_NOEXEC},
89a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC) */
90a53f50b9Schristos
91a53f50b9Schristos #if defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB)
92a53f50b9Schristos {MNTTAB_OPT_NOSUB, MNT2_GEN_OPT_NOSUB},
93a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB) */
94a53f50b9Schristos
95a53f50b9Schristos #if defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID)
96a53f50b9Schristos {MNTTAB_OPT_NOSUID, MNT2_GEN_OPT_NOSUID},
97a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID) */
98a53f50b9Schristos
99a53f50b9Schristos #if defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC)
100a53f50b9Schristos {MNTTAB_OPT_SYNC, MNT2_GEN_OPT_SYNC},
101a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC) */
102a53f50b9Schristos
103a53f50b9Schristos #if defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY)
104a53f50b9Schristos {MNTTAB_OPT_OVERLAY, MNT2_GEN_OPT_OVERLAY},
105a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY) */
106a53f50b9Schristos
107a53f50b9Schristos #if defined(MNT2_GEN_OPT_LOG) && defined(MNTTAB_OPT_LOG)
108a53f50b9Schristos {MNTTAB_OPT_LOG, MNT2_GEN_OPT_LOG},
109a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_LOG) && defined(MNTTAB_OPT_LOG) */
110a53f50b9Schristos
111a53f50b9Schristos #if defined(MNT2_GEN_OPT_NOATIME) && defined(MNTTAB_OPT_NOATIME)
112a53f50b9Schristos {MNTTAB_OPT_NOATIME, MNT2_GEN_OPT_NOATIME},
113a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_NOATIME) && defined(MNTTAB_OPT_NOATIME) */
114a53f50b9Schristos
115a53f50b9Schristos #if defined(MNT2_GEN_OPT_NODEVMTIME) && defined(MNTTAB_OPT_NODEVMTIME)
116a53f50b9Schristos {MNTTAB_OPT_NODEVMTIME, MNT2_GEN_OPT_NODEVMTIME},
117a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_NODEVMTIME) && defined(MNTTAB_OPT_NODEVMTIME) */
118a53f50b9Schristos
119a53f50b9Schristos #if defined(MNT2_GEN_OPT_SOFTDEP) && defined(MNTTAB_OPT_SOFTDEP)
120a53f50b9Schristos {MNTTAB_OPT_SOFTDEP, MNT2_GEN_OPT_SOFTDEP},
121a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_SOFTDEP) && defined(MNTTAB_OPT_SOFTDEP) */
122a53f50b9Schristos
123a53f50b9Schristos #if defined(MNT2_GEN_OPT_SYMPERM) && defined(MNTTAB_OPT_SYMPERM)
124a53f50b9Schristos {MNTTAB_OPT_SYMPERM, MNT2_GEN_OPT_SYMPERM},
125a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_SYMPERM) && defined(MNTTAB_OPT_SYMPERM) */
126a53f50b9Schristos
127a53f50b9Schristos #if defined(MNT2_GEN_OPT_UNION) && defined(MNTTAB_OPT_UNION)
128a53f50b9Schristos {MNTTAB_OPT_UNION, MNT2_GEN_OPT_UNION},
129a53f50b9Schristos #endif /* defined(MNT2_GEN_OPT_UNION) && defined(MNTTAB_OPT_UNION) */
130a53f50b9Schristos
131a53f50b9Schristos /*
132a53f50b9Schristos * Do not define MNT2_NFS_OPT_* entries here! This is for generic
133a53f50b9Schristos * mount(2) options only, not for NFS mount options. If you need to put
134a53f50b9Schristos * something here, it's probably not the right place: see
135a53f50b9Schristos * include/am_compat.h.
136a53f50b9Schristos */
137a53f50b9Schristos
138a53f50b9Schristos {0, 0}
139a53f50b9Schristos };
140a53f50b9Schristos
141a53f50b9Schristos
142a53f50b9Schristos /* compute generic mount flags */
143a53f50b9Schristos int
compute_mount_flags(mntent_t * mntp)144a53f50b9Schristos compute_mount_flags(mntent_t *mntp)
145a53f50b9Schristos {
146a53f50b9Schristos struct opt_tab *opt;
147a53f50b9Schristos int flags = 0;
148a53f50b9Schristos
149a53f50b9Schristos #ifdef MNT2_GEN_OPT_NEWTYPE
150a53f50b9Schristos flags |= MNT2_GEN_OPT_NEWTYPE;
151a53f50b9Schristos #endif /* MNT2_GEN_OPT_NEWTYPE */
152a53f50b9Schristos #ifdef MNT2_GEN_OPT_AUTOMOUNTED
153a53f50b9Schristos flags |= MNT2_GEN_OPT_AUTOMOUNTED;
154a53f50b9Schristos #endif /* not MNT2_GEN_OPT_AUTOMOUNTED */
155a53f50b9Schristos
156a53f50b9Schristos /*
157a53f50b9Schristos * Crack basic mount options
158a53f50b9Schristos */
159a53f50b9Schristos for (opt = mnt_flags; opt->opt; opt++) {
160a53f50b9Schristos flags |= amu_hasmntopt(mntp, opt->opt) ? opt->flag : 0;
161a53f50b9Schristos }
162a53f50b9Schristos
163a53f50b9Schristos return flags;
164a53f50b9Schristos }
165a53f50b9Schristos
166a53f50b9Schristos
167a53f50b9Schristos /* compute generic mount flags for automounter mounts */
168a53f50b9Schristos int
compute_automounter_mount_flags(mntent_t * mntp)169a53f50b9Schristos compute_automounter_mount_flags(mntent_t *mntp)
170a53f50b9Schristos {
171a53f50b9Schristos int flags = 0;
172a53f50b9Schristos
173a53f50b9Schristos #ifdef MNT2_GEN_OPT_IGNORE
174a53f50b9Schristos flags |= MNT2_GEN_OPT_IGNORE;
175a53f50b9Schristos #endif /* not MNT2_GEN_OPT_IGNORE */
176a53f50b9Schristos #ifdef MNT2_GEN_OPT_AUTOMNTFS
177a53f50b9Schristos flags |= MNT2_GEN_OPT_AUTOMNTFS;
178a53f50b9Schristos #endif /* not MNT2_GEN_OPT_AUTOMNTFS */
179a53f50b9Schristos
180a53f50b9Schristos return flags;
181a53f50b9Schristos }
182a53f50b9Schristos
183a53f50b9Schristos
184*4da6d876Schristos #if defined(MOUNT_TABLE_ON_FILE) && defined(MNTTAB_OPT_VERS)
185*4da6d876Schristos /*
186*4da6d876Schristos * add the extra vers={2,3} field to the mount table,
187*4da6d876Schristos * unless already specified by user
188*4da6d876Schristos */
189*4da6d876Schristos static void
addvers(char * zopts,size_t l,mntent_t * mnt,u_long have_vers,u_long want_vers)190*4da6d876Schristos addvers(char *zopts, size_t l, mntent_t *mnt, u_long have_vers,
191*4da6d876Schristos u_long want_vers)
192*4da6d876Schristos {
193*4da6d876Schristos if (have_vers == want_vers &&
194*4da6d876Schristos hasmntval(mnt, MNTTAB_OPT_VERS) != want_vers) {
195*4da6d876Schristos char optsbuf[48];
196*4da6d876Schristos xsnprintf(optsbuf, sizeof(optsbuf),
197*4da6d876Schristos "%s=%d", MNTTAB_OPT_VERS, want_vers);
198*4da6d876Schristos append_opts(zopts, l, optsbuf);
199*4da6d876Schristos }
200*4da6d876Schristos }
201*4da6d876Schristos #endif /* MOUNT_TABLE_ON_FILE && MNTTAB_OPT_VERS */
202*4da6d876Schristos
203a53f50b9Schristos int
mount_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)204a53f50b9Schristos mount_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)
205a53f50b9Schristos {
206a53f50b9Schristos int error = 0;
207a53f50b9Schristos #ifdef MOUNT_TABLE_ON_FILE
208a53f50b9Schristos char *zopts = NULL, *xopts = NULL;
209a53f50b9Schristos size_t l;
210a53f50b9Schristos #endif /* MOUNT_TABLE_ON_FILE */
211a53f50b9Schristos char *mnt_dir = NULL;
212a53f50b9Schristos
213a53f50b9Schristos #ifdef NEED_AUTOFS_SPACE_HACK
214a53f50b9Schristos char *old_mnt_dir = NULL;
215a53f50b9Schristos /* perform space hack */
216a53f50b9Schristos if (on_autofs) {
217a53f50b9Schristos old_mnt_dir = mnt->mnt_dir;
218a53f50b9Schristos mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir);
219a53f50b9Schristos } else
220a53f50b9Schristos #endif /* NEED_AUTOFS_SPACE_HACK */
221*4da6d876Schristos mnt_dir = xstrdup(mnt->mnt_dir);
222a53f50b9Schristos
223a53f50b9Schristos dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)",
224a53f50b9Schristos mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
225a53f50b9Schristos
226a53f50b9Schristos again:
227a53f50b9Schristos error = MOUNT_TRAP(type, mnt, flags, mnt_data);
228a53f50b9Schristos
229a53f50b9Schristos if (error < 0) {
230a53f50b9Schristos plog(XLOG_ERROR, "'%s': mount: %m", mnt_dir);
231a53f50b9Schristos /*
232a53f50b9Schristos * The following code handles conditions which shouldn't
233a53f50b9Schristos * occur. They are possible either because amd screws up
234a53f50b9Schristos * in preparing for the mount, or because some human
235a53f50b9Schristos * messed with the mount point. Both have been known to
236a53f50b9Schristos * happen. -- stolcke 2/22/95
237a53f50b9Schristos */
238a53f50b9Schristos if (errno == EBUSY) {
239a53f50b9Schristos /*
240a53f50b9Schristos * Also, sometimes unmount isn't called, e.g., because
241a53f50b9Schristos * our mountlist is garbled. This leaves old mount
242a53f50b9Schristos * points around which need to be removed before we
243a53f50b9Schristos * can mount something new in their place.
244a53f50b9Schristos */
245a53f50b9Schristos errno = umount_fs(mnt_dir, mnttabname, on_autofs);
246a53f50b9Schristos if (errno != 0)
247a53f50b9Schristos plog(XLOG_ERROR, "'%s': umount: %m", mnt_dir);
248a53f50b9Schristos else {
249a53f50b9Schristos plog(XLOG_WARNING, "extra umount required for '%s'", mnt_dir);
250a53f50b9Schristos error = MOUNT_TRAP(type, mnt, flags, mnt_data);
251a53f50b9Schristos }
252a53f50b9Schristos }
253a53f50b9Schristos }
254a53f50b9Schristos
255a53f50b9Schristos if (error < 0 && --retry > 0) {
256a53f50b9Schristos sleep(1);
257a53f50b9Schristos goto again;
258a53f50b9Schristos }
259a53f50b9Schristos
260a53f50b9Schristos #ifdef NEED_AUTOFS_SPACE_HACK
261a53f50b9Schristos /* Undo space hack */
262a53f50b9Schristos if (on_autofs)
263a53f50b9Schristos mnt->mnt_dir = old_mnt_dir;
264a53f50b9Schristos #endif /* NEED_AUTOFS_SPACE_HACK */
265a53f50b9Schristos
266a53f50b9Schristos if (error < 0) {
267a53f50b9Schristos error = errno;
268a53f50b9Schristos goto out;
269a53f50b9Schristos }
270a53f50b9Schristos
271a53f50b9Schristos #ifdef MOUNT_TABLE_ON_FILE
272a53f50b9Schristos /*
273a53f50b9Schristos * Allocate memory for options:
274a53f50b9Schristos * dev=..., vers={2,3}, proto={tcp,udp}
275a53f50b9Schristos */
276a53f50b9Schristos l = strlen(mnt->mnt_opts) + 48;
277a53f50b9Schristos zopts = (char *) xmalloc(l);
278a53f50b9Schristos
279a53f50b9Schristos /* copy standard options */
280a53f50b9Schristos xopts = mnt->mnt_opts;
281a53f50b9Schristos
282a53f50b9Schristos xstrlcpy(zopts, xopts, l);
283a53f50b9Schristos
284a53f50b9Schristos # ifdef MNTTAB_OPT_DEV
285a53f50b9Schristos {
286a53f50b9Schristos /* add the extra dev= field to the mount table */
287a53f50b9Schristos struct stat stb;
288a53f50b9Schristos if (lstat(mnt_dir, &stb) == 0) {
289a53f50b9Schristos char optsbuf[48];
290a53f50b9Schristos if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */
291a53f50b9Schristos xsnprintf(optsbuf, sizeof(optsbuf), "%s=%04lx",
292a53f50b9Schristos MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff);
293a53f50b9Schristos else /* e.g. System Vr4 */
294a53f50b9Schristos xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx",
295a53f50b9Schristos MNTTAB_OPT_DEV, (u_long) stb.st_dev);
296a53f50b9Schristos append_opts(zopts, l, optsbuf);
297a53f50b9Schristos }
298a53f50b9Schristos }
299a53f50b9Schristos # endif /* MNTTAB_OPT_DEV */
300a53f50b9Schristos
301*4da6d876Schristos # if defined(HAVE_FS_NFS4) && defined(MNTTAB_OPT_VERS)
302*4da6d876Schristos addvers(zopts, l, mnt, nfs_version, NFS_VERSION4);
303*4da6d876Schristos # endif /* defined(HAVE_FS_NFS4) && defined(MNTTAB_OPT_VERS) */
304a53f50b9Schristos # if defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)
305*4da6d876Schristos addvers(zopts, l, mnt, nfs_version, NFS_VERSION3);
306a53f50b9Schristos # endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */
307*4da6d876Schristos # ifdef MNTTAB_OPT_VERS
308*4da6d876Schristos addvers(zopts, l, mnt, nfs_version, NFS_VERSION2);
309*4da6d876Schristos # endif /* MNTTAB_OPT_VERS */
310a53f50b9Schristos
311a53f50b9Schristos # ifdef MNTTAB_OPT_PROTO
312a53f50b9Schristos /*
313a53f50b9Schristos * add the extra proto={tcp,udp} field to the mount table,
314a53f50b9Schristos * unless already specified by user.
315a53f50b9Schristos */
316a53f50b9Schristos if (nfs_proto && !amu_hasmntopt(mnt, MNTTAB_OPT_PROTO)) {
317a53f50b9Schristos char optsbuf[48];
318a53f50b9Schristos xsnprintf(optsbuf, sizeof(optsbuf), "%s=%s", MNTTAB_OPT_PROTO, nfs_proto);
319a53f50b9Schristos append_opts(zopts, l, optsbuf);
320a53f50b9Schristos }
321a53f50b9Schristos # endif /* MNTTAB_OPT_PROTO */
322a53f50b9Schristos
323a53f50b9Schristos /* finally, store the options into the mount table structure */
324a53f50b9Schristos mnt->mnt_opts = zopts;
325a53f50b9Schristos
326a53f50b9Schristos /*
327a53f50b9Schristos * Additional fields in mntent_t
328a53f50b9Schristos * are fixed up here
329a53f50b9Schristos */
330a53f50b9Schristos # ifdef HAVE_MNTENT_T_MNT_CNODE
331a53f50b9Schristos mnt->mnt_cnode = 0;
332a53f50b9Schristos # endif /* HAVE_MNTENT_T_MNT_CNODE */
333a53f50b9Schristos
334a53f50b9Schristos # ifdef HAVE_MNTENT_T_MNT_RO
335a53f50b9Schristos mnt->mnt_ro = (amu_hasmntopt(mnt, MNTTAB_OPT_RO) != NULL);
336a53f50b9Schristos # endif /* HAVE_MNTENT_T_MNT_RO */
337a53f50b9Schristos
338a53f50b9Schristos # ifdef HAVE_MNTENT_T_MNT_TIME
339a53f50b9Schristos # ifdef HAVE_MNTENT_T_MNT_TIME_STRING
340a53f50b9Schristos { /* allocate enough space for a long */
341a53f50b9Schristos size_t l = 13 * sizeof(char);
342a53f50b9Schristos char *str = (char *) xmalloc(l);
343a53f50b9Schristos xsnprintf(str, l, "%ld", time((time_t *) NULL));
344a53f50b9Schristos mnt->mnt_time = str;
345a53f50b9Schristos }
346a53f50b9Schristos # else /* not HAVE_MNTENT_T_MNT_TIME_STRING */
347a53f50b9Schristos mnt->mnt_time = time((time_t *) NULL);
348a53f50b9Schristos # endif /* not HAVE_MNTENT_T_MNT_TIME_STRING */
349a53f50b9Schristos # endif /* HAVE_MNTENT_T_MNT_TIME */
350a53f50b9Schristos
351a53f50b9Schristos write_mntent(mnt, mnttabname);
352a53f50b9Schristos
353a53f50b9Schristos # ifdef MNTTAB_OPT_DEV
354a53f50b9Schristos if (xopts) {
355a53f50b9Schristos XFREE(mnt->mnt_opts);
356a53f50b9Schristos mnt->mnt_opts = xopts;
357a53f50b9Schristos }
358a53f50b9Schristos # endif /* MNTTAB_OPT_DEV */
359a53f50b9Schristos #endif /* MOUNT_TABLE_ON_FILE */
360a53f50b9Schristos
361a53f50b9Schristos out:
362a53f50b9Schristos XFREE(mnt_dir);
363a53f50b9Schristos return error;
364a53f50b9Schristos }
365a53f50b9Schristos
366a53f50b9Schristos
367a53f50b9Schristos /*
368a53f50b9Schristos * Compute all NFS attribute cache related flags separately. Note that this
369a53f50b9Schristos * function now computes attribute-cache flags for both Amd's automount
370a53f50b9Schristos * points (NFS) as well as any normal NFS mount that Amd performs. Edit
371a53f50b9Schristos * with caution.
372a53f50b9Schristos */
373a53f50b9Schristos static void
compute_nfs_attrcache_flags(struct nfs_common_args * nap,mntent_t * mntp)374*4da6d876Schristos compute_nfs_attrcache_flags(struct nfs_common_args *nap, mntent_t *mntp)
375a53f50b9Schristos {
376a53f50b9Schristos int acval = 0;
377a53f50b9Schristos int err_acval = 1; /* 1 means we found no 'actimeo' value */
378a53f50b9Schristos #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)
379a53f50b9Schristos int err_acrdmm; /* for ac{reg,dir}{min,max} */
380a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_AC{REG,DIR}{MIN,MAX} */
381a53f50b9Schristos
382a53f50b9Schristos /************************************************************************/
383a53f50b9Schristos /*** ATTRIBUTE CACHES ***/
384a53f50b9Schristos /************************************************************************/
385a53f50b9Schristos /*
386a53f50b9Schristos * acval is set to 0 at the top of the function. If actimeo mount option
387a53f50b9Schristos * exists and defined in mntopts, then its acval is set to it.
388a53f50b9Schristos * If the value is non-zero, then we set all attribute cache fields to it.
389a53f50b9Schristos * If acval is zero, it means it was never defined in mntopts or the
390a53f50b9Schristos * actimeo mount option does not exist, in which case we check for
391a53f50b9Schristos * individual mount options per attribute cache.
392a53f50b9Schristos * Regardless of the value of acval, mount flags are set based directly
393a53f50b9Schristos * on the values of the attribute caches.
394a53f50b9Schristos */
395a53f50b9Schristos #ifdef MNTTAB_OPT_ACTIMEO
396a53f50b9Schristos err_acval = hasmntvalerr(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */
397a53f50b9Schristos #endif /* MNTTAB_OPT_ACTIMEO */
398a53f50b9Schristos
399a53f50b9Schristos /*** acregmin ***/
400a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_ACREGMIN
401a53f50b9Schristos err_acrdmm = 1; /* 1 means we found no acregmin value */
402a53f50b9Schristos if (!err_acval) {
403a53f50b9Schristos nap->acregmin = acval; /* min ac timeout for reg files (sec) */
404a53f50b9Schristos } else {
405a53f50b9Schristos # ifdef MNTTAB_OPT_ACREGMIN
406*4da6d876Schristos int tmp;
407*4da6d876Schristos err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, &tmp);
408*4da6d876Schristos nap->acregmin = tmp;
409a53f50b9Schristos # else /* not MNTTAB_OPT_ACREGMIN */
410a53f50b9Schristos nap->acregmin = 0;
411a53f50b9Schristos # endif /* not MNTTAB_OPT_ACREGMIN */
412a53f50b9Schristos }
413a53f50b9Schristos /* set this flag iff we changed acregmin (possibly to zero) */
414a53f50b9Schristos # ifdef MNT2_NFS_OPT_ACREGMIN
415a53f50b9Schristos if (!err_acval || !err_acrdmm)
416a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_ACREGMIN;
417a53f50b9Schristos # endif /* MNT2_NFS_OPT_ACREGMIN */
418a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_ACREGMIN */
419a53f50b9Schristos
420a53f50b9Schristos /*** acregmax ***/
421a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_ACREGMAX
422a53f50b9Schristos err_acrdmm = 1; /* 1 means we found no acregmax value */
423a53f50b9Schristos if (!err_acval) {
424a53f50b9Schristos nap->acregmax = acval; /* max ac timeout for reg files (sec) */
425a53f50b9Schristos } else {
426a53f50b9Schristos # ifdef MNTTAB_OPT_ACREGMAX
427*4da6d876Schristos int tmp;
428*4da6d876Schristos err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, &tmp);
429*4da6d876Schristos nap->acregmax = tmp;
430a53f50b9Schristos # else /* not MNTTAB_OPT_ACREGMAX */
431a53f50b9Schristos nap->acregmax = 0;
432a53f50b9Schristos # endif /* not MNTTAB_OPT_ACREGMAX */
433a53f50b9Schristos }
434a53f50b9Schristos /* set this flag iff we changed acregmax (possibly to zero) */
435a53f50b9Schristos # ifdef MNT2_NFS_OPT_ACREGMAX
436a53f50b9Schristos if (!err_acval || !err_acrdmm)
437a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_ACREGMAX;
438a53f50b9Schristos # endif /* MNT2_NFS_OPT_ACREGMAX */
439a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_ACREGMAX */
440a53f50b9Schristos
441a53f50b9Schristos /*** acdirmin ***/
442a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_ACDIRMIN
443a53f50b9Schristos err_acrdmm = 1; /* 1 means we found no acdirmin value */
444a53f50b9Schristos if (!err_acval) {
445a53f50b9Schristos nap->acdirmin = acval; /* min ac timeout for dirs (sec) */
446a53f50b9Schristos } else {
447a53f50b9Schristos # ifdef MNTTAB_OPT_ACDIRMIN
448*4da6d876Schristos int tmp;
449*4da6d876Schristos err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, &tmp);
450*4da6d876Schristos nap->acdirmin = tmp;
451a53f50b9Schristos # else /* not MNTTAB_OPT_ACDIRMIN */
452a53f50b9Schristos nap->acdirmin = 0;
453a53f50b9Schristos # endif /* not MNTTAB_OPT_ACDIRMIN */
454a53f50b9Schristos }
455a53f50b9Schristos /* set this flag iff we changed acdirmin (possibly to zero) */
456a53f50b9Schristos # ifdef MNT2_NFS_OPT_ACDIRMIN
457a53f50b9Schristos if (!err_acval || !err_acrdmm)
458a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_ACDIRMIN;
459a53f50b9Schristos # endif /* MNT2_NFS_OPT_ACDIRMIN */
460a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_ACDIRMIN */
461a53f50b9Schristos
462a53f50b9Schristos /*** acdirmax ***/
463a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_ACDIRMAX
464a53f50b9Schristos err_acrdmm = 1; /* 1 means we found no acdirmax value */
465a53f50b9Schristos if (!err_acval) {
466a53f50b9Schristos nap->acdirmax = acval; /* max ac timeout for dirs (sec) */
467a53f50b9Schristos } else {
468a53f50b9Schristos # ifdef MNTTAB_OPT_ACDIRMAX
469*4da6d876Schristos int tmp;
470*4da6d876Schristos err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, &tmp);
471*4da6d876Schristos nap->acdirmax = tmp;
472a53f50b9Schristos # else /* not MNTTAB_OPT_ACDIRMAX */
473a53f50b9Schristos nap->acdirmax = 0;
474a53f50b9Schristos # endif /* not MNTTAB_OPT_ACDIRMAX */
475a53f50b9Schristos }
476a53f50b9Schristos /* set this flag iff we changed acdirmax (possibly to zero) */
477a53f50b9Schristos # ifdef MNT2_NFS_OPT_ACDIRMAX
478a53f50b9Schristos if (!err_acval || !err_acrdmm)
479a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_ACDIRMAX;
480a53f50b9Schristos # endif /* MNT2_NFS_OPT_ACDIRMAX */
481a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_ACDIRMAX */
482a53f50b9Schristos
483a53f50b9Schristos
484a53f50b9Schristos /* don't cache attributes */
485a53f50b9Schristos #if defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC)
486a53f50b9Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_NOAC) != NULL)
487a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_NOAC;
488a53f50b9Schristos #endif /* defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) */
48945b261d1Schristos (void)err_acval;
490a53f50b9Schristos }
491a53f50b9Schristos
492a53f50b9Schristos
493*4da6d876Schristos
494*4da6d876Schristos static void
compute_nfs_common_args(struct nfs_common_args * nap,mntent_t * mntp,const char * nfs_proto,u_long nfs_version)495*4da6d876Schristos compute_nfs_common_args(struct nfs_common_args *nap, mntent_t *mntp,
496*4da6d876Schristos const char *nfs_proto, u_long nfs_version)
497*4da6d876Schristos {
498*4da6d876Schristos #ifdef MNT2_NFS_OPT_TCP
499*4da6d876Schristos if (nfs_proto && STREQ(nfs_proto, "tcp"))
500*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_TCP;
501*4da6d876Schristos #endif /* MNT2_NFS_OPT_TCP */
502*4da6d876Schristos
503*4da6d876Schristos #ifdef MNT2_NFS_OPT_NOCONN
504*4da6d876Schristos /* check if user specified to use unconnected or connected sockets */
505*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL)
506*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_NOCONN;
507*4da6d876Schristos else if (amu_hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL)
508*4da6d876Schristos nap->flags &= ~MNT2_NFS_OPT_NOCONN;
509*4da6d876Schristos else {
510*4da6d876Schristos /*
511*4da6d876Schristos * Some OSs want you to set noconn always. Some want you to always turn
512*4da6d876Schristos * it off. Others want you to turn it on/off only if NFS V.3 is used.
513*4da6d876Schristos * And all of that changes from revision to another. This is
514*4da6d876Schristos * particularly true of OpenBSD, NetBSD, and FreeBSD. So, rather than
515*4da6d876Schristos * attempt to auto-detect this, I'm forced to "fix" it in the individual
516*4da6d876Schristos * conf/nfs_prot/nfs_prot_*.h files.
517*4da6d876Schristos */
518*4da6d876Schristos # ifdef USE_UNCONNECTED_NFS_SOCKETS
519*4da6d876Schristos if (!(nap->flags & MNT2_NFS_OPT_NOCONN)) {
520*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_NOCONN;
521*4da6d876Schristos plog(XLOG_WARNING, "noconn option not specified, and was just turned ON (OS override)! (May cause NFS hangs on some systems...)");
522*4da6d876Schristos }
523*4da6d876Schristos # endif /* USE_UNCONNECTED_NFS_SOCKETS */
524*4da6d876Schristos # ifdef USE_CONNECTED_NFS_SOCKETS
525*4da6d876Schristos if (nap->flags & MNT2_NFS_OPT_NOCONN) {
526*4da6d876Schristos nap->flags &= ~MNT2_NFS_OPT_NOCONN;
527*4da6d876Schristos plog(XLOG_WARNING, "noconn option specified, and was just turned OFF (OS override)! (May cause NFS hangs on some systems...)");
528*4da6d876Schristos }
529*4da6d876Schristos # endif /* USE_CONNECTED_NFS_SOCKETS */
530*4da6d876Schristos }
531*4da6d876Schristos #endif /* MNT2_NFS_OPT_NOCONN */
532*4da6d876Schristos
533*4da6d876Schristos #ifdef MNT2_NFS_OPT_RESVPORT
534*4da6d876Schristos # ifdef MNTTAB_OPT_RESVPORT
535*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_RESVPORT) != NULL)
536*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_RESVPORT;
537*4da6d876Schristos # else /* not MNTTAB_OPT_RESVPORT */
538*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_RESVPORT;
539*4da6d876Schristos # endif /* not MNTTAB_OPT_RESVPORT */
540*4da6d876Schristos #endif /* MNT2_NFS_OPT_RESVPORT */
541*4da6d876Schristos
542*4da6d876Schristos nap->rsize = hasmntval(mntp, MNTTAB_OPT_RSIZE);
543*4da6d876Schristos #ifdef MNT2_NFS_OPT_RSIZE
544*4da6d876Schristos if (nap->rsize)
545*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_RSIZE;
546*4da6d876Schristos #endif /* MNT2_NFS_OPT_RSIZE */
547*4da6d876Schristos if (nfs_version == NFS_VERSION && nap->rsize > 8192)
548*4da6d876Schristos nap->rsize = 8192;
549*4da6d876Schristos
550*4da6d876Schristos nap->wsize = hasmntval(mntp, MNTTAB_OPT_WSIZE);
551*4da6d876Schristos #ifdef MNT2_NFS_OPT_WSIZE
552*4da6d876Schristos if (nap->wsize)
553*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_WSIZE;
554*4da6d876Schristos #endif /* MNT2_NFS_OPT_WSIZE */
555*4da6d876Schristos if (nfs_version == NFS_VERSION && nap->wsize > 8192)
556*4da6d876Schristos nap->wsize = 8192;
557*4da6d876Schristos
558*4da6d876Schristos nap->timeo = hasmntval(mntp, MNTTAB_OPT_TIMEO);
559*4da6d876Schristos #ifdef MNT2_NFS_OPT_TIMEO
560*4da6d876Schristos if (nap->timeo)
561*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_TIMEO;
562*4da6d876Schristos #endif /* MNT2_NFS_OPT_TIMEO */
563*4da6d876Schristos
564*4da6d876Schristos nap->retrans = hasmntval(mntp, MNTTAB_OPT_RETRANS);
565*4da6d876Schristos #ifdef MNT2_NFS_OPT_RETRANS
566*4da6d876Schristos if (nap->retrans)
567*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_RETRANS;
568*4da6d876Schristos #endif /* MNT2_NFS_OPT_RETRANS */
569*4da6d876Schristos
570*4da6d876Schristos #ifdef MNT2_NFS_OPT_SOFT
571*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL)
572*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_SOFT;
573*4da6d876Schristos #endif /* MNT2_NFS_OPT_SOFT */
574*4da6d876Schristos
575*4da6d876Schristos #ifdef MNT2_NFS_OPT_SPONGY
576*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) {
577*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_SPONGY;
578*4da6d876Schristos if (*flags & MNT2_NFS_OPT_SOFT) {
579*4da6d876Schristos plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored");
580*4da6d876Schristos nap->flags &= ~MNT2_NFS_OPT_SOFT;
581*4da6d876Schristos }
582*4da6d876Schristos }
583*4da6d876Schristos #endif /* MNT2_NFS_OPT_SPONGY */
584*4da6d876Schristos
585*4da6d876Schristos #if defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY)
586*4da6d876Schristos /* Ultrix has separate generic and NFS ro flags */
587*4da6d876Schristos if (genflags & MNT2_GEN_OPT_RONLY)
588*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_RONLY;
589*4da6d876Schristos #endif /* defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) */
590*4da6d876Schristos
591*4da6d876Schristos #ifdef MNTTAB_OPT_INTR
592*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL)
593*4da6d876Schristos /*
594*4da6d876Schristos * Either turn on the "allow interrupts" option, or
595*4da6d876Schristos * turn off the "disallow interrupts" option"
596*4da6d876Schristos */
597*4da6d876Schristos # ifdef MNT2_NFS_OPT_INTR
598*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_INTR;
599*4da6d876Schristos # endif /* MNT2_NFS_OPT_INTR */
600*4da6d876Schristos # ifdef MNT2_NFS_OPT_NOINTR
601*4da6d876Schristos nap->flags &= ~MNT2_NFS_OPT_NOINTR;
602*4da6d876Schristos # endif /* MNT2_NFS_OPT_NOINTR */
603*4da6d876Schristos # ifdef MNT2_NFS_OPT_INT
604*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_INT;
605*4da6d876Schristos # endif /* MNT2_NFS_OPT_INT */
606*4da6d876Schristos # ifdef MNT2_NFS_OPT_NOINT
607*4da6d876Schristos nap->flags &= ~MNT2_NFS_OPT_NOINT;
608*4da6d876Schristos # endif /* MNT2_NFS_OPT_NOINT */
609*4da6d876Schristos #endif /* MNTTAB_OPT_INTR */
610*4da6d876Schristos
611*4da6d876Schristos #ifdef MNT2_NFS_OPT_NOACL
612*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_NOACL) != NULL)
613*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_NOACL;
614*4da6d876Schristos #endif /* MNT2_NFS_OPT_NOACL */
615*4da6d876Schristos
616*4da6d876Schristos #ifdef MNTTAB_OPT_NODEVS
617*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL)
618*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_NODEVS;
619*4da6d876Schristos #endif /* MNTTAB_OPT_NODEVS */
620*4da6d876Schristos
621*4da6d876Schristos #ifdef MNTTAB_OPT_COMPRESS
622*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_COMPRESS) != NULL)
623*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_COMPRESS;
624*4da6d876Schristos #endif /* MNTTAB_OPT_COMPRESS */
625*4da6d876Schristos
626*4da6d876Schristos #ifdef MNTTAB_OPT_PRIVATE /* mount private, single-client tree */
627*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL)
628*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_PRIVATE;
629*4da6d876Schristos #endif /* MNTTAB_OPT_PRIVATE */
630*4da6d876Schristos
631*4da6d876Schristos
632*4da6d876Schristos #if defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO)
633*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL)
634*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_NOCTO;
635*4da6d876Schristos #endif /* defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) */
636*4da6d876Schristos
637*4da6d876Schristos #if defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST)
638*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL)
639*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_PROPLIST;
640*4da6d876Schristos #endif /* defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) */
641*4da6d876Schristos
642*4da6d876Schristos #if defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK)
643*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL)
644*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_NONLM;
645*4da6d876Schristos #endif /* defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) */
646*4da6d876Schristos
647*4da6d876Schristos #if defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE)
648*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_XLATECOOKIE) != NULL)
649*4da6d876Schristos nap->flags |= MNT2_NFS_OPT_XLATECOOKIE;
650*4da6d876Schristos #endif /* defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) */
651*4da6d876Schristos }
652*4da6d876Schristos
653*4da6d876Schristos #ifdef DEBUG
654*4da6d876Schristos static void
print_nfs_common_args(const struct nfs_common_args * a)655*4da6d876Schristos print_nfs_common_args(const struct nfs_common_args *a)
656*4da6d876Schristos {
657*4da6d876Schristos plog(XLOG_DEBUG, "NA->flags = 0x%lx", a->flags);
658*4da6d876Schristos
659*4da6d876Schristos plog(XLOG_DEBUG, "NA->rsize = %lu", a->rsize);
660*4da6d876Schristos plog(XLOG_DEBUG, "NA->wsize = %lu", a->wsize);
661*4da6d876Schristos plog(XLOG_DEBUG, "NA->timeo = %lu", a->timeo);
662*4da6d876Schristos plog(XLOG_DEBUG, "NA->retrans = %lu", a->retrans);
663*4da6d876Schristos
664*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_ACREGMIN
665*4da6d876Schristos plog(XLOG_DEBUG, "NA->acregmin = %lu", a->acregmin);
666*4da6d876Schristos plog(XLOG_DEBUG, "NA->acregmax = %lu", a->acregmax);
667*4da6d876Schristos plog(XLOG_DEBUG, "NA->acdirmin = %lu", a->acdirmin);
668*4da6d876Schristos plog(XLOG_DEBUG, "NA->acdirmax = %lu", a->acdirmax);
669*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_ACREGMIN */
670*4da6d876Schristos }
671*4da6d876Schristos #endif
672*4da6d876Schristos
673*4da6d876Schristos static void
discard_nfs23_args(nfs_args_t * nap)674*4da6d876Schristos discard_nfs23_args(nfs_args_t *nap)
675*4da6d876Schristos {
676*4da6d876Schristos #ifdef HAVE_TRANSPORT_TYPE_TLI
677*4da6d876Schristos free_knetconfig(nap->knconf);
678*4da6d876Schristos if (nap->addr)
679*4da6d876Schristos XFREE(nap->addr); /* allocated in compute_nfs_args() */
680*4da6d876Schristos #endif /* HAVE_TRANSPORT_TYPE_TLI */
681*4da6d876Schristos }
682*4da6d876Schristos
683*4da6d876Schristos #ifdef DEBUG
684*4da6d876Schristos /* get string version (in hex) of identifier */
685*4da6d876Schristos static char *
get_hex_string(u_int len,const char * fhdata)686*4da6d876Schristos get_hex_string(u_int len, const char *fhdata)
687*4da6d876Schristos {
688*4da6d876Schristos u_int i;
689*4da6d876Schristos static u_int xlen;
690*4da6d876Schristos static char *buf;
691*4da6d876Schristos static u_short *arr;
692*4da6d876Schristos char str[16];
693*4da6d876Schristos
694*4da6d876Schristos if (!fhdata || len == 0 || len > 10240)
695*4da6d876Schristos return NULL;
696*4da6d876Schristos i = len * 4 + 1;
697*4da6d876Schristos if (xlen < i) {
698*4da6d876Schristos buf = xrealloc(buf, i);
699*4da6d876Schristos arr = xrealloc(arr, len * sizeof(*arr));
700*4da6d876Schristos xlen = i;
701*4da6d876Schristos }
702*4da6d876Schristos
703*4da6d876Schristos buf[0] = '\0';
704*4da6d876Schristos memset(arr, 0, len * sizeof(*arr));
705*4da6d876Schristos memcpy(arr, fhdata, len);
706*4da6d876Schristos len /= sizeof(*arr);
707*4da6d876Schristos for (i = 0; i < len; i++) {
708*4da6d876Schristos xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i]));
709*4da6d876Schristos xstrlcat(buf, str, xlen);
710*4da6d876Schristos }
711*4da6d876Schristos return buf;
712*4da6d876Schristos }
713*4da6d876Schristos
714*4da6d876Schristos static void
print_nfs_sockaddr_in(const char * tag,const struct sockaddr_in * sap)715*4da6d876Schristos print_nfs_sockaddr_in(const char *tag, const struct sockaddr_in *sap)
716*4da6d876Schristos {
717*4da6d876Schristos char name[64];
718*4da6d876Schristos plog(XLOG_DEBUG, "NA->%s.sin_family = %d", tag, sap->sin_family);
719*4da6d876Schristos plog(XLOG_DEBUG, "NA->%s.sin_port = %d", tag, ntohs(sap->sin_port));
720*4da6d876Schristos if (inet_ntop(AF_INET, &sap->sin_addr, name, sizeof(name)) == NULL)
721*4da6d876Schristos return;
722*4da6d876Schristos plog(XLOG_DEBUG, "NA->%s.sin_addr = \"%s\"", tag, name);
723*4da6d876Schristos }
724*4da6d876Schristos
725*4da6d876Schristos /*
726*4da6d876Schristos * print a subset of fields from "struct nfs_args" that are otherwise
727*4da6d876Schristos * not being provided anywhere else.
728*4da6d876Schristos */
729*4da6d876Schristos static void
print_nfs23_args(const nfs_args_t * nap,u_long nfs_version)730*4da6d876Schristos print_nfs23_args(const nfs_args_t *nap, u_long nfs_version)
731*4da6d876Schristos {
732*4da6d876Schristos int fhlen = 32; /* default: NFS V.2 file handle length is 32 */
733*4da6d876Schristos #ifdef HAVE_TRANSPORT_TYPE_TLI
734*4da6d876Schristos struct netbuf *nbp;
735*4da6d876Schristos struct knetconfig *kncp;
736*4da6d876Schristos #else /* not HAVE_TRANSPORT_TYPE_TLI */
737*4da6d876Schristos struct sockaddr_in *sap;
738*4da6d876Schristos #endif /* not HAVE_TRANSPORT_TYPE_TLI */
739*4da6d876Schristos struct nfs_common_args a;
740*4da6d876Schristos
741*4da6d876Schristos if (!nap) {
742*4da6d876Schristos plog(XLOG_DEBUG, "NULL nfs_args!");
743*4da6d876Schristos return;
744*4da6d876Schristos }
745*4da6d876Schristos
746*4da6d876Schristos /* override default file handle size */
747*4da6d876Schristos #ifdef FHSIZE
748*4da6d876Schristos fhlen = FHSIZE;
749*4da6d876Schristos #endif /* FHSIZE */
750*4da6d876Schristos #ifdef NFS_FHSIZE
751*4da6d876Schristos fhlen = NFS_FHSIZE;
752*4da6d876Schristos #endif /* NFS_FHSIZE */
753*4da6d876Schristos
754*4da6d876Schristos #ifdef HAVE_TRANSPORT_TYPE_TLI
755*4da6d876Schristos nbp = nap->addr;
756*4da6d876Schristos plog(XLOG_DEBUG, "NA->addr {netbuf} (maxlen=%d, len=%d) = \"%s\"",
757*4da6d876Schristos nbp->maxlen, nbp->len,
758*4da6d876Schristos get_hex_string(nbp->len, nbp->buf));
759*4da6d876Schristos nbp = nap->syncaddr;
760*4da6d876Schristos plog(XLOG_DEBUG, "NA->syncaddr {netbuf} %p", nbp);
761*4da6d876Schristos kncp = nap->knconf;
762*4da6d876Schristos plog(XLOG_DEBUG, "NA->knconf->semantics %lu", (u_long) kncp->knc_semantics);
763*4da6d876Schristos plog(XLOG_DEBUG, "NA->knconf->protofmly \"%s\"", kncp->knc_protofmly);
764*4da6d876Schristos plog(XLOG_DEBUG, "NA->knconf->proto \"%s\"", kncp->knc_proto);
765*4da6d876Schristos plog(XLOG_DEBUG, "NA->knconf->rdev %lu", (u_long) kncp->knc_rdev);
766*4da6d876Schristos /* don't print knconf->unused field */
767*4da6d876Schristos #else /* not HAVE_TRANSPORT_TYPE_TLI */
768*4da6d876Schristos # ifdef NFS_ARGS_T_ADDR_IS_POINTER
769*4da6d876Schristos sap = (struct sockaddr_in *) nap->addr;
770*4da6d876Schristos # else /* not NFS_ARGS_T_ADDR_IS_POINTER */
771*4da6d876Schristos sap = (struct sockaddr_in *) &nap->addr;
772*4da6d876Schristos # endif /* not NFS_ARGS_T_ADDR_IS_POINTER */
773*4da6d876Schristos #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
774*4da6d876Schristos /* as per POSIX, sin_len need not be set (used internally by kernel) */
775*4da6d876Schristos plog(XLOG_DEBUG, "NA->addr.sin_len = %d", sap->sin_len);
776*4da6d876Schristos #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
777*4da6d876Schristos print_nfs_sockaddr_in("addr", sap);
778*4da6d876Schristos #endif /* not HAVE_TRANSPORT_TYPE_TLI */
779*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_ADDRLEN
780*4da6d876Schristos plog(XLOG_DEBUG, "NA->addrlen = %d", nap->addrlen);
781*4da6d876Schristos #endif /* ifdef HAVE_NFS_ARGS_T_ADDRLEN */
782*4da6d876Schristos
783*4da6d876Schristos plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname ? nap->hostname : "null");
784*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_NAMLEN
785*4da6d876Schristos plog(XLOG_DEBUG, "NA->namlen = %d", nap->namlen);
786*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_NAMLEN */
787*4da6d876Schristos
788*4da6d876Schristos #ifdef MNT2_NFS_OPT_FSNAME
789*4da6d876Schristos plog(XLOG_DEBUG, "NA->fsname = \"%s\"", nap->fsname ? nap->fsname : "null");
790*4da6d876Schristos #endif /* MNT2_NFS_OPT_FSNAME */
791*4da6d876Schristos
792*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_FHSIZE
793*4da6d876Schristos plog(XLOG_DEBUG, "NA->fhsize = %d", nap->fhsize);
794*4da6d876Schristos fhlen = nap->fhsize;
795*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_FHSIZE */
796*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_FH_LEN
797*4da6d876Schristos plog(XLOG_DEBUG, "NA->fh_len = %d", nap->fh_len);
798*4da6d876Schristos fhlen = nap->fh_len;
799*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_FH_LEN */
800*4da6d876Schristos
801*4da6d876Schristos /*
802*4da6d876Schristos * XXX: need to figure out how to correctly print file handles,
803*4da6d876Schristos * since some times they are pointers, and sometimes the real structure
804*4da6d876Schristos * is stored in nfs_args. Even if it is a pointer, it can be the actual
805*4da6d876Schristos * char[] array, or a structure containing multiple fields.
806*4da6d876Schristos */
807*4da6d876Schristos plog(XLOG_DEBUG, "NA->filehandle = \"%s\"",
808*4da6d876Schristos get_hex_string(fhlen, (const char *) &nap->NFS_FH_FIELD));
809*4da6d876Schristos
810*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_SOTYPE
811*4da6d876Schristos plog(XLOG_DEBUG, "NA->sotype = %d", nap->sotype);
812*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_SOTYPE */
813*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_PROTO
814*4da6d876Schristos plog(XLOG_DEBUG, "NA->proto = %d", (int) nap->proto);
815*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_PROTO */
816*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_VERSION
817*4da6d876Schristos plog(XLOG_DEBUG, "NA->version = %d", nap->version);
818*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_VERSION */
819*4da6d876Schristos
820*4da6d876Schristos put_nfs_common_args(nap, a);
821*4da6d876Schristos print_nfs_common_args(&a);
822*4da6d876Schristos
823*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_BSIZE
824*4da6d876Schristos plog(XLOG_DEBUG, "NA->bsize = %d", nap->bsize);
825*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_BSIZE */
826*4da6d876Schristos
827*4da6d876Schristos #ifdef MNTTAB_OPT_SYMTTL
828*4da6d876Schristos plog(XLOG_DEBUG, "NA->symttl = %d", nap->symttl);
829*4da6d876Schristos #endif /* MNTTAB_OPT_SYMTTL */
830*4da6d876Schristos #ifdef MNTTAB_OPT_PG_THRESH
831*4da6d876Schristos plog(XLOG_DEBUG, "NA->pg_thresh = %d", nap->pg_thresh);
832*4da6d876Schristos #endif /* MNTTAB_OPT_PG_THRESH */
833*4da6d876Schristos
834*4da6d876Schristos #ifdef MNT2_NFS_OPT_BIODS
835*4da6d876Schristos plog(XLOG_DEBUG, "NA->biods = %d", nap->biods);
836*4da6d876Schristos #endif /* MNT2_NFS_OPT_BIODS */
837*4da6d876Schristos
838*4da6d876Schristos }
839*4da6d876Schristos #endif /* DEBUG */
840*4da6d876Schristos
841a53f50b9Schristos /*
842a53f50b9Schristos * Fill in the many possible fields and flags of struct nfs_args.
843a53f50b9Schristos *
844a53f50b9Schristos * nap: pre-allocated structure to fill in.
845a53f50b9Schristos * mntp: mount entry structure (includes options)
846a53f50b9Schristos * genflags: generic mount flags already determined
847a53f50b9Schristos * nfsncp: (TLI only) netconfig entry for this NFS mount
848a53f50b9Schristos * ip_addr: IP address of file server
849*4da6d876Schristos * nfs_version: 2, 3, or 0 if unknown
850a53f50b9Schristos * nfs_proto: "udp", "tcp", or NULL.
851a53f50b9Schristos * fhp: file handle structure pointer
852a53f50b9Schristos * host_name: name of remote NFS host
853a53f50b9Schristos * fs_name: remote file system name to mount
854a53f50b9Schristos */
855*4da6d876Schristos static void
compute_nfs23_args(nfs_args_t * nap,mntent_t * mntp,int genflags,struct netconfig * nfsncp,struct sockaddr_in * ip_addr,u_long nfs_version,char * nfs_proto,am_nfs_handle_t * fhp,char * host_name,char * fs_name)856*4da6d876Schristos compute_nfs23_args(nfs_args_t *nap,
857a53f50b9Schristos mntent_t *mntp,
858a53f50b9Schristos int genflags,
859a53f50b9Schristos struct netconfig *nfsncp,
860a53f50b9Schristos struct sockaddr_in *ip_addr,
861a53f50b9Schristos u_long nfs_version,
862a53f50b9Schristos char *nfs_proto,
863a53f50b9Schristos am_nfs_handle_t *fhp,
864a53f50b9Schristos char *host_name,
865a53f50b9Schristos char *fs_name)
866a53f50b9Schristos {
867*4da6d876Schristos struct nfs_common_args a;
868a53f50b9Schristos /* initialize just in case */
869a53f50b9Schristos memset((voidp) nap, 0, sizeof(nfs_args_t));
870a53f50b9Schristos
871a53f50b9Schristos /* compute all of the NFS attribute-cache flags */
872*4da6d876Schristos memset(&a, 0, sizeof(a));
873*4da6d876Schristos compute_nfs_attrcache_flags(&a, mntp);
874*4da6d876Schristos compute_nfs_common_args(&a, mntp, nfs_proto, nfs_version);
875*4da6d876Schristos get_nfs_common_args(nap, a);
876a53f50b9Schristos
877a53f50b9Schristos /************************************************************************/
878a53f50b9Schristos /*** FILEHANDLE DATA AND LENGTH ***/
879a53f50b9Schristos /************************************************************************/
880a53f50b9Schristos #ifdef HAVE_FS_NFS3
881a53f50b9Schristos if (nfs_version == NFS_VERSION3) {
882*4da6d876Schristos if (fhp == NULL) {
883*4da6d876Schristos plog(XLOG_FATAL, "cannot pass NULL fh for NFSv%lu", nfs_version);
884*4da6d876Schristos going_down(1);
885*4da6d876Schristos return;
886*4da6d876Schristos }
887*4da6d876Schristos
888a53f50b9Schristos # if defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN)
889a53f50b9Schristos /*
890a53f50b9Schristos * Some systems (Irix/bsdi3) have a separate field in nfs_args for
891a53f50b9Schristos * the length of the file handle for NFS V3. They insist that
892a53f50b9Schristos * the file handle set in nfs_args be plain bytes, and not
893a53f50b9Schristos * include the length field.
894a53f50b9Schristos */
895a53f50b9Schristos NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3.am_fh3_data);
896a53f50b9Schristos # else /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
897a53f50b9Schristos NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3);
898a53f50b9Schristos # endif /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */
899a53f50b9Schristos # ifdef MNT2_NFS_OPT_NFSV3
900a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_NFSV3;
901a53f50b9Schristos # endif /* MNT2_NFS_OPT_NFSV3 */
902a53f50b9Schristos # ifdef MNT2_NFS_OPT_VER3
903a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_VER3;
904a53f50b9Schristos # endif /* MNT2_NFS_OPT_VER3 */
905a53f50b9Schristos } else
906a53f50b9Schristos #endif /* HAVE_FS_NFS3 */
907*4da6d876Schristos {
908*4da6d876Schristos if (fhp == NULL) {
909*4da6d876Schristos plog(XLOG_FATAL, "cannot pass NULL fh for NFSv%lu", nfs_version);
910*4da6d876Schristos going_down(1);
911*4da6d876Schristos return;
912*4da6d876Schristos }
913a53f50b9Schristos NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v2);
914*4da6d876Schristos }
915a53f50b9Schristos
916a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_FHSIZE
917a53f50b9Schristos # ifdef HAVE_FS_NFS3
918a53f50b9Schristos if (nfs_version == NFS_VERSION3)
919a53f50b9Schristos nap->fhsize = fhp->v3.am_fh3_length;
920a53f50b9Schristos else
921a53f50b9Schristos # endif /* HAVE_FS_NFS3 */
922a53f50b9Schristos nap->fhsize = FHSIZE;
923a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_FHSIZE */
924a53f50b9Schristos
925a53f50b9Schristos /* this is the version of the nfs_args structure, not of NFS! */
926a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_FH_LEN
927a53f50b9Schristos # ifdef HAVE_FS_NFS3
928a53f50b9Schristos if (nfs_version == NFS_VERSION3)
929a53f50b9Schristos nap->fh_len = fhp->v3.am_fh3_length;
930a53f50b9Schristos else
931a53f50b9Schristos # endif /* HAVE_FS_NFS3 */
932a53f50b9Schristos nap->fh_len = FHSIZE;
933a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_FH_LEN */
934a53f50b9Schristos
935a53f50b9Schristos /************************************************************************/
936a53f50b9Schristos /*** HOST NAME ***/
937a53f50b9Schristos /************************************************************************/
938a53f50b9Schristos /*
939a53f50b9Schristos * XXX: warning, using xstrlcpy in NFS_HN_DREF, which may corrupt a
940a53f50b9Schristos * struct nfs_args, or truncate our concocted "hostname:/path"
941a53f50b9Schristos * string prematurely.
942a53f50b9Schristos */
943a53f50b9Schristos NFS_HN_DREF(nap->hostname, host_name);
944a53f50b9Schristos #ifdef MNT2_NFS_OPT_HOSTNAME
945a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_HOSTNAME;
946a53f50b9Schristos #endif /* MNT2_NFS_OPT_HOSTNAME */
947a53f50b9Schristos
948a53f50b9Schristos /************************************************************************/
949a53f50b9Schristos /*** IP ADDRESS OF REMOTE HOST ***/
950a53f50b9Schristos /************************************************************************/
951a53f50b9Schristos if (ip_addr) {
952a53f50b9Schristos #ifdef HAVE_TRANSPORT_TYPE_TLI
953a53f50b9Schristos nap->addr = ALLOC(struct netbuf); /* free()'ed at end of mount_nfs_fh() */
954a53f50b9Schristos #endif /* HAVE_TRANSPORT_TYPE_TLI */
955a53f50b9Schristos NFS_SA_DREF(nap, ip_addr);
956a53f50b9Schristos }
957a53f50b9Schristos
958a53f50b9Schristos /************************************************************************/
959a53f50b9Schristos /*** NFS PROTOCOL (UDP, TCP) AND VERSION ***/
960a53f50b9Schristos /************************************************************************/
961a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_SOTYPE
962a53f50b9Schristos /* bsdi3 uses this */
963a53f50b9Schristos if (nfs_proto) {
964a53f50b9Schristos if (STREQ(nfs_proto, "tcp"))
965a53f50b9Schristos nap->sotype = SOCK_STREAM;
966a53f50b9Schristos else if (STREQ(nfs_proto, "udp"))
967a53f50b9Schristos nap->sotype = SOCK_DGRAM;
968a53f50b9Schristos }
969a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_SOTYPE */
970a53f50b9Schristos
971a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_PROTO
972a53f50b9Schristos nap->proto = 0; /* bsdi3 sets this field to zero */
973a53f50b9Schristos # ifdef IPPROTO_TCP
974a53f50b9Schristos if (nfs_proto) {
975a53f50b9Schristos if (STREQ(nfs_proto, "tcp")) /* AIX 4.2.x needs this */
976a53f50b9Schristos nap->proto = IPPROTO_TCP;
977a53f50b9Schristos else if (STREQ(nfs_proto, "udp"))
978a53f50b9Schristos nap->proto = IPPROTO_UDP;
979a53f50b9Schristos }
980a53f50b9Schristos # endif /* IPPROTO_TCP */
981a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_SOTYPE */
982a53f50b9Schristos
983a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_VERSION
984a53f50b9Schristos # ifdef NFS_ARGSVERSION
985a53f50b9Schristos nap->version = NFS_ARGSVERSION; /* BSDI 3.0 and OpenBSD 2.2 */
986a53f50b9Schristos # endif /* NFS_ARGSVERSION */
987a53f50b9Schristos # ifdef DG_MOUNT_NFS_VERSION
988a53f50b9Schristos nap->version = DG_MOUNT_NFS_VERSION; /* dg-ux */
989a53f50b9Schristos # endif /* DG_MOUNT_NFS_VERSION */
990a53f50b9Schristos #endif /* HAVE_NFS_ARGS_VERSION */
991a53f50b9Schristos
992a53f50b9Schristos /************************************************************************/
993a53f50b9Schristos /*** OTHER NFS SOCKET RELATED OPTIONS AND FLAGS ***/
994a53f50b9Schristos /************************************************************************/
995a53f50b9Schristos
996a53f50b9Schristos /************************************************************************/
997a53f50b9Schristos /*** OTHER FLAGS AND OPTIONS ***/
998a53f50b9Schristos /************************************************************************/
999a53f50b9Schristos
1000a53f50b9Schristos #ifdef MNT2_NFS_OPT_BIODS
1001a53f50b9Schristos if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS)))
1002a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_BIODS;
1003a53f50b9Schristos #endif /* MNT2_NFS_OPT_BIODS */
1004a53f50b9Schristos
1005a53f50b9Schristos #ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */
1006a53f50b9Schristos if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL)))
1007*4da6d876Schristos nap->args.flags |= MNT2_NFS_OPT_SYMTTL;
1008a53f50b9Schristos #endif /* MNTTAB_OPT_SYMTTL */
1009a53f50b9Schristos
1010a53f50b9Schristos #ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */
1011a53f50b9Schristos if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH)))
1012*4da6d876Schristos nap->args.flags |= MNT2_NFS_OPT_PGTHRESH;
1013a53f50b9Schristos #endif /* MNT2_NFS_OPT_PGTHRESH */
1014a53f50b9Schristos
1015a53f50b9Schristos #if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
1016a53f50b9Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) {
1017a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_POSIX;
1018a53f50b9Schristos # ifdef HAVE_NFS_ARGS_T_PATHCONF
1019a53f50b9Schristos nap->pathconf = NULL;
1020a53f50b9Schristos # endif /* HAVE_NFS_ARGS_T_PATHCONF */
1021a53f50b9Schristos }
1022a53f50b9Schristos #endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
1023a53f50b9Schristos
1024*4da6d876Schristos #ifdef HAVE_TRANSPORT_TYPE_TLI
1025*4da6d876Schristos /* set up syncaddr field */
1026*4da6d876Schristos nap->syncaddr = (struct netbuf *) NULL;
1027*4da6d876Schristos
1028*4da6d876Schristos /* set up knconf field */
1029*4da6d876Schristos if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) {
1030*4da6d876Schristos plog(XLOG_FATAL, "cannot fill knetconfig structure for nfs_args");
1031*4da6d876Schristos going_down(1);
1032*4da6d876Schristos return;
1033*4da6d876Schristos }
1034*4da6d876Schristos /* update the flags field for knconf */
1035*4da6d876Schristos nap->args.flags |= MNT2_NFS_OPT_KNCONF;
1036*4da6d876Schristos #endif /* HAVE_TRANSPORT_TYPE_TLI */
1037*4da6d876Schristos
1038*4da6d876Schristos #ifdef MNT2_NFS_OPT_FSNAME
1039*4da6d876Schristos nap->fsname = fs_name;
1040*4da6d876Schristos nap->args.flags |= MNT2_NFS_OPT_FSNAME;
1041*4da6d876Schristos #endif /* MNT2_NFS_OPT_FSNAME */
1042*4da6d876Schristos
1043*4da6d876Schristos
1044*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_OPTSTR
1045*4da6d876Schristos nap->optstr = mntp->mnt_opts;
1046*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_OPTSTR */
1047a53f50b9Schristos
1048a53f50b9Schristos #if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
1049a53f50b9Schristos nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
1050a53f50b9Schristos if (nap->maxgrouplist != 0)
1051a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_MAXGRPS;
1052a53f50b9Schristos #endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
1053a53f50b9Schristos
1054*4da6d876Schristos /************************************************************************/
1055*4da6d876Schristos /*** FINAL ACTIONS ***/
1056*4da6d876Schristos /************************************************************************/
1057a53f50b9Schristos
1058*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_GFS_FLAGS
1059*4da6d876Schristos /* Ultrix stores generic flags in nfs_args.gfs_flags. */
1060*4da6d876Schristos nap->gfs_flags = genflags;
1061*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_FLAGS */
1062*4da6d876Schristos
1063*4da6d876Schristos return; /* end of compute_nfs_args() function */
1064*4da6d876Schristos }
1065*4da6d876Schristos
1066*4da6d876Schristos #ifdef HAVE_FS_NFS4
1067*4da6d876Schristos
1068*4da6d876Schristos #define RPC_AUTH_GSS_KRB5 390003
1069*4da6d876Schristos #define RPC_AUTH_GSS_KRB5I 390004
1070*4da6d876Schristos #define RPC_AUTH_GSS_KRB5P 390005
1071*4da6d876Schristos #define RPC_AUTH_GSS_LKEY 390006
1072*4da6d876Schristos #define RPC_AUTH_GSS_LKEYI 390007
1073*4da6d876Schristos #define RPC_AUTH_GSS_LKEYP 390008
1074*4da6d876Schristos #define RPC_AUTH_GSS_SPKM 390009
1075*4da6d876Schristos #define RPC_AUTH_GSS_SPKMI 390010
1076*4da6d876Schristos #define RPC_AUTH_GSS_SPKMP 390011
1077*4da6d876Schristos
1078*4da6d876Schristos struct {
1079*4da6d876Schristos const char *name;
1080*4da6d876Schristos int num;
1081*4da6d876Schristos } flavours[] = {
1082*4da6d876Schristos { "unix", AUTH_UNIX },
1083*4da6d876Schristos { "krb5", RPC_AUTH_GSS_KRB5 },
1084*4da6d876Schristos { "krb5i", RPC_AUTH_GSS_KRB5I },
1085*4da6d876Schristos { "krb5p", RPC_AUTH_GSS_KRB5P },
1086*4da6d876Schristos { "lkey", RPC_AUTH_GSS_LKEY },
1087*4da6d876Schristos { "lkeyi", RPC_AUTH_GSS_LKEYI },
1088*4da6d876Schristos { "lkeyp", RPC_AUTH_GSS_LKEYP },
1089*4da6d876Schristos { "spkm", RPC_AUTH_GSS_SPKM },
1090*4da6d876Schristos { "spkmi", RPC_AUTH_GSS_SPKMI },
1091*4da6d876Schristos { "spkmp", RPC_AUTH_GSS_SPKMP },
1092*4da6d876Schristos };
1093*4da6d876Schristos
1094*4da6d876Schristos static char *
set_nfs4_security(nfs4_args_t * nap,mntent_t * mntp)1095*4da6d876Schristos set_nfs4_security(nfs4_args_t *nap, mntent_t *mntp)
1096*4da6d876Schristos {
1097*4da6d876Schristos const char *o = hasmnteq(mntp, MNTTAB_OPT_SEC);
1098*4da6d876Schristos char *q, *s, *ss;
1099*4da6d876Schristos size_t l, i;
1100*4da6d876Schristos
1101*4da6d876Schristos if (o == NULL)
1102*4da6d876Schristos o = "unix";
1103*4da6d876Schristos
1104*4da6d876Schristos for (l = 1, q = strchr(o, ','); q; q = strchr(q + 1, ','))
1105*4da6d876Schristos l++;
1106*4da6d876Schristos
1107*4da6d876Schristos nap->auth_flavours = xmalloc(l * sizeof(*nap->auth_flavours));
1108*4da6d876Schristos
1109*4da6d876Schristos s = ss = xstrdup(o);
1110*4da6d876Schristos for (;;) {
1111*4da6d876Schristos q = strchr(s, ',');
1112*4da6d876Schristos if (q)
1113*4da6d876Schristos *q = '\0';
1114*4da6d876Schristos
1115*4da6d876Schristos for (l = 0, i = 0; i < sizeof(flavours) / sizeof(flavours[0]); i++)
1116*4da6d876Schristos if (strcmp(flavours[i].name, s) == 0) {
1117*4da6d876Schristos nap->auth_flavours[l++] = flavours[i].num;
1118*4da6d876Schristos break;
1119*4da6d876Schristos }
1120*4da6d876Schristos
1121*4da6d876Schristos if (i == sizeof(flavours) / sizeof(flavours[0]))
1122*4da6d876Schristos plog(XLOG_ERROR, "Unknown NFSv4 security mechanism %s\n", s);
1123*4da6d876Schristos
1124*4da6d876Schristos if (q == NULL)
1125*4da6d876Schristos break;
1126*4da6d876Schristos
1127*4da6d876Schristos *q = ':';
1128*4da6d876Schristos s = ++q;
1129*4da6d876Schristos }
1130*4da6d876Schristos
1131*4da6d876Schristos nap->auth_flavourlen = l;
1132*4da6d876Schristos return ss;
1133*4da6d876Schristos }
1134*4da6d876Schristos
1135*4da6d876Schristos static int
get_my_ipv4addr(struct nfs_string * ns)1136*4da6d876Schristos get_my_ipv4addr(struct nfs_string *ns)
1137*4da6d876Schristos {
1138*4da6d876Schristos struct hostent *hp;
1139*4da6d876Schristos char myname[MAXHOSTNAMELEN];
1140*4da6d876Schristos
1141*4da6d876Schristos if (gethostname(myname, sizeof(myname)) == -1)
1142*4da6d876Schristos return -1;
1143*4da6d876Schristos if ((hp = gethostbyname(myname)) == NULL)
1144*4da6d876Schristos return -1;
1145*4da6d876Schristos if (inet_ntop(AF_INET, hp->h_addr, myname, sizeof(myname)) == NULL)
1146*4da6d876Schristos return -1;
1147*4da6d876Schristos ns->len = strlen(myname);
1148*4da6d876Schristos ns->data = xmalloc(ns->len + 1);
1149*4da6d876Schristos memcpy(ns->data, myname, ns->len + 1);
1150*4da6d876Schristos return 0;
1151*4da6d876Schristos }
1152*4da6d876Schristos
1153*4da6d876Schristos static void
add_nfs4_mntopts(const nfs4_args_t * nap,mntent_t * mntp,char * sec)1154*4da6d876Schristos add_nfs4_mntopts(const nfs4_args_t *nap, mntent_t *mntp, char *sec)
1155*4da6d876Schristos {
1156*4da6d876Schristos char *opts = mntp->mnt_opts;
1157*4da6d876Schristos char buf[1024], addr[128];
1158*4da6d876Schristos size_t len = strlen(mntp->mnt_opts);
1159*4da6d876Schristos
1160*4da6d876Schristos if (inet_ntop(AF_INET,
1161*4da6d876Schristos &((const struct sockaddr_in *)nap->host_addr)->sin_addr,
1162*4da6d876Schristos addr, sizeof(addr)) == NULL)
1163*4da6d876Schristos return;
1164*4da6d876Schristos
1165*4da6d876Schristos xsnprintf(buf, sizeof(buf), ",clientaddr=%s,addr=%s", nap->client_addr.data,
1166*4da6d876Schristos addr);
1167*4da6d876Schristos
1168*4da6d876Schristos len += strlen(buf) + 1;
1169*4da6d876Schristos
1170*4da6d876Schristos if (sec && strcmp(sec, "unix") != 0) {
1171*4da6d876Schristos len += strlen(sec) + strlen(MNTTAB_OPT_SEC) + 2; /* 2 = ",=" */
1172*4da6d876Schristos } else
1173*4da6d876Schristos sec = NULL;
1174*4da6d876Schristos
1175*4da6d876Schristos opts = xrealloc(mntp->mnt_opts, len);
1176*4da6d876Schristos xstrlcat(opts, buf, len);
1177*4da6d876Schristos
1178*4da6d876Schristos if (sec) {
1179*4da6d876Schristos xstrlcat(opts, ",", len);
1180*4da6d876Schristos xstrlcat(opts, MNTTAB_OPT_SEC, len);
1181*4da6d876Schristos xstrlcat(opts, "=", len);
1182*4da6d876Schristos xstrlcat(opts, sec, len);
1183*4da6d876Schristos }
1184*4da6d876Schristos
1185*4da6d876Schristos mntp->mnt_opts = opts;
1186*4da6d876Schristos }
1187*4da6d876Schristos
1188*4da6d876Schristos static void
print_nfs4_security(const nfs4_args_t * nap)1189*4da6d876Schristos print_nfs4_security(const nfs4_args_t *nap)
1190*4da6d876Schristos {
1191*4da6d876Schristos char buf[1024];
1192*4da6d876Schristos char num[64];
1193*4da6d876Schristos size_t i, j;
1194*4da6d876Schristos
1195*4da6d876Schristos buf[0] = '\0';
1196*4da6d876Schristos
1197*4da6d876Schristos for (i = 0; i < nap->auth_flavourlen; i++) {
1198*4da6d876Schristos
1199*4da6d876Schristos for (j = 0; j < sizeof(flavours) / sizeof(flavours[0]); j++)
1200*4da6d876Schristos if (flavours[j].num == nap->auth_flavours[i]) {
1201*4da6d876Schristos xstrlcpy(num, flavours[j].name, sizeof(num));
1202*4da6d876Schristos break;
1203*4da6d876Schristos }
1204*4da6d876Schristos
1205*4da6d876Schristos if (j == sizeof(flavours) / sizeof(flavours[0])) {
1206*4da6d876Schristos plog(XLOG_ERROR, "Unknown NFSv4 security mechanism %d\n",
1207*4da6d876Schristos nap->auth_flavours[i]);
1208*4da6d876Schristos xsnprintf(num, sizeof(num), "*%d*", nap->auth_flavours[i]);
1209*4da6d876Schristos }
1210*4da6d876Schristos
1211*4da6d876Schristos if (buf[0])
1212*4da6d876Schristos xstrlcat(buf, ":", sizeof(buf));
1213*4da6d876Schristos
1214*4da6d876Schristos xstrlcat(buf, num, sizeof(buf));
1215*4da6d876Schristos }
1216*4da6d876Schristos
1217*4da6d876Schristos plog(XLOG_DEBUG, "NA->auth_flavours \"%s\"\n", buf);
1218*4da6d876Schristos }
1219*4da6d876Schristos
1220*4da6d876Schristos static void
discard_nfs4_args(nfs4_args_t * nap)1221*4da6d876Schristos discard_nfs4_args(nfs4_args_t *nap)
1222*4da6d876Schristos {
1223*4da6d876Schristos if (nap->client_addr.data)
1224*4da6d876Schristos free(nap->client_addr.data);
1225*4da6d876Schristos if (nap->hostname.data)
1226*4da6d876Schristos free(nap->hostname.data);
1227*4da6d876Schristos if (nap->mnt_path.data)
1228*4da6d876Schristos free(nap->mnt_path.data);
1229*4da6d876Schristos if (nap->host_addr)
1230*4da6d876Schristos free(nap->host_addr);
1231*4da6d876Schristos if (nap->auth_flavours)
1232*4da6d876Schristos free(nap->auth_flavours);
1233*4da6d876Schristos }
1234*4da6d876Schristos
1235*4da6d876Schristos /*
1236*4da6d876Schristos * Fill in the many possible fields and flags of struct nfs4_args.
1237*4da6d876Schristos *
1238*4da6d876Schristos * nap: pre-allocated structure to fill in.
1239*4da6d876Schristos * mntp: mount entry structure (includes options)
1240*4da6d876Schristos * genflags: generic mount flags already determined
1241*4da6d876Schristos * nfsncp: (TLI only) netconfig entry for this NFS mount
1242*4da6d876Schristos * ip_addr: IP address of file server
1243*4da6d876Schristos * nfs_version: 4, or 0 if unknown
1244*4da6d876Schristos * nfs_proto: "udp", "tcp", or NULL.
1245*4da6d876Schristos * fhp: file handle structure pointer
1246*4da6d876Schristos * host_name: name of remote NFS host
1247*4da6d876Schristos * fs_name: remote file system name to mount
1248*4da6d876Schristos */
1249*4da6d876Schristos static void
compute_nfs4_args(nfs4_args_t * nap,mntent_t * mntp,int genflags,struct netconfig * nfsncp,struct sockaddr_in * ip_addr,u_long nfs_version,char * nfs_proto,am_nfs_handle_t * fhp,char * host_name,char * fs_name)1250*4da6d876Schristos compute_nfs4_args(nfs4_args_t *nap,
1251*4da6d876Schristos mntent_t *mntp,
1252*4da6d876Schristos int genflags,
1253*4da6d876Schristos struct netconfig *nfsncp,
1254*4da6d876Schristos struct sockaddr_in *ip_addr,
1255*4da6d876Schristos u_long nfs_version,
1256*4da6d876Schristos char *nfs_proto,
1257*4da6d876Schristos am_nfs_handle_t *fhp,
1258*4da6d876Schristos char *host_name,
1259*4da6d876Schristos char *fs_name)
1260*4da6d876Schristos {
1261*4da6d876Schristos char *s;
1262*4da6d876Schristos struct nfs_common_args a;
1263*4da6d876Schristos uint16_t nfs_port;
1264*4da6d876Schristos
1265*4da6d876Schristos /* initialize just in case */
1266*4da6d876Schristos memset((voidp) nap, 0, sizeof(nfs4_args_t));
1267*4da6d876Schristos
1268*4da6d876Schristos /* compute all of the NFS attribute-cache flags */
1269*4da6d876Schristos memset(&a, 0, sizeof(a));
1270*4da6d876Schristos compute_nfs_attrcache_flags(&a, mntp);
1271*4da6d876Schristos compute_nfs_common_args(&a, mntp, nfs_proto, nfs_version);
1272*4da6d876Schristos get_nfs_common_args(nap, a);
1273*4da6d876Schristos
1274*4da6d876Schristos get_my_ipv4addr(&nap->client_addr);
1275*4da6d876Schristos
1276*4da6d876Schristos /************************************************************************/
1277*4da6d876Schristos /*** HOST NAME ***/
1278*4da6d876Schristos /************************************************************************/
1279*4da6d876Schristos nap->hostname.len = strlen(host_name);
1280*4da6d876Schristos nap->hostname.data = xmalloc(nap->hostname.len + 1);
1281*4da6d876Schristos memcpy(nap->hostname.data, host_name, nap->hostname.len + 1);
1282*4da6d876Schristos
1283*4da6d876Schristos if ((s = strchr(fs_name, ':')) != NULL)
1284*4da6d876Schristos s++;
1285*4da6d876Schristos else
1286*4da6d876Schristos s = fs_name;
1287*4da6d876Schristos
1288*4da6d876Schristos nap->mnt_path.len = strlen(s);
1289*4da6d876Schristos nap->mnt_path.data = xmalloc(nap->mnt_path.len + 1);
1290*4da6d876Schristos memcpy(nap->mnt_path.data, s, nap->mnt_path.len + 1);
1291*4da6d876Schristos plog(XLOG_DEBUG, "dir name %s\n", nap->mnt_path.data);
1292*4da6d876Schristos
1293*4da6d876Schristos /************************************************************************/
1294*4da6d876Schristos /*** IP ADDRESS OF REMOTE HOST ***/
1295*4da6d876Schristos /************************************************************************/
1296*4da6d876Schristos nap->host_addrlen = sizeof(*ip_addr);
1297*4da6d876Schristos nap->host_addr = xmalloc(nap->host_addrlen);
1298*4da6d876Schristos memcpy(nap->host_addr, ip_addr, nap->host_addrlen);
1299*4da6d876Schristos
1300*4da6d876Schristos nfs_port = hasmntval(mntp, MNTTAB_OPT_PORT);
1301*4da6d876Schristos if (nfs_port == 0)
1302*4da6d876Schristos nfs_port = htons(NFS_PORT);
1303*4da6d876Schristos else
1304*4da6d876Schristos nfs_port = htons(nfs_port);
1305*4da6d876Schristos
1306*4da6d876Schristos ((struct sockaddr_in *)nap->host_addr)->sin_port = nfs_port;
1307*4da6d876Schristos
1308*4da6d876Schristos nap->proto = 0; /* bsdi3 sets this field to zero */
1309*4da6d876Schristos if (nfs_proto) {
1310*4da6d876Schristos if (STREQ(nfs_proto, "tcp")) /* AIX 4.2.x needs this */
1311*4da6d876Schristos nap->proto = IPPROTO_TCP;
1312*4da6d876Schristos else if (STREQ(nfs_proto, "udp"))
1313*4da6d876Schristos nap->proto = IPPROTO_UDP;
1314*4da6d876Schristos }
1315*4da6d876Schristos
1316*4da6d876Schristos nap->version = NFS4_MOUNT_VERSION; /* BSDI 3.0 and OpenBSD 2.2 */
1317*4da6d876Schristos
1318*4da6d876Schristos /************************************************************************/
1319*4da6d876Schristos /*** OTHER NFS SOCKET RELATED OPTIONS AND FLAGS ***/
1320*4da6d876Schristos /************************************************************************/
1321*4da6d876Schristos
1322*4da6d876Schristos
1323*4da6d876Schristos /************************************************************************/
1324*4da6d876Schristos /*** OTHER FLAGS AND OPTIONS ***/
1325*4da6d876Schristos /************************************************************************/
1326*4da6d876Schristos
1327*4da6d876Schristos #if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
1328*4da6d876Schristos if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) {
1329*4da6d876Schristos nap->args.flags |= MNT2_NFS_OPT_POSIX;
1330*4da6d876Schristos # ifdef HAVE_NFS_ARGS_T_PATHCONF
1331*4da6d876Schristos nap->pathconf = NULL;
1332*4da6d876Schristos # endif /* HAVE_NFS_ARGS_T_PATHCONF */
1333*4da6d876Schristos }
1334*4da6d876Schristos #endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
1335*4da6d876Schristos
1336*4da6d876Schristos #if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
1337*4da6d876Schristos nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
1338*4da6d876Schristos if (nap->maxgrouplist != 0)
1339*4da6d876Schristos nap->args.flags |= MNT2_NFS_OPT_MAXGRPS;
1340*4da6d876Schristos #endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
1341a53f50b9Schristos
1342a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_OPTSTR
1343a53f50b9Schristos nap->optstr = mntp->mnt_opts;
1344a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_OPTSTR */
1345a53f50b9Schristos
1346a53f50b9Schristos /************************************************************************/
1347a53f50b9Schristos /*** FINAL ACTIONS ***/
1348a53f50b9Schristos /************************************************************************/
1349a53f50b9Schristos
1350a53f50b9Schristos #ifdef HAVE_NFS_ARGS_T_GFS_FLAGS
1351a53f50b9Schristos /* Ultrix stores generic flags in nfs_args.gfs_flags. */
1352a53f50b9Schristos nap->gfs_flags = genflags;
1353a53f50b9Schristos #endif /* HAVE_NFS_ARGS_T_FLAGS */
1354a53f50b9Schristos
1355*4da6d876Schristos s = set_nfs4_security(nap, mntp);
1356*4da6d876Schristos
1357*4da6d876Schristos /* Add addresses to the mount options */
1358*4da6d876Schristos add_nfs4_mntopts(nap, mntp, s);
1359*4da6d876Schristos
1360*4da6d876Schristos return; /* end of compute_nfs4_args() function */
1361a53f50b9Schristos }
1362a53f50b9Schristos
1363*4da6d876Schristos #ifdef DEBUG
1364*4da6d876Schristos static void
print_nfs4_args(const nfs4_args_t * nap,u_long nfs_version)1365*4da6d876Schristos print_nfs4_args(const nfs4_args_t *nap, u_long nfs_version)
1366*4da6d876Schristos {
1367*4da6d876Schristos struct sockaddr_in *sap;
1368*4da6d876Schristos struct nfs_common_args a;
1369*4da6d876Schristos
1370*4da6d876Schristos if (!nap) {
1371*4da6d876Schristos plog(XLOG_DEBUG, "NULL nfs_args!");
1372*4da6d876Schristos return;
1373*4da6d876Schristos }
1374*4da6d876Schristos
1375*4da6d876Schristos plog(XLOG_DEBUG, "NA->client_addr \"%s\"\n", nap->client_addr.data);
1376*4da6d876Schristos plog(XLOG_DEBUG, "NA->mnt_path = \"%s\"", nap->mnt_path.data);
1377*4da6d876Schristos plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname.data);
1378*4da6d876Schristos sap = (struct sockaddr_in *) nap->host_addr;
1379*4da6d876Schristos print_nfs_sockaddr_in("host_addr", sap);
1380*4da6d876Schristos plog(XLOG_DEBUG, "NA->proto = %d", (int) nap->proto);
1381*4da6d876Schristos #ifdef HAVE_NFS_ARGS_T_VERSION
1382*4da6d876Schristos plog(XLOG_DEBUG, "NA->version = %d", nap->version);
1383*4da6d876Schristos #endif /* HAVE_NFS_ARGS_T_VERSION */
1384*4da6d876Schristos print_nfs4_security(nap);
1385*4da6d876Schristos
1386*4da6d876Schristos put_nfs_common_args(nap, a);
1387*4da6d876Schristos print_nfs_common_args(&a);
1388*4da6d876Schristos }
1389*4da6d876Schristos #endif
1390*4da6d876Schristos #endif /* HAVE_FS_NFS4 */
1391*4da6d876Schristos
1392*4da6d876Schristos void
compute_nfs_args(void * nap,mntent_t * mntp,int genflags,struct netconfig * nfsncp,struct sockaddr_in * ip_addr,u_long nfs_version,char * nfs_proto,am_nfs_handle_t * fhp,char * host_name,char * fs_name)1393*4da6d876Schristos compute_nfs_args(void *nap,
1394*4da6d876Schristos mntent_t *mntp,
1395*4da6d876Schristos int genflags,
1396*4da6d876Schristos struct netconfig *nfsncp,
1397*4da6d876Schristos struct sockaddr_in *ip_addr,
1398*4da6d876Schristos u_long nfs_version,
1399*4da6d876Schristos char *nfs_proto,
1400*4da6d876Schristos am_nfs_handle_t *fhp,
1401*4da6d876Schristos char *host_name,
1402*4da6d876Schristos char *fs_name)
1403*4da6d876Schristos {
1404*4da6d876Schristos #ifdef HAVE_FS_NFS4
1405*4da6d876Schristos if (nfs_version == NFS_VERSION4)
1406*4da6d876Schristos compute_nfs4_args(nap, mntp, genflags, nfsncp, ip_addr, nfs_version,
1407*4da6d876Schristos nfs_proto, fhp, host_name, fs_name);
1408*4da6d876Schristos else
1409*4da6d876Schristos #endif /* HAVE_FS_NFS4 */
1410*4da6d876Schristos compute_nfs23_args(nap, mntp, genflags, nfsncp, ip_addr, nfs_version,
1411*4da6d876Schristos nfs_proto, fhp, host_name, fs_name);
1412*4da6d876Schristos }
1413*4da6d876Schristos
1414*4da6d876Schristos void
discard_nfs_args(void * nap,u_long nfs_version)1415*4da6d876Schristos discard_nfs_args(void *nap, u_long nfs_version)
1416*4da6d876Schristos {
1417*4da6d876Schristos #ifdef HAVE_FS_NFS4
1418*4da6d876Schristos if (nfs_version == NFS_VERSION4)
1419*4da6d876Schristos discard_nfs4_args(nap);
1420*4da6d876Schristos else
1421*4da6d876Schristos #endif /* HAVE_FS_NFS4 */
1422*4da6d876Schristos discard_nfs23_args(nap);
1423*4da6d876Schristos }
1424*4da6d876Schristos
1425*4da6d876Schristos #ifdef DEBUG
1426*4da6d876Schristos void
print_nfs_args(const void * nap,u_long nfs_version)1427*4da6d876Schristos print_nfs_args(const void *nap, u_long nfs_version)
1428*4da6d876Schristos {
1429*4da6d876Schristos #ifdef HAVE_FS_NFS4
1430*4da6d876Schristos if (nfs_version == NFS_VERSION4)
1431*4da6d876Schristos print_nfs4_args(nap, nfs_version);
1432*4da6d876Schristos else
1433*4da6d876Schristos #endif /* HAVE_FS_NFS4 */
1434*4da6d876Schristos print_nfs23_args(nap, nfs_version);
1435*4da6d876Schristos }
1436*4da6d876Schristos #endif
1437*4da6d876Schristos
1438a53f50b9Schristos
1439a53f50b9Schristos /*
1440a53f50b9Schristos * Fill in special values for flags and fields of nfs_args, for an
1441a53f50b9Schristos * automounter NFS mount.
1442a53f50b9Schristos */
1443a53f50b9Schristos void
compute_automounter_nfs_args(nfs_args_t * nap,mntent_t * mntp)1444a53f50b9Schristos compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp)
1445a53f50b9Schristos {
1446*4da6d876Schristos struct nfs_common_args a;
1447*4da6d876Schristos
1448a53f50b9Schristos #ifdef MNT2_NFS_OPT_SYMTTL
1449a53f50b9Schristos /*
1450a53f50b9Schristos * Don't let the kernel cache symbolic links we generate, or else lookups
1451a53f50b9Schristos * will bypass amd and fail to remount stuff as needed.
1452a53f50b9Schristos */
1453a53f50b9Schristos plog(XLOG_INFO, "turning on NFS option symttl and setting value to 0");
1454a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_SYMTTL;
1455a53f50b9Schristos nap->symttl = 0;
1456a53f50b9Schristos #endif /* MNT2_NFS_OPT_SYMTTL */
1457a53f50b9Schristos
1458a53f50b9Schristos /*
1459a53f50b9Schristos * This completes the flags for the HIDE_MOUNT_TYPE code in the
1460a53f50b9Schristos * mount_amfs_toplvl() function in amd/amfs_toplvl.c.
1461a53f50b9Schristos * Some systems don't have a mount type, but a mount flag.
1462a53f50b9Schristos */
1463a53f50b9Schristos #ifdef MNT2_NFS_OPT_AUTO
1464a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_AUTO;
1465a53f50b9Schristos #endif /* MNT2_NFS_OPT_AUTO */
1466a53f50b9Schristos #ifdef MNT2_NFS_OPT_IGNORE
1467a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_IGNORE;
1468a53f50b9Schristos #endif /* MNT2_NFS_OPT_IGNORE */
1469a53f50b9Schristos #ifdef MNT2_GEN_OPT_AUTOMNTFS
1470a53f50b9Schristos nap->flags |= MNT2_GEN_OPT_AUTOMNTFS;
1471a53f50b9Schristos #endif /* not MNT2_GEN_OPT_AUTOMNTFS */
1472a53f50b9Schristos
1473a53f50b9Schristos #ifdef MNT2_NFS_OPT_DUMBTIMR
1474a53f50b9Schristos /*
1475a53f50b9Schristos * Don't let the kernel start computing throughput of Amd. The numbers
1476a53f50b9Schristos * will be meaningless because of the way Amd does mount retries.
1477a53f50b9Schristos */
1478a53f50b9Schristos plog(XLOG_INFO, "%s: disabling nfs congestion window", mntp->mnt_dir);
1479a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_DUMBTIMR;
1480a53f50b9Schristos #endif /* MNT2_NFS_OPT_DUMBTIMR */
1481a53f50b9Schristos
1482a53f50b9Schristos /* compute all of the NFS attribute-cache flags */
1483*4da6d876Schristos memset(&a, 0, sizeof(a));
1484*4da6d876Schristos a.flags = nap->flags;
1485*4da6d876Schristos compute_nfs_attrcache_flags(&a, mntp);
1486*4da6d876Schristos get_nfs_common_args(nap, a);
1487a53f50b9Schristos
1488a53f50b9Schristos /*
1489a53f50b9Schristos * Provide a slight bit more security by requiring the kernel to use
1490a53f50b9Schristos * reserved ports.
1491a53f50b9Schristos */
1492a53f50b9Schristos #ifdef MNT2_NFS_OPT_RESVPORT
1493a53f50b9Schristos nap->flags |= MNT2_NFS_OPT_RESVPORT;
1494a53f50b9Schristos #endif /* MNT2_NFS_OPT_RESVPORT */
1495a53f50b9Schristos }
1496a53f50b9Schristos
1497*4da6d876Schristos int
nfs_valid_version(u_long v)1498*4da6d876Schristos nfs_valid_version(u_long v)
1499a53f50b9Schristos {
1500*4da6d876Schristos return v >= NFS_VERS_MIN && v <= NFS_VERS_MAX;
1501a53f50b9Schristos }
1502