1/* 2 * Copyright (c) 1997-2006 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgment: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * 40 * File: am-utils/libamu/mount_fs.c 41 * 42 */ 43 44#ifdef HAVE_CONFIG_H 45# include <config.h> 46#endif /* HAVE_CONFIG_H */ 47#include <am_defs.h> 48#include <amu.h> 49 50 51/* ensure that mount table options are delimited by a comma */ 52#define append_opts(old, l, new) { \ 53 if (*(old) != '\0') \ 54 xstrlcat(old, ",", l); \ 55 xstrlcat(old, new, l); } 56 57/* 58 * Standard mount flags 59 */ 60struct opt_tab mnt_flags[] = 61{ 62#if defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO) 63 {MNTTAB_OPT_RO, MNT2_GEN_OPT_RDONLY}, 64#endif /* defined(MNT2_GEN_OPT_RDONLY) && defined(MNTTAB_OPT_RO) */ 65 66#if defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE) 67 {MNTTAB_OPT_NOCACHE, MNT2_GEN_OPT_NOCACHE}, 68#endif /* defined(MNT2_GEN_OPT_NOCACHE) && defined(MNTTAB_OPT_NOCACHE) */ 69 70 /* the "grpid" mount option can be offered as generic of NFS */ 71#ifdef MNTTAB_OPT_GRPID 72# ifdef MNT2_GEN_OPT_GRPID 73 {MNTTAB_OPT_GRPID, MNT2_GEN_OPT_GRPID}, 74# endif /* MNT2_GEN_OPT_GRPID */ 75# ifdef MNT2_NFS_OPT_GRPID 76 {MNTTAB_OPT_GRPID, MNT2_NFS_OPT_GRPID}, 77# endif /* MNT2_NFS_OPT_GRPID */ 78#endif /* MNTTAB_OPT_GRPID */ 79 80#if defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI) 81 {MNTTAB_OPT_MULTI, MNT2_GEN_OPT_MULTI}, 82#endif /* defined(MNT2_GEN_OPT_MULTI) && defined(MNTTAB_OPT_MULTI) */ 83 84#if defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV) 85 {MNTTAB_OPT_NODEV, MNT2_GEN_OPT_NODEV}, 86#endif /* defined(MNT2_GEN_OPT_NODEV) && defined(MNTTAB_OPT_NODEV) */ 87 88#if defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC) 89 {MNTTAB_OPT_NOEXEC, MNT2_GEN_OPT_NOEXEC}, 90#endif /* defined(MNT2_GEN_OPT_NOEXEC) && defined(MNTTAB_OPT_NOEXEC) */ 91 92#if defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB) 93 {MNTTAB_OPT_NOSUB, MNT2_GEN_OPT_NOSUB}, 94#endif /* defined(MNT2_GEN_OPT_NOSUB) && defined(MNTTAB_OPT_NOSUB) */ 95 96#if defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID) 97 {MNTTAB_OPT_NOSUID, MNT2_GEN_OPT_NOSUID}, 98#endif /* defined(MNT2_GEN_OPT_NOSUID) && defined(MNTTAB_OPT_NOSUID) */ 99 100#if defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC) 101 {MNTTAB_OPT_SYNC, MNT2_GEN_OPT_SYNC}, 102#endif /* defined(MNT2_GEN_OPT_SYNC) && defined(MNTTAB_OPT_SYNC) */ 103 104#if defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY) 105 {MNTTAB_OPT_OVERLAY, MNT2_GEN_OPT_OVERLAY}, 106#endif /* defined(MNT2_GEN_OPT_OVERLAY) && defined(MNTTAB_OPT_OVERLAY) */ 107 108 /* 109 * Do not define MNT2_NFS_OPT_* entries here! This is for generic 110 * mount(2) options only, not for NFS mount options. If you need to put 111 * something here, it's probably not the right place: see 112 * include/am_compat.h. 113 */ 114 115 {0, 0} 116}; 117 118 119/* compute generic mount flags */ 120int 121compute_mount_flags(mntent_t *mntp) 122{ 123 struct opt_tab *opt; 124 int flags = 0; 125 126#ifdef MNT2_GEN_OPT_NEWTYPE 127 flags |= MNT2_GEN_OPT_NEWTYPE; 128#endif /* MNT2_GEN_OPT_NEWTYPE */ 129#ifdef MNT2_GEN_OPT_AUTOMOUNTED 130 flags |= MNT2_GEN_OPT_AUTOMOUNTED; 131#endif /* not MNT2_GEN_OPT_AUTOMOUNTED */ 132 133 /* 134 * Crack basic mount options 135 */ 136 for (opt = mnt_flags; opt->opt; opt++) { 137 flags |= amu_hasmntopt(mntp, opt->opt) ? opt->flag : 0; 138 } 139 140 return flags; 141} 142 143 144/* compute generic mount flags for automounter mounts */ 145int 146compute_automounter_mount_flags(mntent_t *mntp) 147{ 148 int flags = 0; 149 150#ifdef MNT2_GEN_OPT_IGNORE 151 flags |= MNT2_GEN_OPT_IGNORE; 152#endif /* not MNT2_GEN_OPT_IGNORE */ 153#ifdef MNT2_GEN_OPT_AUTOMNTFS 154 flags |= MNT2_GEN_OPT_AUTOMNTFS; 155#endif /* not MNT2_GEN_OPT_AUTOMNTFS */ 156 157 return flags; 158} 159 160 161int 162mount_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) 163{ 164 int error = 0; 165#ifdef MOUNT_TABLE_ON_FILE 166 char *zopts = NULL, *xopts = NULL; 167 size_t l; 168#endif /* MOUNT_TABLE_ON_FILE */ 169 char *mnt_dir = 0; 170 171#ifdef NEED_AUTOFS_SPACE_HACK 172 char *old_mnt_dir = 0; 173 /* perform space hack */ 174 if (on_autofs) { 175 old_mnt_dir = mnt->mnt_dir; 176 mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir); 177 } else 178#endif /* NEED_AUTOFS_SPACE_HACK */ 179 mnt_dir = strdup(mnt->mnt_dir); 180 181 dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)", 182 mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); 183 184again: 185 error = MOUNT_TRAP(type, mnt, flags, mnt_data); 186 187 if (error < 0) { 188 plog(XLOG_ERROR, "'%s': mount: %m", mnt_dir); 189 /* 190 * The following code handles conditions which shouldn't 191 * occur. They are possible either because amd screws up 192 * in preparing for the mount, or because some human 193 * messed with the mount point. Both have been known to 194 * happen. -- stolcke 2/22/95 195 */ 196 if (errno == EBUSY) { 197 /* 198 * Also, sometimes unmount isn't called, e.g., because 199 * our mountlist is garbled. This leaves old mount 200 * points around which need to be removed before we 201 * can mount something new in their place. 202 */ 203 errno = umount_fs(mnt_dir, mnttabname, on_autofs); 204 if (errno != 0) 205 plog(XLOG_ERROR, "'%s': umount: %m", mnt_dir); 206 else { 207 plog(XLOG_WARNING, "extra umount required for '%s'", mnt_dir); 208 error = MOUNT_TRAP(type, mnt, flags, mnt_data); 209 } 210 } 211 } 212 213 if (error < 0 && --retry > 0) { 214 sleep(1); 215 goto again; 216 } 217 218#ifdef NEED_AUTOFS_SPACE_HACK 219 /* Undo space hack */ 220 if (on_autofs) 221 mnt->mnt_dir = old_mnt_dir; 222#endif /* NEED_AUTOFS_SPACE_HACK */ 223 224 if (error < 0) { 225 error = errno; 226 goto out; 227 } 228 229#ifdef MOUNT_TABLE_ON_FILE 230 /* 231 * Allocate memory for options: 232 * dev=..., vers={2,3}, proto={tcp,udp} 233 */ 234 l = strlen(mnt->mnt_opts) + 48; 235 zopts = (char *) xmalloc(l); 236 237 /* copy standard options */ 238 xopts = mnt->mnt_opts; 239 240 xstrlcpy(zopts, xopts, l); 241 242# ifdef MNTTAB_OPT_DEV 243 { 244 /* add the extra dev= field to the mount table */ 245 struct stat stb; 246 if (lstat(mnt_dir, &stb) == 0) { 247 char optsbuf[48]; 248 if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */ 249 xsnprintf(optsbuf, sizeof(optsbuf), "%s=%04lx", 250 MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff); 251 else /* e.g. System Vr4 */ 252 xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx", 253 MNTTAB_OPT_DEV, (u_long) stb.st_dev); 254 append_opts(zopts, l, optsbuf); 255 } 256 } 257# endif /* MNTTAB_OPT_DEV */ 258 259# if defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) 260 /* 261 * add the extra vers={2,3} field to the mount table, 262 * unless already specified by user 263 */ 264 if (nfs_version == NFS_VERSION3 && 265 hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) { 266 char optsbuf[48]; 267 xsnprintf(optsbuf, sizeof(optsbuf), 268 "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3); 269 append_opts(zopts, l, optsbuf); 270 } 271# endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */ 272 273# ifdef MNTTAB_OPT_PROTO 274 /* 275 * add the extra proto={tcp,udp} field to the mount table, 276 * unless already specified by user. 277 */ 278 if (nfs_proto && !amu_hasmntopt(mnt, MNTTAB_OPT_PROTO)) { 279 char optsbuf[48]; 280 xsnprintf(optsbuf, sizeof(optsbuf), "%s=%s", MNTTAB_OPT_PROTO, nfs_proto); 281 append_opts(zopts, l, optsbuf); 282 } 283# endif /* MNTTAB_OPT_PROTO */ 284 285 /* finally, store the options into the mount table structure */ 286 mnt->mnt_opts = zopts; 287 288 /* 289 * Additional fields in mntent_t 290 * are fixed up here 291 */ 292# ifdef HAVE_MNTENT_T_MNT_CNODE 293 mnt->mnt_cnode = 0; 294# endif /* HAVE_MNTENT_T_MNT_CNODE */ 295 296# ifdef HAVE_MNTENT_T_MNT_RO 297 mnt->mnt_ro = (amu_hasmntopt(mnt, MNTTAB_OPT_RO) != NULL); 298# endif /* HAVE_MNTENT_T_MNT_RO */ 299 300# ifdef HAVE_MNTENT_T_MNT_TIME 301# ifdef HAVE_MNTENT_T_MNT_TIME_STRING 302 { /* allocate enough space for a long */ 303 size_t l = 13 * sizeof(char); 304 char *str = (char *) xmalloc(l); 305 xsnprintf(str, l, "%ld", time((time_t *) NULL)); 306 mnt->mnt_time = str; 307 } 308# else /* not HAVE_MNTENT_T_MNT_TIME_STRING */ 309 mnt->mnt_time = time((time_t *) NULL); 310# endif /* not HAVE_MNTENT_T_MNT_TIME_STRING */ 311# endif /* HAVE_MNTENT_T_MNT_TIME */ 312 313 write_mntent(mnt, mnttabname); 314 315# ifdef MNTTAB_OPT_DEV 316 if (xopts) { 317 XFREE(mnt->mnt_opts); 318 mnt->mnt_opts = xopts; 319 } 320# endif /* MNTTAB_OPT_DEV */ 321#endif /* MOUNT_TABLE_ON_FILE */ 322 323 out: 324 XFREE(mnt_dir); 325 return error; 326} 327 328 329/* 330 * Compute all NFS attribute cache related flags separately. Note that this 331 * function now computes attribute-cache flags for both Amd's automount 332 * points (NFS) as well as any normal NFS mount that Amd performs. Edit 333 * with caution. 334 */ 335static void 336compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp) 337{ 338 int acval = 0; 339 int err_acval = 1; /* 1 means we found no 'actimeo' value */ 340#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) 341 int err_acrdmm; /* for ac{reg,dir}{min,max} */ 342#endif /* HAVE_NFS_ARGS_T_AC{REG,DIR}{MIN,MAX} */ 343 344 /************************************************************************/ 345 /*** ATTRIBUTE CACHES ***/ 346 /************************************************************************/ 347 /* 348 * acval is set to 0 at the top of the function. If actimeo mount option 349 * exists and defined in mntopts, then its acval is set to it. 350 * If the value is non-zero, then we set all attribute cache fields to it. 351 * If acval is zero, it means it was never defined in mntopts or the 352 * actimeo mount option does not exist, in which case we check for 353 * individual mount options per attribute cache. 354 * Regardless of the value of acval, mount flags are set based directly 355 * on the values of the attribute caches. 356 */ 357#ifdef MNTTAB_OPT_ACTIMEO 358 err_acval = hasmntvalerr(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */ 359#endif /* MNTTAB_OPT_ACTIMEO */ 360 361 /*** acregmin ***/ 362#ifdef HAVE_NFS_ARGS_T_ACREGMIN 363 err_acrdmm = 1; /* 1 means we found no acregmin value */ 364 if (!err_acval) { 365 nap->acregmin = acval; /* min ac timeout for reg files (sec) */ 366 } else { 367# ifdef MNTTAB_OPT_ACREGMIN 368 err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, (int *) &nap->acregmin); 369# else /* not MNTTAB_OPT_ACREGMIN */ 370 nap->acregmin = 0; 371# endif /* not MNTTAB_OPT_ACREGMIN */ 372 } 373 /* set this flag iff we changed acregmin (possibly to zero) */ 374# ifdef MNT2_NFS_OPT_ACREGMIN 375 if (!err_acval || !err_acrdmm) 376 nap->flags |= MNT2_NFS_OPT_ACREGMIN; 377# endif /* MNT2_NFS_OPT_ACREGMIN */ 378#endif /* HAVE_NFS_ARGS_T_ACREGMIN */ 379 380 /*** acregmax ***/ 381#ifdef HAVE_NFS_ARGS_T_ACREGMAX 382 err_acrdmm = 1; /* 1 means we found no acregmax value */ 383 if (!err_acval) { 384 nap->acregmax = acval; /* max ac timeout for reg files (sec) */ 385 } else { 386# ifdef MNTTAB_OPT_ACREGMAX 387 err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, (int *) &nap->acregmax); 388# else /* not MNTTAB_OPT_ACREGMAX */ 389 nap->acregmax = 0; 390# endif /* not MNTTAB_OPT_ACREGMAX */ 391 } 392 /* set this flag iff we changed acregmax (possibly to zero) */ 393# ifdef MNT2_NFS_OPT_ACREGMAX 394 if (!err_acval || !err_acrdmm) 395 nap->flags |= MNT2_NFS_OPT_ACREGMAX; 396# endif /* MNT2_NFS_OPT_ACREGMAX */ 397#endif /* HAVE_NFS_ARGS_T_ACREGMAX */ 398 399 /*** acdirmin ***/ 400#ifdef HAVE_NFS_ARGS_T_ACDIRMIN 401 err_acrdmm = 1; /* 1 means we found no acdirmin value */ 402 if (!err_acval) { 403 nap->acdirmin = acval; /* min ac timeout for dirs (sec) */ 404 } else { 405# ifdef MNTTAB_OPT_ACDIRMIN 406 err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, (int *) &nap->acdirmin); 407# else /* not MNTTAB_OPT_ACDIRMIN */ 408 nap->acdirmin = 0; 409# endif /* not MNTTAB_OPT_ACDIRMIN */ 410 } 411 /* set this flag iff we changed acdirmin (possibly to zero) */ 412# ifdef MNT2_NFS_OPT_ACDIRMIN 413 if (!err_acval || !err_acrdmm) 414 nap->flags |= MNT2_NFS_OPT_ACDIRMIN; 415# endif /* MNT2_NFS_OPT_ACDIRMIN */ 416#endif /* HAVE_NFS_ARGS_T_ACDIRMIN */ 417 418 /*** acdirmax ***/ 419#ifdef HAVE_NFS_ARGS_T_ACDIRMAX 420 err_acrdmm = 1; /* 1 means we found no acdirmax value */ 421 if (!err_acval) { 422 nap->acdirmax = acval; /* max ac timeout for dirs (sec) */ 423 } else { 424# ifdef MNTTAB_OPT_ACDIRMAX 425 err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, (int *) &nap->acdirmax); 426# else /* not MNTTAB_OPT_ACDIRMAX */ 427 nap->acdirmax = 0; 428# endif /* not MNTTAB_OPT_ACDIRMAX */ 429 } 430 /* set this flag iff we changed acdirmax (possibly to zero) */ 431# ifdef MNT2_NFS_OPT_ACDIRMAX 432 if (!err_acval || !err_acrdmm) 433 nap->flags |= MNT2_NFS_OPT_ACDIRMAX; 434# endif /* MNT2_NFS_OPT_ACDIRMAX */ 435#endif /* HAVE_NFS_ARGS_T_ACDIRMAX */ 436 437 438 /* don't cache attributes */ 439#if defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) 440 if (amu_hasmntopt(mntp, MNTTAB_OPT_NOAC) != NULL) 441 nap->flags |= MNT2_NFS_OPT_NOAC; 442#endif /* defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) */ 443} 444 445 446/* 447 * Fill in the many possible fields and flags of struct nfs_args. 448 * 449 * nap: pre-allocated structure to fill in. 450 * mntp: mount entry structure (includes options) 451 * genflags: generic mount flags already determined 452 * nfsncp: (TLI only) netconfig entry for this NFS mount 453 * ip_addr: IP address of file server 454 * nfs_version: 2, 3, (4 in the future), or 0 if unknown 455 * nfs_proto: "udp", "tcp", or NULL. 456 * fhp: file handle structure pointer 457 * host_name: name of remote NFS host 458 * fs_name: remote file system name to mount 459 */ 460void 461compute_nfs_args(nfs_args_t *nap, 462 mntent_t *mntp, 463 int genflags, 464 struct netconfig *nfsncp, 465 struct sockaddr_in *ip_addr, 466 u_long nfs_version, 467 char *nfs_proto, 468 am_nfs_handle_t *fhp, 469 char *host_name, 470 char *fs_name) 471{ 472 /* initialize just in case */ 473 memset((voidp) nap, 0, sizeof(nfs_args_t)); 474 475 /* compute all of the NFS attribute-cache flags */ 476 compute_nfs_attrcache_flags(nap, mntp); 477 478 /************************************************************************/ 479 /*** FILEHANDLE DATA AND LENGTH ***/ 480 /************************************************************************/ 481#ifdef HAVE_FS_NFS3 482 if (nfs_version == NFS_VERSION3) { 483# if defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) 484 /* 485 * Some systems (Irix/bsdi3) have a separate field in nfs_args for 486 * the length of the file handle for NFS V3. They insist that 487 * the file handle set in nfs_args be plain bytes, and not 488 * include the length field. 489 */ 490 NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3.am_fh3_data); 491# else /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */ 492 NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3); 493# endif /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */ 494# ifdef MNT2_NFS_OPT_NFSV3 495 nap->flags |= MNT2_NFS_OPT_NFSV3; 496# endif /* MNT2_NFS_OPT_NFSV3 */ 497# ifdef MNT2_NFS_OPT_VER3 498 nap->flags |= MNT2_NFS_OPT_VER3; 499# endif /* MNT2_NFS_OPT_VER3 */ 500 } else 501#endif /* HAVE_FS_NFS3 */ 502 NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v2); 503 504#ifdef HAVE_NFS_ARGS_T_FHSIZE 505# ifdef HAVE_FS_NFS3 506 if (nfs_version == NFS_VERSION3) 507 nap->fhsize = fhp->v3.am_fh3_length; 508 else 509# endif /* HAVE_FS_NFS3 */ 510 nap->fhsize = FHSIZE; 511#endif /* HAVE_NFS_ARGS_T_FHSIZE */ 512 513 /* this is the version of the nfs_args structure, not of NFS! */ 514#ifdef HAVE_NFS_ARGS_T_FH_LEN 515# ifdef HAVE_FS_NFS3 516 if (nfs_version == NFS_VERSION3) 517 nap->fh_len = fhp->v3.am_fh3_length; 518 else 519# endif /* HAVE_FS_NFS3 */ 520 nap->fh_len = FHSIZE; 521#endif /* HAVE_NFS_ARGS_T_FH_LEN */ 522 523 /************************************************************************/ 524 /*** HOST NAME ***/ 525 /************************************************************************/ 526 /* 527 * XXX: warning, using xstrlcpy in NFS_HN_DREF, which may corrupt a 528 * struct nfs_args, or truncate our concocted "hostname:/path" 529 * string prematurely. 530 */ 531 NFS_HN_DREF(nap->hostname, host_name); 532#ifdef MNT2_NFS_OPT_HOSTNAME 533 nap->flags |= MNT2_NFS_OPT_HOSTNAME; 534#endif /* MNT2_NFS_OPT_HOSTNAME */ 535 536 /************************************************************************/ 537 /*** IP ADDRESS OF REMOTE HOST ***/ 538 /************************************************************************/ 539 if (ip_addr) { 540#ifdef HAVE_TRANSPORT_TYPE_TLI 541 nap->addr = ALLOC(struct netbuf); /* free()'ed at end of mount_nfs_fh() */ 542#endif /* HAVE_TRANSPORT_TYPE_TLI */ 543 NFS_SA_DREF(nap, ip_addr); 544 } 545 546 /************************************************************************/ 547 /*** NFS PROTOCOL (UDP, TCP) AND VERSION ***/ 548 /************************************************************************/ 549#ifdef MNT2_NFS_OPT_TCP 550 if (nfs_proto && STREQ(nfs_proto, "tcp")) 551 nap->flags |= MNT2_NFS_OPT_TCP; 552#endif /* MNT2_NFS_OPT_TCP */ 553 554#ifdef HAVE_NFS_ARGS_T_SOTYPE 555 /* bsdi3 uses this */ 556 if (nfs_proto) { 557 if (STREQ(nfs_proto, "tcp")) 558 nap->sotype = SOCK_STREAM; 559 else if (STREQ(nfs_proto, "udp")) 560 nap->sotype = SOCK_DGRAM; 561 } 562#endif /* HAVE_NFS_ARGS_T_SOTYPE */ 563 564#ifdef HAVE_NFS_ARGS_T_PROTO 565 nap->proto = 0; /* bsdi3 sets this field to zero */ 566# ifdef IPPROTO_TCP 567 if (nfs_proto) { 568 if (STREQ(nfs_proto, "tcp")) /* AIX 4.2.x needs this */ 569 nap->proto = IPPROTO_TCP; 570 else if (STREQ(nfs_proto, "udp")) 571 nap->proto = IPPROTO_UDP; 572 } 573# endif /* IPPROTO_TCP */ 574#endif /* HAVE_NFS_ARGS_T_SOTYPE */ 575 576#ifdef HAVE_NFS_ARGS_T_VERSION 577# ifdef NFS_ARGSVERSION 578 nap->version = NFS_ARGSVERSION; /* BSDI 3.0 and OpenBSD 2.2 */ 579# endif /* NFS_ARGSVERSION */ 580# ifdef DG_MOUNT_NFS_VERSION 581 nap->version = DG_MOUNT_NFS_VERSION; /* dg-ux */ 582# endif /* DG_MOUNT_NFS_VERSION */ 583#endif /* HAVE_NFS_ARGS_VERSION */ 584 585 /************************************************************************/ 586 /*** OTHER NFS SOCKET RELATED OPTIONS AND FLAGS ***/ 587 /************************************************************************/ 588#ifdef MNT2_NFS_OPT_NOCONN 589 /* check if user specified to use unconnected or connected sockets */ 590 if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL) 591 nap->flags |= MNT2_NFS_OPT_NOCONN; 592 else if (amu_hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL) 593 nap->flags &= ~MNT2_NFS_OPT_NOCONN; 594 else { 595 /* 596 * Some OSs want you to set noconn always. Some want you to always turn 597 * it off. Others want you to turn it on/off only if NFS V.3 is used. 598 * And all of that changes from revision to another. This is 599 * particularly true of OpenBSD, NetBSD, and FreeBSD. So, rather than 600 * attempt to auto-detect this, I'm forced to "fix" it in the individual 601 * conf/nfs_prot/nfs_prot_*.h files. 602 */ 603# ifdef USE_UNCONNECTED_NFS_SOCKETS 604 if (!(nap->flags & MNT2_NFS_OPT_NOCONN)) { 605 nap->flags |= MNT2_NFS_OPT_NOCONN; 606 plog(XLOG_WARNING, "noconn option not specified, and was just turned ON (OS override)! (May cause NFS hangs on some systems...)"); 607 } 608# endif /* USE_UNCONNECTED_NFS_SOCKETS */ 609# ifdef USE_CONNECTED_NFS_SOCKETS 610 if (nap->flags & MNT2_NFS_OPT_NOCONN) { 611 nap->flags &= ~MNT2_NFS_OPT_NOCONN; 612 plog(XLOG_WARNING, "noconn option specified, and was just turned OFF (OS override)! (May cause NFS hangs on some systems...)"); 613 } 614# endif /* USE_CONNECTED_NFS_SOCKETS */ 615 } 616#endif /* MNT2_NFS_OPT_NOCONN */ 617 618#ifdef MNT2_NFS_OPT_RESVPORT 619# ifdef MNTTAB_OPT_RESVPORT 620 if (amu_hasmntopt(mntp, MNTTAB_OPT_RESVPORT) != NULL) 621 nap->flags |= MNT2_NFS_OPT_RESVPORT; 622# else /* not MNTTAB_OPT_RESVPORT */ 623 nap->flags |= MNT2_NFS_OPT_RESVPORT; 624# endif /* not MNTTAB_OPT_RESVPORT */ 625#endif /* MNT2_NFS_OPT_RESVPORT */ 626 627 /************************************************************************/ 628 /*** OTHER FLAGS AND OPTIONS ***/ 629 /************************************************************************/ 630 631#ifdef HAVE_TRANSPORT_TYPE_TLI 632 /* set up syncaddr field */ 633 nap->syncaddr = (struct netbuf *) NULL; 634 635 /* set up knconf field */ 636 if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) { 637 plog(XLOG_FATAL, "cannot fill knetconfig structure for nfs_args"); 638 going_down(1); 639 } 640 /* update the flags field for knconf */ 641 nap->flags |= MNT2_NFS_OPT_KNCONF; 642#endif /* HAVE_TRANSPORT_TYPE_TLI */ 643 644#ifdef MNT2_NFS_OPT_FSNAME 645 nap->fsname = fs_name; 646 nap->flags |= MNT2_NFS_OPT_FSNAME; 647#endif /* MNT2_NFS_OPT_FSNAME */ 648 649 nap->rsize = hasmntval(mntp, MNTTAB_OPT_RSIZE); 650#ifdef MNT2_NFS_OPT_RSIZE 651 if (nap->rsize) 652 nap->flags |= MNT2_NFS_OPT_RSIZE; 653#endif /* MNT2_NFS_OPT_RSIZE */ 654 if (nfs_version == NFS_VERSION && nap->rsize > 8192) 655 nap->rsize = 8192; 656 657 nap->wsize = hasmntval(mntp, MNTTAB_OPT_WSIZE); 658#ifdef MNT2_NFS_OPT_WSIZE 659 if (nap->wsize) 660 nap->flags |= MNT2_NFS_OPT_WSIZE; 661#endif /* MNT2_NFS_OPT_WSIZE */ 662 if (nfs_version == NFS_VERSION && nap->wsize > 8192) 663 nap->wsize = 8192; 664 665 nap->timeo = hasmntval(mntp, MNTTAB_OPT_TIMEO); 666#ifdef MNT2_NFS_OPT_TIMEO 667 if (nap->timeo) 668 nap->flags |= MNT2_NFS_OPT_TIMEO; 669#endif /* MNT2_NFS_OPT_TIMEO */ 670 671 nap->retrans = hasmntval(mntp, MNTTAB_OPT_RETRANS); 672#ifdef MNT2_NFS_OPT_RETRANS 673 if (nap->retrans) 674 nap->flags |= MNT2_NFS_OPT_RETRANS; 675#endif /* MNT2_NFS_OPT_RETRANS */ 676 677#ifdef MNT2_NFS_OPT_BIODS 678 if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS))) 679 nap->flags |= MNT2_NFS_OPT_BIODS; 680#endif /* MNT2_NFS_OPT_BIODS */ 681 682#ifdef MNT2_NFS_OPT_SOFT 683 if (amu_hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL) 684 nap->flags |= MNT2_NFS_OPT_SOFT; 685#endif /* MNT2_NFS_OPT_SOFT */ 686 687#ifdef MNT2_NFS_OPT_SPONGY 688 if (amu_hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) { 689 nap->flags |= MNT2_NFS_OPT_SPONGY; 690 if (nap->flags & MNT2_NFS_OPT_SOFT) { 691 plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored"); 692 nap->flags &= ~MNT2_NFS_OPT_SOFT; 693 } 694 } 695#endif /* MNT2_NFS_OPT_SPONGY */ 696 697#if defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) 698 /* Ultrix has separate generic and NFS ro flags */ 699 if (genflags & MNT2_GEN_OPT_RONLY) 700 nap->flags |= MNT2_NFS_OPT_RONLY; 701#endif /* defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) */ 702 703#ifdef MNTTAB_OPT_INTR 704 if (amu_hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL) 705 /* 706 * Either turn on the "allow interrupts" option, or 707 * turn off the "disallow interrupts" option" 708 */ 709# ifdef MNT2_NFS_OPT_INTR 710 nap->flags |= MNT2_NFS_OPT_INTR; 711# endif /* MNT2_NFS_OPT_INTR */ 712# ifdef MNT2_NFS_OPT_NOINTR 713 nap->flags &= ~MNT2_NFS_OPT_NOINTR; 714# endif /* MNT2_NFS_OPT_NOINTR */ 715# ifdef MNT2_NFS_OPT_INT 716 nap->flags |= MNT2_NFS_OPT_INT; 717# endif /* MNT2_NFS_OPT_INT */ 718# ifdef MNT2_NFS_OPT_NOINT 719 nap->flags &= ~MNT2_NFS_OPT_NOINT; 720# endif /* MNT2_NFS_OPT_NOINT */ 721#endif /* MNTTAB_OPT_INTR */ 722 723#ifdef MNTTAB_OPT_NODEVS 724 if (amu_hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL) 725 nap->flags |= MNT2_NFS_OPT_NODEVS; 726#endif /* MNTTAB_OPT_NODEVS */ 727 728#ifdef MNTTAB_OPT_COMPRESS 729 if (amu_hasmntopt(mntp, MNTTAB_OPT_COMPRESS) != NULL) 730 nap->flags |= MNT2_NFS_OPT_COMPRESS; 731#endif /* MNTTAB_OPT_COMPRESS */ 732 733#ifdef MNTTAB_OPT_PRIVATE /* mount private, single-client tree */ 734 if (amu_hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL) 735 nap->flags |= MNT2_NFS_OPT_PRIVATE; 736#endif /* MNTTAB_OPT_PRIVATE */ 737 738#ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */ 739 if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL))) 740 nap->flags |= MNT2_NFS_OPT_SYMTTL; 741#endif /* MNTTAB_OPT_SYMTTL */ 742 743#ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */ 744 if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH))) 745 nap->flags |= MNT2_NFS_OPT_PGTHRESH; 746#endif /* MNT2_NFS_OPT_PGTHRESH */ 747 748#if defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) 749 if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL) 750 nap->flags |= MNT2_NFS_OPT_NOCTO; 751#endif /* defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) */ 752 753#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX) 754 if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) { 755 nap->flags |= MNT2_NFS_OPT_POSIX; 756 nap->pathconf = NULL; 757 } 758#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */ 759 760#if defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) 761 if (amu_hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL) 762 nap->flags |= MNT2_NFS_OPT_PROPLIST; 763#endif /* defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) */ 764 765#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) 766 nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS); 767 if (nap->maxgrouplist != 0) 768 nap->flags |= MNT2_NFS_OPT_MAXGRPS; 769#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */ 770 771#if defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) 772 if (amu_hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL) 773 nap->flags |= MNT2_NFS_OPT_NONLM; 774#endif /* defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) */ 775 776#if defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) 777 if (amu_hasmntopt(mntp, MNTTAB_OPT_XLATECOOKIE) != NULL) 778 nap->flags |= MNT2_NFS_OPT_XLATECOOKIE; 779#endif /* defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) */ 780 781#ifdef HAVE_NFS_ARGS_T_OPTSTR 782 nap->optstr = mntp->mnt_opts; 783#endif /* HAVE_NFS_ARGS_T_OPTSTR */ 784 785 /************************************************************************/ 786 /*** FINAL ACTIONS ***/ 787 /************************************************************************/ 788 789#ifdef HAVE_NFS_ARGS_T_GFS_FLAGS 790 /* Ultrix stores generic flags in nfs_args.gfs_flags. */ 791 nap->gfs_flags = genflags; 792#endif /* HAVE_NFS_ARGS_T_FLAGS */ 793 794 return; /* end of compute_nfs_args() function */ 795} 796 797 798/* 799 * Fill in special values for flags and fields of nfs_args, for an 800 * automounter NFS mount. 801 */ 802void 803compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp) 804{ 805#ifdef MNT2_NFS_OPT_SYMTTL 806 /* 807 * Don't let the kernel cache symbolic links we generate, or else lookups 808 * will bypass amd and fail to remount stuff as needed. 809 */ 810 plog(XLOG_INFO, "turning on NFS option symttl and setting value to 0"); 811 nap->flags |= MNT2_NFS_OPT_SYMTTL; 812 nap->symttl = 0; 813#endif /* MNT2_NFS_OPT_SYMTTL */ 814 815 /* 816 * This completes the flags for the HIDE_MOUNT_TYPE code in the 817 * mount_amfs_toplvl() function in amd/amfs_toplvl.c. 818 * Some systems don't have a mount type, but a mount flag. 819 */ 820#ifdef MNT2_NFS_OPT_AUTO 821 nap->flags |= MNT2_NFS_OPT_AUTO; 822#endif /* MNT2_NFS_OPT_AUTO */ 823#ifdef MNT2_NFS_OPT_IGNORE 824 nap->flags |= MNT2_NFS_OPT_IGNORE; 825#endif /* MNT2_NFS_OPT_IGNORE */ 826#ifdef MNT2_GEN_OPT_AUTOMNTFS 827 nap->flags |= MNT2_GEN_OPT_AUTOMNTFS; 828#endif /* not MNT2_GEN_OPT_AUTOMNTFS */ 829 830#ifdef MNT2_NFS_OPT_DUMBTIMR 831 /* 832 * Don't let the kernel start computing throughput of Amd. The numbers 833 * will be meaningless because of the way Amd does mount retries. 834 */ 835 plog(XLOG_INFO, "%s: disabling nfs congestion window", mntp->mnt_dir); 836 nap->flags |= MNT2_NFS_OPT_DUMBTIMR; 837#endif /* MNT2_NFS_OPT_DUMBTIMR */ 838 839 /* compute all of the NFS attribute-cache flags */ 840 compute_nfs_attrcache_flags(nap, mntp); 841 842 /* 843 * Provide a slight bit more security by requiring the kernel to use 844 * reserved ports. 845 */ 846#ifdef MNT2_NFS_OPT_RESVPORT 847 nap->flags |= MNT2_NFS_OPT_RESVPORT; 848#endif /* MNT2_NFS_OPT_RESVPORT */ 849} 850 851 852#ifdef DEBUG 853/* get string version (in hex) of identifier */ 854static char * 855get_hex_string(u_int len, const char *fhdata) 856{ 857 u_int i; 858 static char buf[128]; /* better not go over it! */ 859 char str[16]; 860 short int arr[64]; 861 862 if (!fhdata) 863 return NULL; 864 buf[0] = '\0'; 865 memset(&arr[0], 0, (64 * sizeof(short int))); 866 memcpy(&arr[0], &fhdata[0], len); 867 for (i=0; i<len/sizeof(unsigned short int); i++) { 868 xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i])); 869 xstrlcat(buf, str, sizeof(buf)); 870 } 871 return buf; 872} 873 874 875/* 876 * print a subset of fields from "struct nfs_args" that are otherwise 877 * not being provided anywhere else. 878 */ 879void 880print_nfs_args(const nfs_args_t *nap, u_long nfs_version) 881{ 882 int fhlen = 32; /* default: NFS V.2 file handle length is 32 */ 883#ifdef HAVE_TRANSPORT_TYPE_TLI 884 struct netbuf *nbp; 885 struct knetconfig *kncp; 886#else /* not HAVE_TRANSPORT_TYPE_TLI */ 887 struct sockaddr_in *sap; 888#endif /* not HAVE_TRANSPORT_TYPE_TLI */ 889 890 if (!nap) { 891 plog(XLOG_DEBUG, "NULL nfs_args!"); 892 return; 893 } 894 895 /* override default file handle size */ 896#ifdef FHSIZE 897 fhlen = FHSIZE; 898#endif /* FHSIZE */ 899#ifdef NFS_FHSIZE 900 fhlen = NFS_FHSIZE; 901#endif /* NFS_FHSIZE */ 902 903#ifdef HAVE_TRANSPORT_TYPE_TLI 904 nbp = nap->addr; 905 plog(XLOG_DEBUG, "NA->addr {netbuf} (maxlen=%d, len=%d) = \"%s\"", 906 nbp->maxlen, nbp->len, 907 get_hex_string(nbp->len, nbp->buf)); 908 nbp = nap->syncaddr; 909 plog(XLOG_DEBUG, "NA->syncaddr {netbuf} %p", nbp); 910 kncp = nap->knconf; 911 plog(XLOG_DEBUG, "NA->knconf->semantics %lu", (u_long) kncp->knc_semantics); 912 plog(XLOG_DEBUG, "NA->knconf->protofmly \"%s\"", kncp->knc_protofmly); 913 plog(XLOG_DEBUG, "NA->knconf->proto \"%s\"", kncp->knc_proto); 914 plog(XLOG_DEBUG, "NA->knconf->rdev %lu", (u_long) kncp->knc_rdev); 915 /* don't print knconf->unused field */ 916#else /* not HAVE_TRANSPORT_TYPE_TLI */ 917# ifdef NFS_ARGS_T_ADDR_IS_POINTER 918 sap = (struct sockaddr_in *) nap->addr; 919# else /* not NFS_ARGS_T_ADDR_IS_POINTER */ 920 sap = (struct sockaddr_in *) &nap->addr; 921# endif /* not NFS_ARGS_T_ADDR_IS_POINTER */ 922 plog(XLOG_DEBUG, "NA->addr {sockaddr_in} (len=%d) = \"%s\"", 923 (int) sizeof(struct sockaddr_in), 924 get_hex_string(sizeof(struct sockaddr_in), (const char *)sap)); 925#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 926 /* as per POSIX, sin_len need not be set (used internally by kernel) */ 927 plog(XLOG_DEBUG, "NA->addr.sin_len = %d", sap->sin_len); 928#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ 929 plog(XLOG_DEBUG, "NA->addr.sin_family = %d", sap->sin_family); 930 plog(XLOG_DEBUG, "NA->addr.sin_port = %d", sap->sin_port); 931 plog(XLOG_DEBUG, "NA->addr.sin_addr = \"%s\"", 932 get_hex_string(sizeof(struct in_addr), (const char *) &sap->sin_addr)); 933#endif /* not HAVE_TRANSPORT_TYPE_TLI */ 934#ifdef HAVE_NFS_ARGS_T_ADDRLEN 935 plog(XLOG_DEBUG, "NA->addrlen = %d", nap->addrlen); 936#endif /* ifdef HAVE_NFS_ARGS_T_ADDRLEN */ 937 938 plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname ? nap->hostname : "null"); 939#ifdef HAVE_NFS_ARGS_T_NAMLEN 940 plog(XLOG_DEBUG, "NA->namlen = %d", nap->namlen); 941#endif /* HAVE_NFS_ARGS_T_NAMLEN */ 942 943#ifdef MNT2_NFS_OPT_FSNAME 944 plog(XLOG_DEBUG, "NA->fsname = \"%s\"", nap->fsname ? nap->fsname : "null"); 945#endif /* MNT2_NFS_OPT_FSNAME */ 946 947#ifdef HAVE_NFS_ARGS_T_FHSIZE 948 plog(XLOG_DEBUG, "NA->fhsize = %d", nap->fhsize); 949 fhlen = nap->fhsize; 950#endif /* HAVE_NFS_ARGS_T_FHSIZE */ 951#ifdef HAVE_NFS_ARGS_T_FH_LEN 952 plog(XLOG_DEBUG, "NA->fh_len = %d", nap->fh_len); 953 fhlen = nap->fh_len; 954#endif /* HAVE_NFS_ARGS_T_FH_LEN */ 955 956 /* 957 * XXX: need to figure out how to correctly print file handles, 958 * since some times they are pointers, and sometimes the real structure 959 * is stored in nfs_args. Even if it is a pointer, it can be the actual 960 * char[] array, or a structure containing multiple fields. 961 */ 962 plog(XLOG_DEBUG, "NA->filehandle = \"%s\"", 963 get_hex_string(fhlen, (const char *) &nap->NFS_FH_FIELD)); 964 965#ifdef HAVE_NFS_ARGS_T_SOTYPE 966 plog(XLOG_DEBUG, "NA->sotype = %d", nap->sotype); 967#endif /* HAVE_NFS_ARGS_T_SOTYPE */ 968#ifdef HAVE_NFS_ARGS_T_PROTO 969 plog(XLOG_DEBUG, "NA->proto = %d", (int) nap->proto); 970#endif /* HAVE_NFS_ARGS_T_PROTO */ 971#ifdef HAVE_NFS_ARGS_T_VERSION 972 plog(XLOG_DEBUG, "NA->version = %d", nap->version); 973#endif /* HAVE_NFS_ARGS_T_VERSION */ 974 975 plog(XLOG_DEBUG, "NA->flags = 0x%x", (int) nap->flags); 976 977 plog(XLOG_DEBUG, "NA->rsize = %d", (int) nap->rsize); 978 plog(XLOG_DEBUG, "NA->wsize = %d", (int) nap->wsize); 979#ifdef HAVE_NFS_ARGS_T_BSIZE 980 plog(XLOG_DEBUG, "NA->bsize = %d", nap->bsize); 981#endif /* HAVE_NFS_ARGS_T_BSIZE */ 982 plog(XLOG_DEBUG, "NA->timeo = %d", (int) nap->timeo); 983 plog(XLOG_DEBUG, "NA->retrans = %d", (int) nap->retrans); 984 985#ifdef HAVE_NFS_ARGS_T_ACREGMIN 986 plog(XLOG_DEBUG, "NA->acregmin = %d", (int) nap->acregmin); 987 plog(XLOG_DEBUG, "NA->acregmax = %d", (int) nap->acregmax); 988 plog(XLOG_DEBUG, "NA->acdirmin = %d", (int) nap->acdirmin); 989 plog(XLOG_DEBUG, "NA->acdirmax = %d", (int) nap->acdirmax); 990#endif /* HAVE_NFS_ARGS_T_ACREGMIN */ 991#ifdef MNTTAB_OPT_SYMTTL 992 plog(XLOG_DEBUG, "NA->symttl = %d", nap->symttl); 993#endif /* MNTTAB_OPT_SYMTTL */ 994#ifdef MNTTAB_OPT_PG_THRESH 995 plog(XLOG_DEBUG, "NA->pg_thresh = %d", nap->pg_thresh); 996#endif /* MNTTAB_OPT_PG_THRESH */ 997 998#ifdef MNT2_NFS_OPT_BIODS 999 plog(XLOG_DEBUG, "NA->biods = %d", nap->biods); 1000#endif /* MNT2_NFS_OPT_BIODS */ 1001 1002} 1003#endif /* DEBUG */ 1004