voidp xmalloc(int len) { voidp p; int retries = 600; /* * Avoid malloc's which return NULL for malloc(0) */ if (len == 0) len = 1; do { p = (voidp) malloc((unsigned) len); if (p) { #if defined(DEBUG) && defined(DEBUG_MEM) amuDebug(D_MEM) plog(XLOG_DEBUG, "Allocated size %d; block %#x", len, p); #endif /* defined(DEBUG) && defined(DEBUG_MEM) */ return p; } if (retries > 0) { plog(XLOG_ERROR, "Retrying memory allocation"); sleep(1); } } while (--retries); plog(XLOG_FATAL, "Out of memory"); going_down(1); abort(); return 0; }
voidp xrealloc(voidp ptr, int len) { if (amuDebug(D_MEM)) plog(XLOG_DEBUG, "Reallocated size %d; block %p", len, ptr); if (len == 0) len = 1; if (ptr) ptr = (voidp) realloc(ptr, (unsigned) len); else ptr = (voidp) xmalloc((unsigned) len); if (!ptr) { plog(XLOG_FATAL, "Out of memory in realloc"); going_down(1); abort(); } return ptr; }
voidp xrealloc(voidp ptr, int len) { #if defined(DEBUG) && defined(DEBUG_MEM) amuDebug(D_MEM) plog(XLOG_DEBUG, "Reallocated size %d; block %#x", len, ptr); #endif /* defined(DEBUG) && defined(DEBUG_MEM) */ if (len == 0) len = 1; if (ptr) ptr = (voidp) realloc(ptr, (unsigned) len); else ptr = (voidp) xmalloc((unsigned) len); if (!ptr) { plog(XLOG_FATAL, "Out of memory in realloc"); going_down(1); abort(); } return ptr; }
int main(int argc, char *argv[]) { char *domdot, *verstr, *vertmp; int ppid = 0; int error; char *progname = NULL; /* "amd" */ char hostname[MAXHOSTNAMELEN + 1] = "localhost"; /* Hostname */ /* * Make sure some built-in assumptions are true before we start */ assert(sizeof(nfscookie) >= sizeof(u_int)); assert(sizeof(int) >= 4); /* * Set processing status. */ amd_state = Start; /* * Determine program name */ if (argv[0]) { progname = strrchr(argv[0], '/'); if (progname && progname[1]) progname++; else progname = argv[0]; } if (!progname) progname = "amd"; am_set_progname(progname); /* * Initialize process id. This is kept * cached since it is used for generating * and using file handles. */ am_set_mypid(); /* * Get local machine name */ if (gethostname(hostname, sizeof(hostname)) < 0) { plog(XLOG_FATAL, "gethostname: %m"); going_down(1); } hostname[sizeof(hostname) - 1] = '\0'; /* * Check it makes sense */ if (!*hostname) { plog(XLOG_FATAL, "host name is not set"); going_down(1); } /* * Initialize global options structure. */ init_global_options(); /* * Partially initialize hostd[]. This * is completed in get_args(). */ if ((domdot = strchr(hostname, '.'))) { /* * Hostname already contains domainname. * Split out hostname and domainname * components */ *domdot++ = '\0'; hostdomain = domdot; } xstrlcpy(hostd, hostname, sizeof(hostd)); am_set_hostname(hostname); /* * Setup signal handlers */ /* SIGINT: trap interrupts for shutdowns */ setup_sighandler(SIGINT, sigterm); /* SIGTERM: trap terminate so we can shutdown cleanly (some chance) */ setup_sighandler(SIGTERM, sigterm); /* SIGHUP: hangups tell us to reload the cache */ setup_sighandler(SIGHUP, sighup); /* * SIGCHLD: trap Death-of-a-child. These allow us to pick up the exit * status of backgrounded mounts. See "sched.c". */ setup_sighandler(SIGCHLD, sigchld); #ifdef HAVE_SIGACTION /* construct global "masked_sigs" used in nfs_start.c */ sigemptyset(&masked_sigs); sigaddset(&masked_sigs, SIGINT); sigaddset(&masked_sigs, SIGTERM); sigaddset(&masked_sigs, SIGHUP); sigaddset(&masked_sigs, SIGCHLD); #endif /* HAVE_SIGACTION */ /* * Fix-up any umask problems. Most systems default * to 002 which is not too convenient for our purposes */ orig_umask = umask(0); /* * Figure out primary network name */ getwire(&PrimNetName, &PrimNetNum); /* * Determine command-line arguments */ get_args(argc, argv); /* * Log version information. */ vertmp = get_version_string(); verstr = strtok(vertmp, "\n"); plog(XLOG_INFO, "AM-UTILS VERSION INFORMATION:"); while (verstr) { plog(XLOG_INFO, "%s", verstr); verstr = strtok(NULL, "\n"); } XFREE(vertmp); /* * Get our own IP address so that we can mount the automounter. We pass * localhost_address which could be used as the default localhost * name/address in amu_get_myaddress(). */ amu_get_myaddress(&myipaddr, gopt.localhost_address); plog(XLOG_INFO, "My ip addr is %s", inet_ntoa(myipaddr)); /* avoid hanging on other NFS servers if started elsewhere */ if (chdir("/") < 0) plog(XLOG_INFO, "cannot chdir to /: %m"); /* * Now check we are root. */ if (geteuid() != 0) { plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %ld)", (long) geteuid()); going_down(1); } #ifdef HAVE_MAP_NIS /* * If the domain was specified then bind it here * to circumvent any default bindings that may * be done in the C library. */ if (gopt.nis_domain && yp_bind(gopt.nis_domain)) { plog(XLOG_FATAL, "Can't bind to NIS domain \"%s\"", gopt.nis_domain); going_down(1); } #endif /* HAVE_MAP_NIS */ if (!amuDebug(D_DAEMON)) ppid = daemon_mode(); /* * Lock process text and data segment in memory. */ if (gopt.flags & CFM_PROCESS_LOCK) { do_memory_locking(); } do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval; /* * Register automounter with system. */ error = mount_automounter(ppid); if (error && ppid) kill(ppid, SIGALRM); #ifdef HAVE_FS_AUTOFS /* * XXX this should be part of going_down(), but I can't move it there * because it would be calling non-library code from the library... ugh */ if (amd_use_autofs) destroy_autofs_service(); #endif /* HAVE_FS_AUTOFS */ going_down(error); abort(); return 1; /* should never get here */ }
void nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp) { union { am_nfs_fh nfsproc_getattr_2_arg; nfssattrargs nfsproc_setattr_2_arg; nfsdiropargs nfsproc_lookup_2_arg; am_nfs_fh nfsproc_readlink_2_arg; nfsreadargs nfsproc_read_2_arg; nfswriteargs nfsproc_write_2_arg; nfscreateargs nfsproc_create_2_arg; nfsdiropargs nfsproc_remove_2_arg; nfsrenameargs nfsproc_rename_2_arg; nfslinkargs nfsproc_link_2_arg; nfssymlinkargs nfsproc_symlink_2_arg; nfscreateargs nfsproc_mkdir_2_arg; nfsdiropargs nfsproc_rmdir_2_arg; nfsreaddirargs nfsproc_readdir_2_arg; am_nfs_fh nfsproc_statfs_2_arg; } argument; char *result; xdrproc_t xdr_argument, xdr_result; nfssvcproc_t local; nfs_program_2_transp = NULL; switch (rqstp->rq_proc) { case NFSPROC_NULL: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_void; local = (nfssvcproc_t) nfsproc_null_2_svc; break; case NFSPROC_GETATTR: xdr_argument = (xdrproc_t) xdr_nfs_fh; xdr_result = (xdrproc_t) xdr_attrstat; local = (nfssvcproc_t) nfsproc_getattr_2_svc; break; case NFSPROC_SETATTR: xdr_argument = (xdrproc_t) xdr_sattrargs; xdr_result = (xdrproc_t) xdr_attrstat; local = (nfssvcproc_t) nfsproc_setattr_2_svc; break; case NFSPROC_ROOT: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_void; local = (nfssvcproc_t) nfsproc_root_2_svc; break; case NFSPROC_LOOKUP: xdr_argument = (xdrproc_t) xdr_diropargs; xdr_result = (xdrproc_t) xdr_diropres; local = (nfssvcproc_t) nfsproc_lookup_2_svc; /* * Cheap way to pass transp down to afs_lookuppn so it can * be stored in the am_node structure and later used for * quick_reply(). */ nfs_program_2_transp = transp; break; case NFSPROC_READLINK: xdr_argument = (xdrproc_t) xdr_nfs_fh; xdr_result = (xdrproc_t) xdr_readlinkres; local = (nfssvcproc_t) nfsproc_readlink_2_svc; break; case NFSPROC_READ: xdr_argument = (xdrproc_t) xdr_readargs; xdr_result = (xdrproc_t) xdr_readres; local = (nfssvcproc_t) nfsproc_read_2_svc; break; case NFSPROC_WRITECACHE: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_void; local = (nfssvcproc_t) nfsproc_writecache_2_svc; break; case NFSPROC_WRITE: xdr_argument = (xdrproc_t) xdr_writeargs; xdr_result = (xdrproc_t) xdr_attrstat; local = (nfssvcproc_t) nfsproc_write_2_svc; break; case NFSPROC_CREATE: xdr_argument = (xdrproc_t) xdr_createargs; xdr_result = (xdrproc_t) xdr_diropres; local = (nfssvcproc_t) nfsproc_create_2_svc; break; case NFSPROC_REMOVE: xdr_argument = (xdrproc_t) xdr_diropargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_remove_2_svc; break; case NFSPROC_RENAME: xdr_argument = (xdrproc_t) xdr_renameargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_rename_2_svc; break; case NFSPROC_LINK: xdr_argument = (xdrproc_t) xdr_linkargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_link_2_svc; break; case NFSPROC_SYMLINK: xdr_argument = (xdrproc_t) xdr_symlinkargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_symlink_2_svc; break; case NFSPROC_MKDIR: xdr_argument = (xdrproc_t) xdr_createargs; xdr_result = (xdrproc_t) xdr_diropres; local = (nfssvcproc_t) nfsproc_mkdir_2_svc; break; case NFSPROC_RMDIR: xdr_argument = (xdrproc_t) xdr_diropargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_rmdir_2_svc; break; case NFSPROC_READDIR: xdr_argument = (xdrproc_t) xdr_readdirargs; xdr_result = (xdrproc_t) xdr_readdirres; local = (nfssvcproc_t) nfsproc_readdir_2_svc; break; case NFSPROC_STATFS: xdr_argument = (xdrproc_t) xdr_nfs_fh; xdr_result = (xdrproc_t) xdr_statfsres; local = (nfssvcproc_t) nfsproc_statfs_2_svc; break; default: svcerr_noproc(transp); return; } memset((char *) &argument, 0, sizeof(argument)); if (!svc_getargs(transp, (XDRPROC_T_TYPE) xdr_argument, (SVC_IN_ARG_TYPE) &argument)) { plog(XLOG_ERROR, "NFS xdr decode failed for %d %d %d", (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc); svcerr_decode(transp); return; } result = (*local) (&argument, rqstp); nfs_program_2_transp = NULL; if (result != NULL && !svc_sendreply(transp, (XDRPROC_T_TYPE) xdr_result, result)) { svcerr_systemerr(transp); } if (!svc_freeargs(transp, (XDRPROC_T_TYPE) xdr_argument, (SVC_IN_ARG_TYPE) & argument)) { plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2"); going_down(1); } }
void nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp) { union { am_nfs_fh nfsproc_getattr_2_arg; nfssattrargs nfsproc_setattr_2_arg; nfsdiropargs nfsproc_lookup_2_arg; am_nfs_fh nfsproc_readlink_2_arg; nfsreadargs nfsproc_read_2_arg; nfswriteargs nfsproc_write_2_arg; nfscreateargs nfsproc_create_2_arg; nfsdiropargs nfsproc_remove_2_arg; nfsrenameargs nfsproc_rename_2_arg; nfslinkargs nfsproc_link_2_arg; nfssymlinkargs nfsproc_symlink_2_arg; nfscreateargs nfsproc_mkdir_2_arg; nfsdiropargs fsproc_rmdir_2_arg; nfsreaddirargs nfsproc_readdir_2_arg; am_nfs_fh nfsproc_statfs_2_arg; } argument; char *result; xdrproc_t xdr_argument, xdr_result; nfssvcproc_t local; #ifdef HAVE_TRANSPORT_TYPE_TLI /* * On TLI systems we don't use an INET network type, but a "ticlts" (see * /etc/netconfig and conf/transp_tli.c:create_nfs_service). This means * that packets could only come from the loopback interface, and we don't * need to check them and filter possibly spoofed packets. Therefore we * only need to check if the UID caller is correct. */ # ifdef HAVE___RPC_GET_LOCAL_UID uid_t u; /* extern definition for an internal libnsl function */ extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid); if (__rpc_get_local_uid(transp, &u) >= 0 && u != 0) { plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u); return; } # else /* not HAVE___RPC_GET_LOCAL_UID */ dlog("cannot verify local uid for rpc request"); # endif /* HAVE___RPC_GET_LOCAL_UID */ #else /* not HAVE_TRANPORT_TYPE_TLI */ struct sockaddr_in *sinp; char dq[20], dq2[28]; sinp = amu_svc_getcaller(rqstp->rq_xprt); # ifdef MNT2_NFS_OPT_RESVPORT /* Verify that the request comes from a reserved port */ if (sinp && ntohs(sinp->sin_port) >= IPPORT_RESERVED && !(gopt.flags & CFM_NFS_INSECURE_PORT)) { plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved", inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr), ntohs(sinp->sin_port)); return; } # endif /* MNT2_NFS_OPT_RESVPORT */ /* if the address does not match, ignore the request */ if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) { if (gopt.flags & CFM_NFS_ANY_INTERFACE) { if (!is_interface_local(sinp->sin_addr.s_addr)) { plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface", inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr), ntohs(sinp->sin_port)); } } else { plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s", inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr), ntohs(sinp->sin_port), inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr)); return; } } #endif /* not HAVE_TRANPORT_TYPE_TLI */ current_transp = NULL; switch (rqstp->rq_proc) { case NFSPROC_NULL: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_void; local = (nfssvcproc_t) nfsproc_null_2_svc; break; case NFSPROC_GETATTR: xdr_argument = (xdrproc_t) xdr_nfs_fh; xdr_result = (xdrproc_t) xdr_attrstat; local = (nfssvcproc_t) nfsproc_getattr_2_svc; break; case NFSPROC_SETATTR: xdr_argument = (xdrproc_t) xdr_sattrargs; xdr_result = (xdrproc_t) xdr_attrstat; local = (nfssvcproc_t) nfsproc_setattr_2_svc; break; case NFSPROC_ROOT: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_void; local = (nfssvcproc_t) nfsproc_root_2_svc; break; case NFSPROC_LOOKUP: xdr_argument = (xdrproc_t) xdr_diropargs; xdr_result = (xdrproc_t) xdr_diropres; local = (nfssvcproc_t) nfsproc_lookup_2_svc; /* * Cheap way to pass transp down to amfs_auto_lookuppn so it can * be stored in the am_node structure and later used for * quick_reply(). */ current_transp = transp; break; case NFSPROC_READLINK: xdr_argument = (xdrproc_t) xdr_nfs_fh; xdr_result = (xdrproc_t) xdr_readlinkres; local = (nfssvcproc_t) nfsproc_readlink_2_svc; break; case NFSPROC_READ: xdr_argument = (xdrproc_t) xdr_readargs; xdr_result = (xdrproc_t) xdr_readres; local = (nfssvcproc_t) nfsproc_read_2_svc; break; case NFSPROC_WRITECACHE: xdr_argument = (xdrproc_t) xdr_void; xdr_result = (xdrproc_t) xdr_void; local = (nfssvcproc_t) nfsproc_writecache_2_svc; break; case NFSPROC_WRITE: xdr_argument = (xdrproc_t) xdr_writeargs; xdr_result = (xdrproc_t) xdr_attrstat; local = (nfssvcproc_t) nfsproc_write_2_svc; break; case NFSPROC_CREATE: xdr_argument = (xdrproc_t) xdr_createargs; xdr_result = (xdrproc_t) xdr_diropres; local = (nfssvcproc_t) nfsproc_create_2_svc; break; case NFSPROC_REMOVE: xdr_argument = (xdrproc_t) xdr_diropargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_remove_2_svc; break; case NFSPROC_RENAME: xdr_argument = (xdrproc_t) xdr_renameargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_rename_2_svc; break; case NFSPROC_LINK: xdr_argument = (xdrproc_t) xdr_linkargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_link_2_svc; break; case NFSPROC_SYMLINK: xdr_argument = (xdrproc_t) xdr_symlinkargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_symlink_2_svc; break; case NFSPROC_MKDIR: xdr_argument = (xdrproc_t) xdr_createargs; xdr_result = (xdrproc_t) xdr_diropres; local = (nfssvcproc_t) nfsproc_mkdir_2_svc; break; case NFSPROC_RMDIR: xdr_argument = (xdrproc_t) xdr_diropargs; xdr_result = (xdrproc_t) xdr_nfsstat; local = (nfssvcproc_t) nfsproc_rmdir_2_svc; break; case NFSPROC_READDIR: xdr_argument = (xdrproc_t) xdr_readdirargs; xdr_result = (xdrproc_t) xdr_readdirres; local = (nfssvcproc_t) nfsproc_readdir_2_svc; break; case NFSPROC_STATFS: xdr_argument = (xdrproc_t) xdr_nfs_fh; xdr_result = (xdrproc_t) xdr_statfsres; local = (nfssvcproc_t) nfsproc_statfs_2_svc; break; default: svcerr_noproc(transp); return; } memset((char *) &argument, 0, sizeof(argument)); if (!svc_getargs(transp, (XDRPROC_T_TYPE) xdr_argument, (SVC_IN_ARG_TYPE) &argument)) { plog(XLOG_ERROR, "NFS xdr decode failed for %d %d %d", (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc); svcerr_decode(transp); return; } result = (*local) (&argument, rqstp); current_transp = NULL; if (result != NULL && !svc_sendreply(transp, (XDRPROC_T_TYPE) xdr_result, result)) { svcerr_systemerr(transp); } if (!svc_freeargs(transp, (XDRPROC_T_TYPE) xdr_argument, (SVC_IN_ARG_TYPE) & argument)) { plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2"); going_down(1); } }
/* * Fill in the many possible fields and flags of struct nfs_args. * * nap: pre-allocated structure to fill in. * mntp: mount entry structure (includes options) * genflags: generic mount flags already determined * nfsncp: (TLI only) netconfig entry for this NFS mount * ip_addr: IP address of file server * nfs_version: 2, 3, (4 in the future), or 0 if unknown * nfs_proto: "udp", "tcp", or NULL. * fhp: file handle structure pointer * host_name: name of remote NFS host * fs_name: remote file system name to mount */ void compute_nfs_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) { /* initialize just in case */ memset((voidp) nap, 0, sizeof(nfs_args_t)); /* compute all of the NFS attribute-cache flags */ compute_nfs_attrcache_flags(nap, mntp); /************************************************************************/ /*** FILEHANDLE DATA AND LENGTH ***/ /************************************************************************/ #ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3) { # if defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) /* * Some systems (Irix/bsdi3) have a separate field in nfs_args for * the length of the file handle for NFS V3. They insist that * the file handle set in nfs_args be plain bytes, and not * include the length field. */ NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3.am_fh3_data); # else /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */ NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3); # endif /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */ # ifdef MNT2_NFS_OPT_NFSV3 nap->flags |= MNT2_NFS_OPT_NFSV3; # endif /* MNT2_NFS_OPT_NFSV3 */ # ifdef MNT2_NFS_OPT_VER3 nap->flags |= MNT2_NFS_OPT_VER3; # endif /* MNT2_NFS_OPT_VER3 */ } else #endif /* HAVE_FS_NFS3 */ NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v2); #ifdef HAVE_NFS_ARGS_T_FHSIZE # ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3) nap->fhsize = fhp->v3.am_fh3_length; else # endif /* HAVE_FS_NFS3 */ nap->fhsize = FHSIZE; #endif /* HAVE_NFS_ARGS_T_FHSIZE */ /* this is the version of the nfs_args structure, not of NFS! */ #ifdef HAVE_NFS_ARGS_T_FH_LEN # ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3) nap->fh_len = fhp->v3.am_fh3_length; else # endif /* HAVE_FS_NFS3 */ nap->fh_len = FHSIZE; #endif /* HAVE_NFS_ARGS_T_FH_LEN */ /************************************************************************/ /*** HOST NAME ***/ /************************************************************************/ /* * XXX: warning, using xstrlcpy in NFS_HN_DREF, which may corrupt a * struct nfs_args, or truncate our concocted "hostname:/path" * string prematurely. */ NFS_HN_DREF(nap->hostname, host_name); #ifdef MNT2_NFS_OPT_HOSTNAME nap->flags |= MNT2_NFS_OPT_HOSTNAME; #endif /* MNT2_NFS_OPT_HOSTNAME */ /************************************************************************/ /*** IP ADDRESS OF REMOTE HOST ***/ /************************************************************************/ if (ip_addr) { #ifdef HAVE_TRANSPORT_TYPE_TLI nap->addr = ALLOC(struct netbuf); /* free()'ed at end of mount_nfs_fh() */ #endif /* HAVE_TRANSPORT_TYPE_TLI */ NFS_SA_DREF(nap, ip_addr); } /************************************************************************/ /*** NFS PROTOCOL (UDP, TCP) AND VERSION ***/ /************************************************************************/ #ifdef MNT2_NFS_OPT_TCP if (nfs_proto && STREQ(nfs_proto, "tcp")) nap->flags |= MNT2_NFS_OPT_TCP; #endif /* MNT2_NFS_OPT_TCP */ #ifdef HAVE_NFS_ARGS_T_SOTYPE /* bsdi3 uses this */ if (nfs_proto) { if (STREQ(nfs_proto, "tcp")) nap->sotype = SOCK_STREAM; else if (STREQ(nfs_proto, "udp")) nap->sotype = SOCK_DGRAM; } #endif /* HAVE_NFS_ARGS_T_SOTYPE */ #ifdef HAVE_NFS_ARGS_T_PROTO nap->proto = 0; /* bsdi3 sets this field to zero */ # ifdef IPPROTO_TCP if (nfs_proto) { if (STREQ(nfs_proto, "tcp")) /* AIX 4.2.x needs this */ nap->proto = IPPROTO_TCP; else if (STREQ(nfs_proto, "udp")) nap->proto = IPPROTO_UDP; } # endif /* IPPROTO_TCP */ #endif /* HAVE_NFS_ARGS_T_SOTYPE */ #ifdef HAVE_NFS_ARGS_T_VERSION # ifdef NFS_ARGSVERSION nap->version = NFS_ARGSVERSION; /* BSDI 3.0 and OpenBSD 2.2 */ # endif /* NFS_ARGSVERSION */ # ifdef DG_MOUNT_NFS_VERSION nap->version = DG_MOUNT_NFS_VERSION; /* dg-ux */ # endif /* DG_MOUNT_NFS_VERSION */ #endif /* HAVE_NFS_ARGS_VERSION */ /************************************************************************/ /*** OTHER NFS SOCKET RELATED OPTIONS AND FLAGS ***/ /************************************************************************/ #ifdef MNT2_NFS_OPT_NOCONN /* check if user specified to use unconnected or connected sockets */ if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL) nap->flags |= MNT2_NFS_OPT_NOCONN; else if (amu_hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL) nap->flags &= ~MNT2_NFS_OPT_NOCONN; else { /* * Some OSs want you to set noconn always. Some want you to always turn * it off. Others want you to turn it on/off only if NFS V.3 is used. * And all of that changes from revision to another. This is * particularly true of OpenBSD, NetBSD, and FreeBSD. So, rather than * attempt to auto-detect this, I'm forced to "fix" it in the individual * conf/nfs_prot/nfs_prot_*.h files. */ # ifdef USE_UNCONNECTED_NFS_SOCKETS if (!(nap->flags & MNT2_NFS_OPT_NOCONN)) { nap->flags |= MNT2_NFS_OPT_NOCONN; plog(XLOG_WARNING, "noconn option not specified, and was just turned ON (OS override)! (May cause NFS hangs on some systems...)"); } # endif /* USE_UNCONNECTED_NFS_SOCKETS */ # ifdef USE_CONNECTED_NFS_SOCKETS if (nap->flags & MNT2_NFS_OPT_NOCONN) { nap->flags &= ~MNT2_NFS_OPT_NOCONN; plog(XLOG_WARNING, "noconn option specified, and was just turned OFF (OS override)! (May cause NFS hangs on some systems...)"); } # endif /* USE_CONNECTED_NFS_SOCKETS */ } #endif /* MNT2_NFS_OPT_NOCONN */ #ifdef MNT2_NFS_OPT_RESVPORT # ifdef MNTTAB_OPT_RESVPORT if (amu_hasmntopt(mntp, MNTTAB_OPT_RESVPORT) != NULL) nap->flags |= MNT2_NFS_OPT_RESVPORT; # else /* not MNTTAB_OPT_RESVPORT */ nap->flags |= MNT2_NFS_OPT_RESVPORT; # endif /* not MNTTAB_OPT_RESVPORT */ #endif /* MNT2_NFS_OPT_RESVPORT */ /************************************************************************/ /*** OTHER FLAGS AND OPTIONS ***/ /************************************************************************/ #ifdef HAVE_TRANSPORT_TYPE_TLI /* set up syncaddr field */ nap->syncaddr = (struct netbuf *) NULL; /* set up knconf field */ if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) { plog(XLOG_FATAL, "cannot fill knetconfig structure for nfs_args"); going_down(1); } /* update the flags field for knconf */ nap->flags |= MNT2_NFS_OPT_KNCONF; #endif /* HAVE_TRANSPORT_TYPE_TLI */ #ifdef MNT2_NFS_OPT_FSNAME nap->fsname = fs_name; nap->flags |= MNT2_NFS_OPT_FSNAME; #endif /* MNT2_NFS_OPT_FSNAME */ nap->rsize = hasmntval(mntp, MNTTAB_OPT_RSIZE); #ifdef MNT2_NFS_OPT_RSIZE if (nap->rsize) nap->flags |= MNT2_NFS_OPT_RSIZE; #endif /* MNT2_NFS_OPT_RSIZE */ if (nfs_version == NFS_VERSION && nap->rsize > 8192) nap->rsize = 8192; nap->wsize = hasmntval(mntp, MNTTAB_OPT_WSIZE); #ifdef MNT2_NFS_OPT_WSIZE if (nap->wsize) nap->flags |= MNT2_NFS_OPT_WSIZE; #endif /* MNT2_NFS_OPT_WSIZE */ if (nfs_version == NFS_VERSION && nap->wsize > 8192) nap->wsize = 8192; nap->timeo = hasmntval(mntp, MNTTAB_OPT_TIMEO); #ifdef MNT2_NFS_OPT_TIMEO if (nap->timeo) nap->flags |= MNT2_NFS_OPT_TIMEO; #endif /* MNT2_NFS_OPT_TIMEO */ nap->retrans = hasmntval(mntp, MNTTAB_OPT_RETRANS); #ifdef MNT2_NFS_OPT_RETRANS if (nap->retrans) nap->flags |= MNT2_NFS_OPT_RETRANS; #endif /* MNT2_NFS_OPT_RETRANS */ #ifdef MNT2_NFS_OPT_BIODS if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS))) nap->flags |= MNT2_NFS_OPT_BIODS; #endif /* MNT2_NFS_OPT_BIODS */ #ifdef MNT2_NFS_OPT_SOFT if (amu_hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL) nap->flags |= MNT2_NFS_OPT_SOFT; #endif /* MNT2_NFS_OPT_SOFT */ #ifdef MNT2_NFS_OPT_SPONGY if (amu_hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) { nap->flags |= MNT2_NFS_OPT_SPONGY; if (nap->flags & MNT2_NFS_OPT_SOFT) { plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored"); nap->flags &= ~MNT2_NFS_OPT_SOFT; } } #endif /* MNT2_NFS_OPT_SPONGY */ #if defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) /* Ultrix has separate generic and NFS ro flags */ if (genflags & MNT2_GEN_OPT_RONLY) nap->flags |= MNT2_NFS_OPT_RONLY; #endif /* defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) */ #ifdef MNTTAB_OPT_INTR if (amu_hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL) /* * Either turn on the "allow interrupts" option, or * turn off the "disallow interrupts" option" */ # ifdef MNT2_NFS_OPT_INTR nap->flags |= MNT2_NFS_OPT_INTR; # endif /* MNT2_NFS_OPT_INTR */ # ifdef MNT2_NFS_OPT_NOINTR nap->flags &= ~MNT2_NFS_OPT_NOINTR; # endif /* MNT2_NFS_OPT_NOINTR */ # ifdef MNT2_NFS_OPT_INT nap->flags |= MNT2_NFS_OPT_INT; # endif /* MNT2_NFS_OPT_INT */ # ifdef MNT2_NFS_OPT_NOINT nap->flags &= ~MNT2_NFS_OPT_NOINT; # endif /* MNT2_NFS_OPT_NOINT */ #endif /* MNTTAB_OPT_INTR */ #ifdef MNTTAB_OPT_NODEVS if (amu_hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL) nap->flags |= MNT2_NFS_OPT_NODEVS; #endif /* MNTTAB_OPT_NODEVS */ #ifdef MNTTAB_OPT_COMPRESS if (amu_hasmntopt(mntp, MNTTAB_OPT_COMPRESS) != NULL) nap->flags |= MNT2_NFS_OPT_COMPRESS; #endif /* MNTTAB_OPT_COMPRESS */ #ifdef MNTTAB_OPT_PRIVATE /* mount private, single-client tree */ if (amu_hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL) nap->flags |= MNT2_NFS_OPT_PRIVATE; #endif /* MNTTAB_OPT_PRIVATE */ #ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */ if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL))) nap->flags |= MNT2_NFS_OPT_SYMTTL; #endif /* MNTTAB_OPT_SYMTTL */ #ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */ if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH))) nap->flags |= MNT2_NFS_OPT_PGTHRESH; #endif /* MNT2_NFS_OPT_PGTHRESH */ #if defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL) nap->flags |= MNT2_NFS_OPT_NOCTO; #endif /* defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) */ #if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX) if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) { nap->flags |= MNT2_NFS_OPT_POSIX; # ifdef HAVE_NFS_ARGS_T_PATHCONF nap->pathconf = NULL; # endif /* HAVE_NFS_ARGS_T_PATHCONF */ } #endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */ #if defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) if (amu_hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL) nap->flags |= MNT2_NFS_OPT_PROPLIST; #endif /* defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) */ #if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS); if (nap->maxgrouplist != 0) nap->flags |= MNT2_NFS_OPT_MAXGRPS; #endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */ #if defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) if (amu_hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL) nap->flags |= MNT2_NFS_OPT_NONLM; #endif /* defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) */ #if defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) if (amu_hasmntopt(mntp, MNTTAB_OPT_XLATECOOKIE) != NULL) nap->flags |= MNT2_NFS_OPT_XLATECOOKIE; #endif /* defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) */ #ifdef HAVE_NFS_ARGS_T_OPTSTR nap->optstr = mntp->mnt_opts; #endif /* HAVE_NFS_ARGS_T_OPTSTR */ /************************************************************************/ /*** FINAL ACTIONS ***/ /************************************************************************/ #ifdef HAVE_NFS_ARGS_T_GFS_FLAGS /* Ultrix stores generic flags in nfs_args.gfs_flags. */ nap->gfs_flags = genflags; #endif /* HAVE_NFS_ARGS_T_FLAGS */ return; /* end of compute_nfs_args() function */ }