diff --git a/contrib/amd/amd/amq_subr.c b/contrib/amd/amd/amq_subr.c index a5c7f247c68e..79ecafc3d9b3 100644 --- a/contrib/amd/amd/amq_subr.c +++ b/contrib/amd/amd/amq_subr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: amq_subr.c,v 1.6.2.6 2004/01/19 00:25:55 ezk Exp $ - * $FreeBSD$ + * File: am-utils/amd/amq_subr.c * */ /* @@ -112,8 +110,10 @@ amq_mount_tree_list * amqproc_export_1_svc(voidp argp, struct svc_req *rqstp) { static amq_mount_tree_list aml; + static am_node *mp; - aml.amq_mount_tree_list_val = (amq_mount_tree_p *) &exported_ap[0]; + mp = get_exported_ap(0); + aml.amq_mount_tree_list_val = (amq_mount_tree_p *) ((void *) &mp); aml.amq_mount_tree_list_len = 1; /* XXX */ return &aml; @@ -131,16 +131,14 @@ amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp) switch (opt->as_opt) { case AMOPT_DEBUG: -#ifdef DEBUG if (debug_option(opt->as_str)) -#endif /* DEBUG */ rc = EINVAL; break; case AMOPT_LOGFILE: if (gopt.logfile && opt->as_str && STREQ(gopt.logfile, opt->as_str)) { - if (switch_to_logfile(opt->as_str, orig_umask)) + if (switch_to_logfile(opt->as_str, orig_umask, 0)) rc = EINVAL; } else { rc = EACCES; @@ -156,8 +154,8 @@ amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp) if (amd_state == Run) { plog(XLOG_INFO, "amq says flush cache"); do_mapc_reload = 0; - flush_nfs_fhandle_cache((fserver *) 0); - flush_srvr_nfs_cache(); + flush_nfs_fhandle_cache((fserver *) NULL); + flush_srvr_nfs_cache((fserver *) NULL); } break; } @@ -169,7 +167,7 @@ amqproc_setopt_1_svc(voidp argp, struct svc_req *rqstp) amq_mount_info_list * amqproc_getmntfs_1_svc(voidp argp, struct svc_req *rqstp) { - return (amq_mount_info_list *) ((void *)&mfhead); /* XXX */ + return (amq_mount_info_list *) ((void *)&mfhead); /* XXX */ } @@ -194,6 +192,64 @@ amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp) } +/* + * Process PAWD string of remote pawd tool. + * + * We repeat the resolution of the string until the resolved string resolves + * to itself. This ensures that we follow path resolutions through all + * possible Amd mount points until we reach some sort of convergence. To + * prevent possible infinite loops, we break out of this loop if the strings + * do not converge after MAX_PAWD_TRIES times. + */ +amq_string * +amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp) +{ + static amq_string res; +#define MAX_PAWD_TRIES 10 + int index, len, maxagain = MAX_PAWD_TRIES; + am_node *mp; + char *mountpoint; + char *dir = *(char **) argp; + static char tmp_buf[MAXPATHLEN]; + char prev_buf[MAXPATHLEN]; + + tmp_buf[0] = prev_buf[0] = '\0'; /* default is empty string: no match */ + do { + for (mp = get_first_exported_ap(&index); + mp; + mp = get_next_exported_ap(&index)) { + if (STREQ(mp->am_mnt->mf_ops->fs_type, "toplvl")) + continue; + if (STREQ(mp->am_mnt->mf_ops->fs_type, "auto")) + continue; + mountpoint = (mp->am_link ? mp->am_link : mp->am_mnt->mf_mount); + len = strlen(mountpoint); + if (len == 0) + continue; + if (!NSTREQ(mountpoint, dir, len)) + continue; + if (dir[len] != '\0' && dir[len] != '/') + continue; + xstrlcpy(tmp_buf, mp->am_path, sizeof(tmp_buf)); + xstrlcat(tmp_buf, &dir[len], sizeof(tmp_buf)); + break; + } /* end of "for" loop */ + /* once tmp_buf and prev_buf are equal, break out of "do" loop */ + if (STREQ(tmp_buf, prev_buf)) + break; + else + xstrlcpy(prev_buf, tmp_buf, sizeof(prev_buf)); + } while (--maxagain); + /* check if we couldn't resolve the string after MAX_PAWD_TRIES times */ + if (maxagain <= 0) + plog(XLOG_WARNING, "path \"%s\" did not resolve after %d tries", + tmp_buf, MAX_PAWD_TRIES); + + res = tmp_buf; + return &res; +} + + /* * XDR routines. */ @@ -202,7 +258,7 @@ amqproc_getpid_1_svc(voidp argp, struct svc_req *rqstp) bool_t xdr_amq_setopt(XDR *xdrs, amq_setopt *objp) { - if (!xdr_enum(xdrs, (enum_t *) & objp->as_opt)) { + if (!xdr_enum(xdrs, (enum_t *) ((voidp) &objp->as_opt))) { return (FALSE); } if (!xdr_string(xdrs, &objp->as_str, AMQ_STRLEN)) { @@ -267,10 +323,16 @@ xdr_amq_mount_subtree(XDR *xdrs, amq_mount_tree *objp) if (!xdr_amq_mount_tree_node(xdrs, objp)) { return (FALSE); } - if (!xdr_pointer(xdrs, (char **) &mp->am_osib, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { + if (!xdr_pointer(xdrs, + (char **) ((voidp) &mp->am_osib), + sizeof(amq_mount_tree), + (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { return (FALSE); } - if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { + if (!xdr_pointer(xdrs, + (char **) ((voidp) &mp->am_child), + sizeof(amq_mount_tree), + (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { return (FALSE); } return (TRUE); @@ -281,15 +343,21 @@ bool_t xdr_amq_mount_tree(XDR *xdrs, amq_mount_tree *objp) { am_node *mp = (am_node *) objp; - am_node *mnil = 0; + am_node *mnil = NULL; if (!xdr_amq_mount_tree_node(xdrs, objp)) { return (FALSE); } - if (!xdr_pointer(xdrs, (char **) ((void *)&mnil), sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { + if (!xdr_pointer(xdrs, + (char **) ((voidp) &mnil), + sizeof(amq_mount_tree), + (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { return (FALSE); } - if (!xdr_pointer(xdrs, (char **) &mp->am_child, sizeof(amq_mount_tree), (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { + if (!xdr_pointer(xdrs, + (char **) ((voidp) &mp->am_child), + sizeof(amq_mount_tree), + (XDRPROC_T_TYPE) xdr_amq_mount_subtree)) { return (FALSE); } return (TRUE); @@ -333,7 +401,7 @@ bool_t xdr_amq_mount_tree_list(XDR *xdrs, amq_mount_tree_list *objp) { if (!xdr_array(xdrs, - (char **) &objp->amq_mount_tree_list_val, + (char **) ((voidp) &objp->amq_mount_tree_list_val), (u_int *) &objp->amq_mount_tree_list_len, ~0, sizeof(amq_mount_tree_p), @@ -355,7 +423,7 @@ xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead) u_int len = 0; for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) { - if (!(mf->mf_ops->fs_flags & FS_AMQINFO)) + if (!(mf->mf_fsflags & FS_AMQINFO)) continue; len++; } @@ -366,7 +434,7 @@ xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead) */ for (mf = AM_LAST(mntfs, qhead); mf != HEAD(mntfs, qhead); mf = PREV(mntfs, mf)) { int up; - if (!(mf->mf_ops->fs_flags & FS_AMQINFO)) + if (!(mf->mf_fsflags & FS_AMQINFO)) continue; if (!xdr_amq_string(xdrs, &mf->mf_ops->fs_type)) { @@ -387,20 +455,12 @@ xdr_amq_mount_info_qelem(XDR *xdrs, qelem *qhead) if (!xdr_int(xdrs, &mf->mf_refc)) { return (FALSE); } - if (mf->mf_server->fs_flags & FSF_ERROR) + if (FSRV_ERROR(mf->mf_server) || FSRV_ISDOWN(mf->mf_server)) up = 0; + else if (FSRV_ISUP(mf->mf_server)) + up = 1; else - switch (mf->mf_server->fs_flags & (FSF_DOWN | FSF_VALID)) { - case FSF_DOWN | FSF_VALID: - up = 0; - break; - case FSF_VALID: - up = 1; - break; - default: - up = -1; - break; - } + up = -1; if (!xdr_int(xdrs, &up)) { return (FALSE); } diff --git a/contrib/amd/amd/get_args.c b/contrib/amd/amd/get_args.c index e5c3edf09359..12a7d07efd59 100644 --- a/contrib/amd/amd/get_args.c +++ b/contrib/amd/amd/get_args.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: get_args.c,v 1.7.2.6 2004/01/06 03:15:16 ezk Exp $ - * $FreeBSD$ + * File: am-utils/amd/get_args.c * */ @@ -56,17 +54,12 @@ /* include auto-generated version file */ #include -char *conf_file = "/etc/amd.conf"; /* default amd configuration file */ +char *amu_conf_file = "/etc/amd.conf"; /* default amd configuration file */ char *conf_tag = NULL; /* default conf file tags to use */ int usage = 0; int use_conf_file = 0; /* default don't use amd.conf file */ char *mnttab_file_name = NULL; /* symbol must be available always */ -#if 0 -#ifdef DEBUG -int debug_flags = D_AMQ /* Register AMQ */ - | D_DAEMON; /* Enter daemon mode */ -#endif /* DEBUG */ -#endif + /* * Return the version string (dynamic buffer) @@ -74,48 +67,61 @@ int debug_flags = D_AMQ /* Register AMQ */ char * get_version_string(void) { - static char *vers = NULL; + char *vers = NULL; char tmpbuf[1024]; char *wire_buf; int wire_buf_len = 0; + size_t len; /* max allocated length (to avoid buf overflow) */ - /* first get dynamic string listing all known networks */ + /* + * First get dynamic string listing all known networks. + * This could be a long list, if host has lots of interfaces. + */ wire_buf = print_wires(); if (wire_buf) wire_buf_len = strlen(wire_buf); - vers = xmalloc(2048 + wire_buf_len); - sprintf(vers, "%s\n%s\n%s\n%s\n", - "Copyright (c) 1997-2004 Erez Zadok", - "Copyright (c) 1990 Jan-Simon Pendry", - "Copyright (c) 1990 Imperial College of Science, Technology & Medicine", - "Copyright (c) 1990 The Regents of the University of California."); - sprintf(tmpbuf, "%s version %s (build %d).\n", - PACKAGE, VERSION, AMU_BUILD_VERSION); - strcat(vers, tmpbuf); - sprintf(tmpbuf, "Built by %s@%s on date %s.\n", - USER_NAME, HOST_NAME, CONFIG_DATE); - strcat(vers, tmpbuf); - sprintf(tmpbuf, "cpu=%s (%s-endian), arch=%s, karch=%s.\n", - cpu, endian, gopt.arch, gopt.karch); - strcat(vers, tmpbuf); - sprintf(tmpbuf, "full_os=%s, os=%s, osver=%s, vendor=%s.\n", - gopt.op_sys_full, gopt.op_sys, gopt.op_sys_ver, gopt.op_sys_vendor); - strcat(vers, tmpbuf); + len = 2048 + wire_buf_len; + vers = xmalloc(len); + xsnprintf(vers, len, "%s\n%s\n%s\n%s\n", + "Copyright (c) 1997-2006 Erez Zadok", + "Copyright (c) 1990 Jan-Simon Pendry", + "Copyright (c) 1990 Imperial College of Science, Technology & Medicine", + "Copyright (c) 1990 The Regents of the University of California."); + xsnprintf(tmpbuf, sizeof(tmpbuf), "%s version %s (build %d).\n", + PACKAGE_NAME, PACKAGE_VERSION, AMU_BUILD_VERSION); + strlcat(vers, tmpbuf, len); + xsnprintf(tmpbuf, sizeof(tmpbuf), "Report bugs to %s.\n", PACKAGE_BUGREPORT); + strlcat(vers, tmpbuf, len); + xsnprintf(tmpbuf, sizeof(tmpbuf), "Configured by %s@%s on date %s.\n", + USER_NAME, HOST_NAME, CONFIG_DATE); + strlcat(vers, tmpbuf, len); + xsnprintf(tmpbuf, sizeof(tmpbuf), "Built by %s@%s on date %s.\n", + BUILD_USER, BUILD_HOST, BUILD_DATE); + strlcat(vers, tmpbuf, len); + xsnprintf(tmpbuf, sizeof(tmpbuf), "cpu=%s (%s-endian), arch=%s, karch=%s.\n", + cpu, endian, gopt.arch, gopt.karch); + strlcat(vers, tmpbuf, len); + xsnprintf(tmpbuf, sizeof(tmpbuf), "full_os=%s, os=%s, osver=%s, vendor=%s, distro=%s.\n", + gopt.op_sys_full, gopt.op_sys, gopt.op_sys_ver, gopt.op_sys_vendor, DISTRO_NAME); + strlcat(vers, tmpbuf, len); + xsnprintf(tmpbuf, sizeof(tmpbuf), "domain=%s, host=%s, hostd=%s.\n", + hostdomain, am_get_hostname(), hostd); + strlcat(vers, tmpbuf, len); - strcat(vers, "Map support for: "); - mapc_showtypes(tmpbuf); - strcat(vers, tmpbuf); - strcat(vers, ".\nAMFS: "); - ops_showamfstypes(tmpbuf); - strcat(vers, tmpbuf); - strcat(vers, ".\nFS: "); - ops_showfstypes(tmpbuf); - strcat(vers, tmpbuf); + strlcat(vers, "Map support for: ", len); + mapc_showtypes(tmpbuf, sizeof(tmpbuf)); + strlcat(vers, tmpbuf, len); + strlcat(vers, ".\nAMFS: ", len); + ops_showamfstypes(tmpbuf, sizeof(tmpbuf)); + strlcat(vers, tmpbuf, len); + strlcat(vers, ", inherit.\nFS: ", len); /* hack: "show" that we support type:=inherit */ + ops_showfstypes(tmpbuf, sizeof(tmpbuf)); + strlcat(vers, tmpbuf, len); /* append list of networks if available */ if (wire_buf) { - strcat(vers, wire_buf); + strlcat(vers, wire_buf, len); XFREE(wire_buf); } @@ -123,13 +129,48 @@ get_version_string(void) } +static void +show_usage(void) +{ + fprintf(stderr, + "Usage: %s [-nprvHS] [-a mount_point] [-c cache_time] [-d domain]\n\ +\t[-k kernel_arch] [-l logfile%s\n\ +\t[-t timeout.retrans] [-w wait_timeout] [-A arch] [-C cluster_name]\n\ +\t[-o op_sys_ver] [-O op_sys_name]\n\ +\t[-F conf_file] [-T conf_tag]", am_get_progname(), +#ifdef HAVE_SYSLOG +# ifdef LOG_DAEMON + "|\"syslog[:facility]\"]" +# else /* not LOG_DAEMON */ + "|\"syslog\"]" +# endif /* not LOG_DAEMON */ +#else /* not HAVE_SYSLOG */ + "]" +#endif /* not HAVE_SYSLOG */ + ); + +#ifdef HAVE_MAP_NIS + fputs(" [-y nis-domain]\n", stderr); +#else /* not HAVE_MAP_NIS */ + fputc('\n', stderr); +#endif /* HAVE_MAP_NIS */ + + show_opts('x', xlog_opt); +#ifdef DEBUG + show_opts('D', dbg_opt); +#endif /* DEBUG */ + fprintf(stderr, "\t[directory mapname [-map_options]] ...\n"); +} + + void get_args(int argc, char *argv[]) { - int opt_ch; + int opt_ch, i; FILE *fp = stdin; - char getopt_arguments[] = "+nprvSa:c:d:k:l:o:t:w:x:y:C:D:F:T:O:H"; + char getopt_arguments[] = "+nprvSa:c:d:k:l:o:t:w:x:y:C:D:F:T:O:HA:"; char *getopt_args; + int print_version = 0; /* 1 means we should print version info */ #ifdef HAVE_GNU_GETOPT getopt_args = getopt_arguments; @@ -188,24 +229,30 @@ get_args(int argc, char *argv[]) break; case 't': - /* timeo.retrans */ + /* timeo.retrans (also affects toplvl mounts) */ { char *dot = strchr(optarg, '.'); + int i; if (dot) *dot = '\0'; if (*optarg) { - gopt.amfs_auto_timeo = atoi(optarg); + for (i=0; i= 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 +# ifdef MNT2_NFS_OPT_RESVPORT /* Verify that the request comes from a reserved port */ - if ((ntohs(sinp->sin_port) >= IPPORT_RESERVED) && + 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, sinp->sin_addr.s_addr), + inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr), ntohs(sinp->sin_port)); return; } -#endif /* MNT2_NFS_OPT_RESVPORT */ +# endif /* MNT2_NFS_OPT_RESVPORT */ /* if the address does not match, ignore the request */ - if (sinp->sin_addr.s_addr && sinp->sin_addr.s_addr != myipaddr.s_addr) { - plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s", - inet_dquad(dq, sinp->sin_addr.s_addr), - ntohs(sinp->sin_port), - inet_dquad(dq2, myipaddr.s_addr)); - return; + 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 */ - nfs_program_2_transp = NULL; + current_transp = NULL; switch (rqstp->rq_proc) { @@ -159,7 +187,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp) * be stored in the am_node structure and later used for * quick_reply(). */ - nfs_program_2_transp = transp; + current_transp = transp; break; case NFSPROC_READLINK: @@ -257,7 +285,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp) } result = (*local) (&argument, rqstp); - nfs_program_2_transp = NULL; + current_transp = NULL; if (result != NULL && !svc_sendreply(transp, (XDRPROC_T_TYPE) xdr_result, diff --git a/contrib/amd/amd/ops_pcfs.c b/contrib/amd/amd/ops_pcfs.c index 5552c4302cd1..527dc926ca77 100644 --- a/contrib/amd/amd/ops_pcfs.c +++ b/contrib/amd/amd/ops_pcfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: ops_pcfs.c,v 1.3.2.5 2004/01/06 03:15:16 ezk Exp $ - * $FreeBSD$ + * File: am-utils/amd/ops_pcfs.c * */ @@ -55,8 +53,8 @@ /* forward definitions */ static char *pcfs_match(am_opts *fo); -static int pcfs_fmount(mntfs *mf); -static int pcfs_fumount(mntfs *mf); +static int pcfs_mount(am_node *am, mntfs *mf); +static int pcfs_umount(am_node *am, mntfs *mf); /* * Ops structure @@ -66,17 +64,20 @@ am_ops pcfs_ops = "pcfs", pcfs_match, 0, /* pcfs_init */ - amfs_auto_fmount, - pcfs_fmount, - amfs_auto_fumount, - pcfs_fumount, - amfs_error_lookuppn, + pcfs_mount, + pcfs_umount, + amfs_error_lookup_child, + amfs_error_mount_child, amfs_error_readdir, 0, /* pcfs_readlink */ 0, /* pcfs_mounted */ 0, /* pcfs_umounted */ - find_amfs_auto_srvr, - FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO + amfs_generic_find_srvr, + 0, /* pcfs_get_wchan */ + FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */ +#ifdef HAVE_FS_AUTOFS + AUTOFS_PCFS_FS_FLAGS, +#endif /* HAVE_FS_AUTOFS */ }; @@ -91,9 +92,7 @@ pcfs_match(am_opts *fo) plog(XLOG_USER, "pcfs: no source device specified"); return 0; } -#ifdef DEBUG dlog("PCFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs); -#endif /* DEBUG */ /* * Determine magic cookie to put in mtab @@ -103,11 +102,17 @@ pcfs_match(am_opts *fo) static int -mount_pcfs(char *dir, char *fs_name, char *opts) +mount_pcfs(char *mntdir, char *fs_name, char *opts, int on_autofs) { pcfs_args_t pcfs_args; mntent_t mnt; int flags; +#if defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) + int mask; +#endif /* defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) */ +#if defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) + char *str; +#endif /* defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) */ /* * Figure out the name of the file system type. @@ -120,12 +125,18 @@ mount_pcfs(char *dir, char *fs_name, char *opts) * Fill in the mount structure */ memset((voidp) &mnt, 0, sizeof(mnt)); - mnt.mnt_dir = dir; + mnt.mnt_dir = mntdir; mnt.mnt_fsname = fs_name; mnt.mnt_type = MNTTAB_TYPE_PCFS; mnt.mnt_opts = opts; flags = compute_mount_flags(&mnt); +#ifdef HAVE_FS_AUTOFS + if (on_autofs) + flags |= autofs_compute_mount_flags(&mnt); +#endif /* HAVE_FS_AUTOFS */ + if (amuDebug(D_TRACE)) + plog(XLOG_DEBUG, "mount_pcfs: flags=0x%x", (u_int) flags); #ifdef HAVE_PCFS_ARGS_T_FSPEC pcfs_args.fspec = fs_name; @@ -133,18 +144,46 @@ mount_pcfs(char *dir, char *fs_name, char *opts) #ifdef HAVE_PCFS_ARGS_T_MASK pcfs_args.mask = 0777; /* this may be the msdos file modes */ + if ((mask = hasmntval(&mnt, MNTTAB_OPT_MASK)) > 0) + pcfs_args.mask = mask; + if (amuDebug(D_TRACE)) + plog(XLOG_DEBUG, "mount_pcfs: mask=%o (octal)", (u_int) pcfs_args.mask); #endif /* HAVE_PCFS_ARGS_T_MASK */ #ifdef HAVE_PCFS_ARGS_T_DIRMASK - pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */ + pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */ + if ((mask = hasmntval(&mnt, MNTTAB_OPT_DIRMASK)) > 0) + pcfs_args.dirmask = mask; + if (amuDebug(D_TRACE)) + plog(XLOG_DEBUG, "mount_pcfs: dirmask=%o (octal)", (u_int) pcfs_args.dirmask); #endif /* HAVE_PCFS_ARGS_T_DIRMASK */ #ifdef HAVE_PCFS_ARGS_T_UID - pcfs_args.uid = 0; /* root */ + pcfs_args.uid = 0; /* default to root */ + if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) { + struct passwd *pw; + if ((pw = getpwnam(str)) != NULL) + pcfs_args.uid = pw->pw_uid; + else /* maybe used passed a UID number, not user name */ + pcfs_args.uid = atoi(str); /* atoi returns '0' if it failed */ + XFREE(str); + } + if (amuDebug(D_TRACE)) + plog(XLOG_DEBUG, "mount_pcfs: uid=%d", (int) pcfs_args.uid); #endif /* HAVE_PCFS_ARGS_T_UID */ #ifdef HAVE_PCFS_ARGS_T_GID - pcfs_args.gid = 0; /* wheel */ + pcfs_args.gid = 0; /* default to wheel/root group */ + if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) { + struct group *gr; + if ((gr = getgrnam(str)) != NULL) + pcfs_args.gid = gr->gr_gid; + else /* maybe used passed a GID number, not group name */ + pcfs_args.gid = atoi(str); /* atoi returns '0' if it failed */ + XFREE(str); + } + if (amuDebug(D_TRACE)) + plog(XLOG_DEBUG, "mount_pcfs: gid=%d", (int) pcfs_args.gid); #endif /* HAVE_PCFS_ARGS_T_GID */ #ifdef HAVE_PCFS_ARGS_T_SECONDSWEST @@ -157,16 +196,17 @@ mount_pcfs(char *dir, char *fs_name, char *opts) /* * Call generic mount routine */ - return mount_fs(&mnt, flags, (caddr_t) & pcfs_args, 0, type, 0, NULL, mnttab_file_name); + return mount_fs(&mnt, flags, (caddr_t) & pcfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs); } static int -pcfs_fmount(mntfs *mf) +pcfs_mount(am_node *am, mntfs *mf) { + int on_autofs = mf->mf_flags & MFF_ON_AUTOFS; int error; - error = mount_pcfs(mf->mf_mount, mf->mf_info, mf->mf_mopts); + error = mount_pcfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs); if (error) { errno = error; plog(XLOG_ERROR, "mount_pcfs: %m"); @@ -178,7 +218,9 @@ pcfs_fmount(mntfs *mf) static int -pcfs_fumount(mntfs *mf) +pcfs_umount(am_node *am, mntfs *mf) { - return UMOUNT_FS(mf->mf_mount, mnttab_file_name); + int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0; + + return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags); } diff --git a/contrib/amd/amd/srvr_nfs.c b/contrib/amd/amd/srvr_nfs.c index 67d1724707fb..0c74a658e5ee 100644 --- a/contrib/amd/amd/srvr_nfs.c +++ b/contrib/amd/amd/srvr_nfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: srvr_nfs.c,v 1.7.2.11 2004/01/06 03:15:16 ezk Exp $ - * $FreeBSD$ + * File: am-utils/amd/srvr_nfs.c * */ @@ -73,8 +71,6 @@ */ #endif /* (FAST_NFS_PING * MAX_ALLOWED_PINGS) >= ALLOWED_MOUNT_TIME */ -#define NPXID_ALLOC(struct ) (++np_xid) - /* structures and typedefs */ typedef struct nfs_private { u_short np_mountd; /* Mount daemon port number */ @@ -89,9 +85,16 @@ typedef struct nfs_private { qelem nfs_srvr_list = {&nfs_srvr_list, &nfs_srvr_list}; /* statics */ -static int np_xid; /* For NFS pings */ -static int ping_len; -static char ping_buf[sizeof(struct rpc_msg) + 32]; +static int global_xid; /* For NFS pings */ +#define XID_ALLOC() (++global_xid) + +#ifdef HAVE_FS_NFS3 +# define NUM_NFS_VERS 2 +#else /* not HAVE_FS_NFS3 */ +# define NUM_NFS_VERS 1 +#endif /* not HAVE_FS_NFS3 */ +static int ping_len[NUM_NFS_VERS]; +static char ping_buf[NUM_NFS_VERS][sizeof(struct rpc_msg) + 32]; #if defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) /* @@ -100,6 +103,8 @@ static char ping_buf[sizeof(struct rpc_msg) + 32]; * Note that Solaris 8 and newer NetBSD systems are switching to UDP first, * so this order may have to be adjusted for Amd in the future once more * vendors make that change. -Erez 11/24/2000 + * + * Or we might simply make this is a platform-specific order. -Ion 09/13/2003 */ static char *protocols[] = { "tcp", "udp", NULL }; #endif /* defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */ @@ -108,20 +113,21 @@ static char *protocols[] = { "tcp", "udp", NULL }; static void nfs_keepalive(voidp); - /* - * Flush any cached data + * Flush cached data for an fserver (or for all, if fs==NULL) */ void -flush_srvr_nfs_cache(void) +flush_srvr_nfs_cache(fserver *fs) { - fserver *fs = 0; + fserver *fs2 = NULL; - ITER(fs, fserver, &nfs_srvr_list) { - nfs_private *np = (nfs_private *) fs->fs_private; - if (np) { - np->np_mountd_inval = TRUE; - np->np_error = -1; + ITER(fs2, fserver, &nfs_srvr_list) { + if (fs == NULL || fs == fs2) { + nfs_private *np = (nfs_private *) fs2->fs_private; + if (np) { + np->np_mountd_inval = TRUE; + np->np_error = -1; + } } } } @@ -131,7 +137,7 @@ flush_srvr_nfs_cache(void) * Startup the NFS ping for a particular version. */ static void -start_ping(u_long nfs_version) +create_ping_payload(u_long nfs_version) { XDR ping_xdr; struct rpc_msg ping_msg; @@ -141,16 +147,16 @@ start_ping(u_long nfs_version) */ if (nfs_version == 0) { nfs_version = NFS_VERSION; - plog(XLOG_WARNING, "start_ping: nfs_version = 0 fixed"); - } - plog(XLOG_INFO, "start_ping: nfs_version: %d", (int) nfs_version); + plog(XLOG_WARNING, "create_ping_payload: nfs_version = 0, changed to 2"); + } else + plog(XLOG_INFO, "create_ping_payload: nfs_version: %d", (int) nfs_version); rpc_msg_init(&ping_msg, NFS_PROGRAM, nfs_version, NFSPROC_NULL); /* * Create an XDR endpoint */ - xdrmem_create(&ping_xdr, ping_buf, sizeof(ping_buf), XDR_ENCODE); + xdrmem_create(&ping_xdr, ping_buf[nfs_version - NFS_VERSION], sizeof(ping_buf[0]), XDR_ENCODE); /* * Create the NFS ping message @@ -162,7 +168,7 @@ start_ping(u_long nfs_version) /* * Find out how long it is */ - ping_len = xdr_getpos(&ping_xdr); + ping_len[nfs_version - NFS_VERSION] = xdr_getpos(&ping_xdr); /* * Destroy the XDR endpoint - we don't need it anymore @@ -184,7 +190,7 @@ got_portmap(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, * Find which fileserver we are talking about */ ITER(fs, fserver, &nfs_srvr_list) - if (fs == fs2) + if (fs == fs2) break; if (fs == fs2) { @@ -193,9 +199,7 @@ got_portmap(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, nfs_private *np = (nfs_private *) fs->fs_private; if (!error && port) { -#ifdef DEBUG dlog("got port (%d) for mountd on %s", (int) port, fs->fs_host); -#endif /* DEBUG */ /* * Grab the port number. Portmap sends back * an u_long in native ordering, so it @@ -206,10 +210,8 @@ got_portmap(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, np->np_mountd_inval = FALSE; np->np_error = 0; } else { -#ifdef DEBUG dlog("Error fetching port for mountd on %s", fs->fs_host); dlog("\t error=%d, port=%d", error, (int) port); -#endif /* DEBUG */ /* * Almost certainly no mountd running on remote host */ @@ -219,13 +221,9 @@ got_portmap(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, if (fs->fs_flags & FSF_WANT) wakeup_srvr(fs); } else if (done) { -#ifdef DEBUG dlog("Got portmap for old port request"); -#endif /* DEBUG */ } else { -#ifdef DEBUG dlog("portmap request timed out"); -#endif /* DEBUG */ } } @@ -259,7 +257,7 @@ call_portmap(fserver *fs, AUTH *auth, u_long prog, u_long vers, u_long prot) memset((voidp) &sin, 0, sizeof(sin)); sin = *fs->fs_ip; sin.sin_port = htons(PMAPPORT); - error = fwd_packet(RPC_XID_PORTMAP, (voidp) iobuf, len, + error = fwd_packet(RPC_XID_PORTMAP, iobuf, len, &sin, &sin, (voidp) fs, got_portmap); } else { error = -len; @@ -275,6 +273,12 @@ recompute_portmap(fserver *fs) int error; u_long mnt_version; + /* + * No portmap calls for pure WebNFS servers. + */ + if (fs->fs_flags & FSF_WEBNFS) + return; + if (nfs_auth) error = 0; else @@ -289,10 +293,11 @@ recompute_portmap(fserver *fs) if (fs->fs_version == 0) plog(XLOG_WARNING, "recompute_portmap: nfs_version = 0 fixed"); - plog(XLOG_INFO, "recompute_portmap: NFS version %d", (int) fs->fs_version); + plog(XLOG_INFO, "recompute_portmap: NFS version %d on %s", + (int) fs->fs_version, fs->fs_host); #ifdef HAVE_FS_NFS3 if (fs->fs_version == NFS_VERSION3) - mnt_version = MOUNTVERS3; + mnt_version = AM_MOUNTVERS3; else #endif /* HAVE_FS_NFS3 */ mnt_version = MOUNTVERS; @@ -302,19 +307,61 @@ recompute_portmap(fserver *fs) } +int +get_mountd_port(fserver *fs, u_short *port, wchan_t wchan) +{ + int error = -1; + if (FSRV_ISDOWN(fs)) + return EWOULDBLOCK; + + if (FSRV_ISUP(fs)) { + nfs_private *np = (nfs_private *) fs->fs_private; + if (np->np_error == 0) { + *port = np->np_mountd; + error = 0; + } else { + error = np->np_error; + } + /* + * Now go get the port mapping again in case it changed. + * Note that it is used even if (np_mountd_inval) + * is True. The flag is used simply as an + * indication that the mountd may be invalid, not + * that it is known to be invalid. + */ + if (np->np_mountd_inval) + recompute_portmap(fs); + else + np->np_mountd_inval = TRUE; + } + if (error < 0 && wchan && !(fs->fs_flags & FSF_WANT)) { + /* + * If a wait channel is supplied, and no + * error has yet occurred, then arrange + * that a wakeup is done on the wait channel, + * whenever a wakeup is done on this fs node. + * Wakeup's are done on the fs node whenever + * it changes state - thus causing control to + * come back here and new, better things to happen. + */ + fs->fs_flags |= FSF_WANT; + sched_task(wakeup_task, wchan, (wchan_t) fs); + } + return error; +} + + /* * This is called when we get a reply to an RPC ping. * The value of id was taken from the nfs_private * structure when the ping was transmitted. */ static void -nfs_pinged(voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, voidp idv, int done) +nfs_keepalive_callback(voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, voidp idv, int done) { - int xid = (long) idv; /* for 64-bit archs */ + int xid = (long) idv; /* cast needed for 64-bit archs */ fserver *fs; -#ifdef DEBUG int found_map = 0; -#endif /* DEBUG */ if (!done) return; @@ -337,19 +384,15 @@ nfs_pinged(voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, } else { if (np->np_ping > 1) srvrlog(fs, "ok"); -#ifdef DEBUG else srvrlog(fs, "starts up"); -#endif /* DEBUG */ fs->fs_flags |= FSF_VALID; } map_flush_srvr(fs); } else { if (fs->fs_flags & FSF_VALID) { -#ifdef DEBUG dlog("file server %s type nfs is still up", fs->fs_host); -#endif /* DEBUG */ } else { if (np->np_ping > 1) srvrlog(fs, "ok"); @@ -366,13 +409,13 @@ nfs_pinged(voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, /* * Update ttl for this server */ - np->np_ttl = clocktime() + + np->np_ttl = clocktime(NULL) + (MAX_ALLOWED_PINGS - 1) * FAST_NFS_PING + fs->fs_pinger - 1; /* * New RPC xid... */ - np->np_xid = NPXID_ALLOC(struct ); + np->np_xid = XID_ALLOC(); /* * Failed pings is zero... @@ -385,17 +428,53 @@ nfs_pinged(voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, if (np->np_mountd_inval) recompute_portmap(fs); -#ifdef DEBUG found_map++; -#endif /* DEBUG */ break; } } -#ifdef DEBUG if (found_map == 0) dlog("Spurious ping packet"); -#endif /* DEBUG */ +} + + +static void +check_fs_addr_change(fserver *fs) +{ + struct hostent *hp = NULL; + struct in_addr ia; + char *old_ipaddr, *new_ipaddr; + + hp = gethostbyname(fs->fs_host); + if (!hp || + hp->h_addrtype != AF_INET || + !STREQ((char *) hp->h_name, fs->fs_host) || + memcmp((voidp) &fs->fs_ip->sin_addr, + (voidp) hp->h_addr, + sizeof(fs->fs_ip->sin_addr)) == 0) + return; + /* if got here: downed server changed IP address */ + old_ipaddr = strdup(inet_ntoa(fs->fs_ip->sin_addr)); + memmove((voidp) &ia, (voidp) hp->h_addr, sizeof(struct in_addr)); + new_ipaddr = inet_ntoa(ia); /* ntoa uses static buf */ + plog(XLOG_WARNING, "EZK: down fileserver %s changed ip: %s -> %s", + fs->fs_host, old_ipaddr, new_ipaddr); + XFREE(old_ipaddr); + /* copy new IP addr */ + memmove((voidp) &fs->fs_ip->sin_addr, + (voidp) hp->h_addr, + sizeof(fs->fs_ip->sin_addr)); + /* XXX: do we need to un/set these flags? */ + fs->fs_flags &= ~FSF_DOWN; + fs->fs_flags |= FSF_VALID | FSF_WANT; + map_flush_srvr(fs); /* XXX: a race with flush_srvr_nfs_cache? */ + flush_srvr_nfs_cache(fs); + fs->fs_flags |= FSF_FORCE_UNMOUNT; + +#if 0 + flush_nfs_fhandle_cache(fs); /* done in caller: nfs_keepalive_timeout */ + /* XXX: need to purge nfs_private so that somehow it will get re-initialized? */ +#endif } @@ -403,7 +482,7 @@ nfs_pinged(voidp pkt, int len, struct sockaddr_in *sp, struct sockaddr_in *tsp, * Called when no ping-reply received */ static void -nfs_timed_out(voidp v) +nfs_keepalive_timeout(voidp v) { fserver *fs = v; nfs_private *np = (nfs_private *) fs->fs_private; @@ -424,11 +503,9 @@ nfs_timed_out(voidp v) /* * If ttl has expired then guess that it is dead */ - if (np->np_ttl < clocktime()) { + if (np->np_ttl < clocktime(NULL)) { int oflags = fs->fs_flags; -#ifdef DEBUG dlog("ttl has expired"); -#endif /* DEBUG */ if ((fs->fs_flags & FSF_DOWN) == 0) { /* * Server was up, but is now down. @@ -442,14 +519,13 @@ nfs_timed_out(voidp v) */ flush_nfs_fhandle_cache(fs); np->np_error = -1; + check_fs_addr_change(fs); /* check if IP addr of fserver changed */ } else { /* * Known to be down */ -#ifdef DEBUG if ((fs->fs_flags & FSF_VALID) == 0) srvrlog(fs, "starts down"); -#endif /* DEBUG */ fs->fs_flags |= FSF_VALID; } if (oflags != fs->fs_flags && (fs->fs_flags & FSF_WANT)) @@ -459,17 +535,15 @@ nfs_timed_out(voidp v) */ np->np_ping = 0; } else { -#ifdef DEBUG if (np->np_ping > 1) dlog("%d pings to %s failed - at most %d allowed", np->np_ping, fs->fs_host, MAX_ALLOWED_PINGS); -#endif /* DEBUG */ } /* * New RPC xid, so any late responses to the previous ping * get ignored... */ - np->np_xid = NPXID_ALLOC(struct ); + np->np_xid = XID_ALLOC(); /* * Run keepalive again @@ -493,19 +567,19 @@ nfs_keepalive(voidp v) * Send an NFS ping to this node */ - if (ping_len == 0) - start_ping(fs->fs_version); + if (ping_len[fs->fs_version - NFS_VERSION] == 0) + create_ping_payload(fs->fs_version); /* * Queue the packet... */ error = fwd_packet(MK_RPC_XID(RPC_XID_NFSPING, np->np_xid), - (voidp) ping_buf, - ping_len, + ping_buf[fs->fs_version - NFS_VERSION], + ping_len[fs->fs_version - NFS_VERSION], fs->fs_ip, (struct sockaddr_in *) 0, - (voidp) ((long) np->np_xid), /* for 64-bit archs */ - nfs_pinged); + (voidp) ((long) np->np_xid), /* cast needed for 64-bit archs */ + nfs_keepalive_callback); /* * See if a hard error occurred @@ -518,7 +592,7 @@ nfs_keepalive(voidp v) np->np_ping = MAX_ALLOWED_PINGS; /* immediately down */ np->np_ttl = (time_t) 0; /* - * This causes an immediate call to nfs_timed_out + * This causes an immediate call to nfs_keepalive_timeout * whenever the server was thought to be up. * See +++ below. */ @@ -526,15 +600,13 @@ nfs_keepalive(voidp v) break; case 0: -#ifdef DEBUG dlog("Sent NFS ping to %s", fs->fs_host); -#endif /* DEBUG */ break; } /* * Back off the ping interval if we are not getting replies and - * the remote system is know to be down. + * the remote system is known to be down. */ switch (fs->fs_flags & (FSF_DOWN | FSF_VALID)) { case FSF_VALID: /* Up */ @@ -551,73 +623,41 @@ nfs_keepalive(voidp v) break; } -#ifdef DEBUG dlog("NFS timeout in %d seconds", fstimeo); -#endif /* DEBUG */ - fs->fs_cid = timeout(fstimeo, nfs_timed_out, (voidp) fs); -} - - -int -nfs_srvr_port(fserver *fs, u_short *port, voidp wchan) -{ - int error = -1; - if ((fs->fs_flags & FSF_VALID) == FSF_VALID) { - if ((fs->fs_flags & FSF_DOWN) == 0) { - nfs_private *np = (nfs_private *) fs->fs_private; - if (np->np_error == 0) { - *port = np->np_mountd; - error = 0; - } else { - error = np->np_error; - } - /* - * Now go get the port mapping again in case it changed. - * Note that it is used even if (np_mountd_inval) - * is True. The flag is used simply as an - * indication that the mountd may be invalid, not - * that it is known to be invalid. - */ - if (np->np_mountd_inval) - recompute_portmap(fs); - else - np->np_mountd_inval = TRUE; - } else { - error = EWOULDBLOCK; - } - } - if (error < 0 && wchan && !(fs->fs_flags & FSF_WANT)) { - /* - * If a wait channel is supplied, and no - * error has yet occurred, then arrange - * that a wakeup is done on the wait channel, - * whenever a wakeup is done on this fs node. - * Wakeup's are done on the fs node whenever - * it changes state - thus causing control to - * come back here and new, better things to happen. - */ - fs->fs_flags |= FSF_WANT; - sched_task(wakeup_task, wchan, (voidp) fs); - } - return error; + fs->fs_cid = timeout(fstimeo, nfs_keepalive_timeout, (voidp) fs); } static void start_nfs_pings(fserver *fs, int pingval) { - if (fs->fs_flags & FSF_PINGING) { -#ifdef DEBUG - dlog("Already running pings to %s", fs->fs_host); -#endif /* DEBUG */ + if (pingval == 0) /* could be because ping mnt option not found */ + pingval = AM_PINGER; + /* if pings haven't been initalized, then init them for first time */ + if (fs->fs_flags & FSF_PING_UNINIT) { + fs->fs_flags &= ~FSF_PING_UNINIT; + plog(XLOG_INFO, "initializing %s's pinger to %d sec", fs->fs_host, pingval); + goto do_pings; + } + + if ((fs->fs_flags & FSF_PINGING) && fs->fs_pinger == pingval) { + dlog("already running pings to %s", fs->fs_host); return; } + /* if got here, then we need to update the ping value */ + plog(XLOG_INFO, "changing %s's ping value from %d%s to %d%s", + fs->fs_host, + fs->fs_pinger, (fs->fs_pinger < 0 ? " (off)" : ""), + pingval, (pingval < 0 ? " (off)" : "")); + do_pings: + fs->fs_pinger = pingval; + if (fs->fs_cid) untimeout(fs->fs_cid); if (pingval < 0) { - srvrlog(fs, "wired up"); + srvrlog(fs, "wired up (pings disabled)"); fs->fs_flags |= FSF_VALID; fs->fs_flags &= ~FSF_DOWN; } else { @@ -634,17 +674,18 @@ fserver * find_nfs_srvr(mntfs *mf) { char *host = mf->mf_fo->opt_rhost; - char *nfs_proto = NULL; fserver *fs; int pingval; mntent_t mnt; nfs_private *np; - struct hostent *hp = 0; - struct sockaddr_in *ip; + struct hostent *hp = NULL; + struct sockaddr_in *ip = NULL; u_long nfs_version = 0; /* default is no version specified */ -#ifdef MNTTAB_OPT_PROTO - char *rfsname = mf->mf_fo->opt_rfs; -#endif /* MNTTAB_OPT_PROTO */ + u_long best_nfs_version = 0; + char *nfs_proto = NULL; /* no IP protocol either */ + int nfs_port = 0; + int nfs_port_opt = 0; + int fserver_is_down = 0; /* * Get ping interval from mount options. @@ -654,49 +695,60 @@ find_nfs_srvr(mntfs *mf) mnt.mnt_opts = mf->mf_mopts; pingval = hasmntval(&mnt, "ping"); - /* - * Get the NFS version from the mount options. This is used - * to decide the highest NFS version to try. - */ + if (mf->mf_flags & MFF_NFS_SCALEDOWN) { + /* + * the server granted us a filehandle, but we were unable to mount it. + * therefore, scale down to NFSv2/UDP and try again. + */ + nfs_version = NFS_VERSION; + nfs_proto = "udp"; + plog(XLOG_WARNING, "find_nfs_srvr: NFS mount failed, trying again with NFSv2/UDP"); + mf->mf_flags &= ~MFF_NFS_SCALEDOWN; + } else { + /* + * Get the NFS version from the mount options. This is used + * to decide the highest NFS version to try. + */ #ifdef MNTTAB_OPT_VERS - nfs_version = hasmntval(&mnt, MNTTAB_OPT_VERS); + nfs_version = hasmntval(&mnt, MNTTAB_OPT_VERS); #endif /* MNTTAB_OPT_VERS */ #ifdef MNTTAB_OPT_PROTO - { - char *proto_opt = hasmnteq(&mnt, MNTTAB_OPT_PROTO); - if (proto_opt) { - char **p; - for (p = protocols; *p; p ++) - if (NSTREQ(proto_opt, *p, strlen(*p))) { - nfs_proto = *p; - break; - } - if (*p == NULL) - plog(XLOG_WARNING, "ignoring unknown protocol option for %s:%s", - host, rfsname); + { + char *proto_opt = hasmnteq(&mnt, MNTTAB_OPT_PROTO); + if (proto_opt) { + char **p; + for (p = protocols; *p; p++) + if (NSTREQ(proto_opt, *p, strlen(*p))) { + nfs_proto = *p; + break; + } + if (*p == NULL) + plog(XLOG_WARNING, "ignoring unknown protocol option for %s:%s", + host, mf->mf_fo->opt_rfs); + } } - } #endif /* MNTTAB_OPT_PROTO */ #ifdef HAVE_NFS_NFSV2_H - /* allow overriding if nfsv2 option is specified in mount options */ - if (hasmntopt(&mnt, "nfsv2")) { - nfs_version = (u_long) 2; /* nullify any ``vers=X'' statements */ - nfs_proto = "udp"; /* nullify any ``proto=tcp'' statements */ - plog(XLOG_WARNING, "found compatiblity option \"nfsv2\": set options vers=2,proto=udp for host %s", host); - } + /* allow overriding if nfsv2 option is specified in mount options */ + if (amu_hasmntopt(&mnt, "nfsv2")) { + nfs_version = NFS_VERSION;/* nullify any ``vers=X'' statements */ + nfs_proto = "udp"; /* nullify any ``proto=tcp'' statements */ + plog(XLOG_WARNING, "found compatibility option \"nfsv2\": set options vers=2,proto=udp for host %s", host); + } #endif /* HAVE_NFS_NFSV2_H */ - /* check if we globally overridden the NFS version/protocol */ - if (gopt.nfs_vers) { - nfs_version = gopt.nfs_vers; - plog(XLOG_INFO, "find_nfs_srvr: force NFS version to %d", - (int) nfs_version); - } - if (gopt.nfs_proto) { - nfs_proto = gopt.nfs_proto; - plog(XLOG_INFO, "find_nfs_srvr: force NFS protocol transport to %s", nfs_proto); + /* check if we've globally overridden the NFS version/protocol */ + if (gopt.nfs_vers) { + nfs_version = gopt.nfs_vers; + plog(XLOG_INFO, "find_nfs_srvr: force NFS version to %d", + (int) nfs_version); + } + if (gopt.nfs_proto) { + nfs_proto = gopt.nfs_proto; + plog(XLOG_INFO, "find_nfs_srvr: force NFS protocol transport to %s", nfs_proto); + } } /* @@ -719,72 +771,148 @@ find_nfs_srvr(mntfs *mf) case AF_INET: ip = ALLOC(struct sockaddr_in); memset((voidp) ip, 0, sizeof(*ip)); + /* as per POSIX, sin_len need not be set (used internally by kernel) */ ip->sin_family = AF_INET; memmove((voidp) &ip->sin_addr, (voidp) hp->h_addr, sizeof(ip->sin_addr)); - - ip->sin_port = htons(NFS_PORT); break; default: - ip = 0; - break; + plog(XLOG_USER, "No IP address for host %s", host); + goto no_dns; } } else { plog(XLOG_USER, "Unknown host: %s", host); - ip = 0; + goto no_dns; } /* - * Get the NFS Version, and verify server is up. Probably no - * longer need to start server down below. + * This may not be the best way to do things, but it really doesn't make + * sense to query a file server which is marked as 'down' for any + * version/proto combination. */ - if (ip) { + ITER(fs, fserver, &nfs_srvr_list) { + if (FSRV_ISDOWN(fs) && + STREQ(host, fs->fs_host)) { + plog(XLOG_WARNING, "fileserver %s is already hung - not running NFS proto/version discovery", host); + fs->fs_refc++; + if (ip) + XFREE(ip); + return fs; + } + } + + /* + * Get the NFS Version, and verify server is up. + * If the client only supports NFSv2, hardcode it but still try to + * contact the remote portmapper to see if the service is running. + */ +#ifndef HAVE_FS_NFS3 + nfs_version = NFS_VERSION; + nfs_proto = "udp"; + plog(XLOG_INFO, "The client supports only NFS(2,udp)"); +#endif /* not HAVE_FS_NFS3 */ + + + if (amu_hasmntopt(&mnt, MNTTAB_OPT_PUBLIC)) { + /* + * Use WebNFS to obtain file handles. + */ + mf->mf_flags |= MFF_WEBNFS; + plog(XLOG_INFO, "%s option used, NOT contacting the portmapper on %s", + MNTTAB_OPT_PUBLIC, host); + /* + * Prefer NFSv3/tcp if the client supports it (cf. RFC 2054, 7). + */ + if (!nfs_version) { #ifdef HAVE_FS_NFS3 + nfs_version = NFS_VERSION3; +#else /* not HAVE_FS_NFS3 */ + nfs_version = NFS_VERSION; +#endif /* not HAVE_FS_NFS3 */ + plog(XLOG_INFO, "No NFS version specified, will use NFSv%d", + (int) nfs_version); + } + if (!nfs_proto) { +#if defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) + nfs_proto = "tcp"; +#else /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */ + nfs_proto = "udp"; +#endif /* not defined(MNTTAB_OPT_PROTO) || defined(HAVE_FS_NFS3) */ + plog(XLOG_INFO, "No NFS protocol transport specified, will use %s", + nfs_proto); + } + } else { /* * Find the best combination of NFS version and protocol. * When given a choice, use the highest available version, * and use TCP over UDP if available. */ - if (nfs_proto) - nfs_version = get_nfs_version(host, ip, nfs_version, nfs_proto); - else { - int best_nfs_version = 0; - int proto_nfs_version; - char **p; + if (check_pmap_up(host, ip)) { + if (nfs_proto) { + best_nfs_version = get_nfs_version(host, ip, nfs_version, nfs_proto); + nfs_port = ip->sin_port; + } +#ifdef MNTTAB_OPT_PROTO + else { + u_int proto_nfs_version; + char **p; - for (p = protocols; *p; p++) { - proto_nfs_version = get_nfs_version(host, ip, nfs_version, *p); + for (p = protocols; *p; p++) { + proto_nfs_version = get_nfs_version(host, ip, nfs_version, *p); - if (proto_nfs_version > best_nfs_version) { - best_nfs_version = proto_nfs_version; - nfs_proto = *p; + if (proto_nfs_version > best_nfs_version) { + best_nfs_version = proto_nfs_version; + nfs_proto = *p; + nfs_port = ip->sin_port; + } } } - nfs_version = best_nfs_version; +#endif /* MNTTAB_OPT_PROTO */ + } else { + plog(XLOG_INFO, "portmapper service not running on %s", host); } - if (!nfs_version) { + /* use the portmapper results only nfs_version is not set yet */ + if (!best_nfs_version) { /* * If the NFS server is down or does not support the portmapper call * (such as certain Novell NFS servers) we mark it as version 2 and we - * let the nfs code deal with the case that is down. If when the - * server comes back up, it can support NFS V.3 and/or TCP, it will + * let the nfs code deal with the case when it is down. If/when the + * server comes back up and it can support NFSv3 and/or TCP, it will * use those. */ - nfs_version = NFS_VERSION; - nfs_proto = "udp"; + if (nfs_version == 0) { + nfs_version = NFS_VERSION; + nfs_proto = "udp"; + } + plog(XLOG_INFO, "NFS service not running on %s", host); + fserver_is_down = 1; + } else { + if (nfs_version == 0) + nfs_version = best_nfs_version; + plog(XLOG_INFO, "Using NFS version %d, protocol %s on host %s", + (int) nfs_version, nfs_proto, host); } -#else /* not HAVE_FS_NFS3 */ - nfs_version = NFS_VERSION; -#endif /* not HAVE_FS_NFS3 */ } - if (!nfs_proto) - nfs_proto = "udp"; + /* + * Determine the NFS port. + * + * A valid "port" mount option overrides anything else. + * If the port has been determined from the portmapper, use that. + * Default to NFS_PORT otherwise (cf. RFC 2054, 3). + */ + nfs_port_opt = hasmntval(&mnt, MNTTAB_OPT_PORT); + if (nfs_port_opt > 0) + nfs_port = htons(nfs_port_opt); + if (!nfs_port) + nfs_port = htons(NFS_PORT); - plog(XLOG_INFO, "Using NFS version %d, protocol %s on host %s", - (int) nfs_version, nfs_proto, host); + dlog("find_nfs_srvr: using port %d for nfs on %s", + (int) ntohs(nfs_port), host); + ip->sin_port = nfs_port; +no_dns: /* * Try to find an existing fs server structure for this host. * Note that differing versions or protocols have their own structures. @@ -796,16 +924,46 @@ find_nfs_srvr(mntfs *mf) nfs_version == fs->fs_version && STREQ(nfs_proto, fs->fs_proto)) { /* - * following if statement from Mike Mitchell - * - * Initialize the ping data if we aren't pinging - * now. The np_ttl and np_ping fields are - * especially important. + * fill in the IP address -- this is only needed + * if there is a chance an IP address will change + * between mounts. + * Mike Mitchell, mcm@unx.sas.com, 09/08/93 + */ + if (hp && fs->fs_ip && + memcmp((voidp) &fs->fs_ip->sin_addr, + (voidp) hp->h_addr, + sizeof(fs->fs_ip->sin_addr)) != 0) { + struct in_addr ia; + char *old_ipaddr, *new_ipaddr; + old_ipaddr = strdup(inet_ntoa(fs->fs_ip->sin_addr)); + memmove((voidp) &ia, (voidp) hp->h_addr, sizeof(struct in_addr)); + new_ipaddr = inet_ntoa(ia); /* ntoa uses static buf */ + plog(XLOG_WARNING, "fileserver %s changed ip: %s -> %s", + fs->fs_host, old_ipaddr, new_ipaddr); + XFREE(old_ipaddr); + flush_nfs_fhandle_cache(fs); + memmove((voidp) &fs->fs_ip->sin_addr, (voidp) hp->h_addr, sizeof(fs->fs_ip->sin_addr)); + } + + /* + * If the new file systems doesn't use WebNFS, the nfs pings may + * try to contact the portmapper. + */ + if (!(mf->mf_flags & MFF_WEBNFS)) + fs->fs_flags &= ~FSF_WEBNFS; + + /* check if pingval needs to be updated/set/reset */ + start_nfs_pings(fs, pingval); + + /* + * Following if statement from Mike Mitchell + * Initialize the ping data if we aren't pinging now. The np_ttl and + * np_ping fields are especially important. */ if (!(fs->fs_flags & FSF_PINGING)) { np = (nfs_private *) fs->fs_private; np->np_mountd_inval = TRUE; - np->np_xid = NPXID_ALLOC(struct ); + np->np_xid = XID_ALLOC(); np->np_error = -1; np->np_ping = 0; /* @@ -813,18 +971,12 @@ find_nfs_srvr(mntfs *mf) * after MAX_ALLOWED_PINGS of the fast variety * have failed. */ - np->np_ttl = MAX_ALLOWED_PINGS * FAST_NFS_PING + clocktime() - 1; + np->np_ttl = MAX_ALLOWED_PINGS * FAST_NFS_PING + clocktime(NULL) - 1; + start_nfs_pings(fs, pingval); + if (fserver_is_down) + fs->fs_flags |= FSF_VALID | FSF_DOWN; } - /* - * fill in the IP address -- this is only needed - * if there is a chance an IP address will change - * between mounts. - * Mike Mitchell, mcm@unx.sas.com, 09/08/93 - */ - if (hp && fs->fs_ip) - memmove((voidp) &fs->fs_ip->sin_addr, (voidp) hp->h_addr, sizeof(fs->fs_ip->sin_addr)); - start_nfs_pings(fs, pingval); fs->fs_refc++; if (ip) XFREE(ip); @@ -853,29 +1005,32 @@ find_nfs_srvr(mntfs *mf) mf->mf_flags |= MFF_ERROR; mf->mf_error = ENOENT; } + if (mf->mf_flags & MFF_WEBNFS) + fs->fs_flags |= FSF_WEBNFS; fs->fs_version = nfs_version; fs->fs_proto = nfs_proto; fs->fs_type = MNTTAB_TYPE_NFS; fs->fs_pinger = AM_PINGER; + fs->fs_flags |= FSF_PING_UNINIT; /* pinger hasn't been initialized */ np = ALLOC(struct nfs_private); memset((voidp) np, 0, sizeof(*np)); np->np_mountd_inval = TRUE; - np->np_xid = NPXID_ALLOC(struct ); + np->np_xid = XID_ALLOC(); np->np_error = -1; /* * Initially the server will be deemed dead after * MAX_ALLOWED_PINGS of the fast variety have failed. */ - np->np_ttl = clocktime() + MAX_ALLOWED_PINGS * FAST_NFS_PING - 1; + np->np_ttl = clocktime(NULL) + MAX_ALLOWED_PINGS * FAST_NFS_PING - 1; fs->fs_private = (voidp) np; fs->fs_prfree = (void (*)(voidp)) free; - if (!(fs->fs_flags & FSF_ERROR)) { - /* - * Start of keepalive timer - */ + if (!FSRV_ERROR(fs)) { + /* start of keepalive timer, first updating pingval */ start_nfs_pings(fs, pingval); + if (fserver_is_down) + fs->fs_flags |= FSF_VALID | FSF_DOWN; } /* diff --git a/contrib/amd/amq/amq.c b/contrib/amd/amq/amq.c index d9828ac74221..2379b6214766 100644 --- a/contrib/amd/amq/amq.c +++ b/contrib/amd/amq/amq.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,32 +36,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: amq.c,v 1.7.2.9 2004/01/06 03:15:16 ezk Exp $ + * File: am-utils/amq/amq.c * */ -#include -__FBSDID("$FreeBSD$"); - /* * Automounter query tool */ -#ifndef lint -char copyright[] = "\ -@(#)Copyright (c) 1997-2004 Erez Zadok\n\ -@(#)Copyright (c) 1990 Jan-Simon Pendry\n\ -@(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\ -@(#)Copyright (c) 1990 The Regents of the University of California.\n\ -@(#)All rights reserved.\n"; -#if __GNUC__ < 2 -static char rcsid[] = "$Id: amq.c,v 1.7.2.9 2004/01/06 03:15:16 ezk Exp $"; -static char sccsid[] = "%W% (Berkeley) %G%"; -#endif /* __GNUC__ < 2 */ -#endif /* not lint */ - #ifdef HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ @@ -118,8 +101,8 @@ show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid) case Full: { - struct tm *tp = localtime((time_t *) &mt->mt_mounttime); - printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", + struct tm *tp = localtime((time_t *) ((voidp) &mt->mt_mounttime)); + printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%04d %02d:%02d:%02d\n", *dwid, *dwid, *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ *twid, *twid, @@ -135,16 +118,16 @@ show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid) mt->mt_readlink, mt->mt_statfs, - tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, tp->tm_mon + 1, tp->tm_mday, + tp->tm_year < 1900 ? tp->tm_year + 1900 : tp->tm_year, tp->tm_hour, tp->tm_min, tp->tm_sec); } break; case Stats: { - struct tm *tp = localtime((time_t *) &mt->mt_mounttime); - printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", + struct tm *tp = localtime((time_t *) ((voidp) &mt->mt_mounttime)); + printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%04d\n", *dwid, *dwid, *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ @@ -155,8 +138,8 @@ show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid) mt->mt_readlink, mt->mt_statfs, - tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year, tp->tm_mon + 1, tp->tm_mday, + tp->tm_year < 1900 ? tp->tm_year + 1900 : tp->tm_year, tp->tm_hour, tp->tm_min, tp->tm_sec); } break; @@ -184,7 +167,7 @@ show_mti(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *twid) * Display a pwd data */ static void -show_pwd(amq_mount_tree *mt, char *path, int *flag) +show_pwd(amq_mount_tree *mt, char *path, size_t l, int *flag) { int len; @@ -192,13 +175,13 @@ show_pwd(amq_mount_tree *mt, char *path, int *flag) len = strlen(mt->mt_mountpoint); if (NSTREQ(path, mt->mt_mountpoint, len) && !STREQ(mt->mt_directory, mt->mt_mountpoint)) { - char buf[MAXPATHLEN+1]; - strcpy(buf, mt->mt_directory); - strcat(buf, &path[len]); - strcpy(path, buf); + char buf[MAXPATHLEN+1]; /* must be same size as 'path' */ + xstrlcpy(buf, mt->mt_directory, sizeof(buf)); + xstrlcat(buf, &path[len], sizeof(buf)); + xstrlcpy(path, buf, l); *flag = 1; } - show_pwd(mt->mt_next, path, flag); + show_pwd(mt->mt_next, path, l, flag); mt = mt->mt_child; } } @@ -221,7 +204,7 @@ show_mt(amq_mount_tree *mt, enum show_opt e, int *mwid, int *dwid, int *pwid) static void show_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, int *dwid, int *twid) { - int i; + u_int i; switch (e) { @@ -254,14 +237,7 @@ show_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, int *dwid, int *twi mi->mi_up > 0 ? "up" : mi->mi_up < 0 ? "starting" : "down"); if (mi->mi_error > 0) { - if (mi->mi_error < sys_nerr) -#ifdef HAVE_STRERROR - printf(" (%s)", strerror(mi->mi_error)); -#else /* not HAVE_STRERROR */ - printf(" (%s)", sys_errlist[mi->mi_error]); -#endif /* not HAVE_STRERROR */ - else - printf(" (Error %d)", mi->mi_error); + printf(" (%s)", strerror(mi->mi_error)); } else if (mi->mi_error < 0) { fputs(" (in progress)", stdout); } @@ -458,7 +434,8 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\ am_get_progname(), server); exit(1); } - memset(&server_addr, 0, sizeof server_addr); + memset(&server_addr, 0, sizeof(server_addr)); + /* as per POSIX, sin_len need not be set (used internally by kernel) */ server_addr.sin_family = AF_INET; if (hp) { memmove((voidp) &server_addr.sin_addr, (voidp) hp->h_addr, @@ -564,7 +541,8 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\ char *wd = getcwd(path, MAXPATHLEN+1); amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt); amq_mount_tree_p mt; - int i, flag; + u_int i; + int flag; if (!wd) { perror("getcwd"); @@ -574,7 +552,7 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\ mt = mlp->amq_mount_tree_list_val[i]; while (1) { flag = 0; - show_pwd(mt, path, &flag); + show_pwd(mt, path, sizeof(path), &flag); if (!flag) { printf("%s\n", path); break; @@ -688,8 +666,9 @@ Usage: %s [-fmpsvwHTU] [-h hostname] [-l log_file|\"syslog\"]\n\ if (mlp) { enum show_opt e = Calc; int mwid = 0, dwid = 0, pwid = 0; + while (e != ShowDone) { - int i; + u_int i; for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { show_mt(mlp->amq_mount_tree_list_val[i], e, &mwid, &dwid, &pwid); diff --git a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h index 24bc9b37fe4e..cf7ba33ee47b 100644 --- a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h +++ b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: nfs_prot_freebsd2.h,v 1.3.2.4 2004/01/06 03:15:19 ezk Exp $ - * $FreeBSD$ + * File: am-utils/conf/nfs_prot/nfs_prot_freebsd2.h * */ diff --git a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h index 27c535db11fa..4e1e84a42f81 100644 --- a/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h +++ b/contrib/amd/conf/nfs_prot/nfs_prot_freebsd3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,8 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * + * File: am-utils/conf/nfs_prot/nfs_prot_freebsd3.h * $Id: nfs_prot_freebsd3.h,v 1.5.2.7 2004/01/06 03:15:19 ezk Exp $ * $FreeBSD$ * @@ -68,6 +68,13 @@ struct nfs_fh3; # include #endif /* HAVE_NFS_NFS_H */ #ifdef HAVE_UFS_UFS_UFSMOUNT_H +# ifdef HAVE_UFS_UFS_EXTATTR_H +/* + * Define a dummy struct ufs_extattr_per_mount, which is used in struct + * ufsmount in . + */ +struct ufs_extattr_per_mount; +# endif /* HAVE_UFS_UFS_EXTATTR_H */ # include #endif /* HAVE_UFS_UFS_UFSMOUNT_H */ @@ -179,22 +186,16 @@ typedef writeargs nfswriteargs; # define MOUNT_NFS3 "nfs" /* is this right? */ # define MNTOPT_NFS3 "nfs" +# ifndef HAVE_XDR_LOOKUP3RES /* - * as of 3.0-RELEASE the nfs_fh3 that is defined in the system headers - * (or the one generated by rpcgen) lacks the proper full definition, - * listed below. A special macro (m4/macros/struct_nfs_fh3.m4) searches - * for this special name before other names. + * FreeBSD uses different field names than are defined on most other + * systems. */ -struct nfs_fh3_freebsd3 { - u_int fh3_length; - union nfs_fh3_u { - struct nfs_fh3_i { - fhandle_t fh3_i; - } nfs_fh3_i; - char data[NFS3_FHSIZE]; - } fh3_u; -}; -typedef struct nfs_fh3_freebsd3 nfs_fh3_freebsd3; +# define AMU_LOOKUP3RES_OK(x) ((x)->LOOKUP3res_u.resok) +# define AMU_LOOKUP3RES_FAIL(x) ((x)->LOOKUP3res_u.resfail) +# define AMU_LOOKUP3RES_FH_LEN(x) (AMU_LOOKUP3RES_OK(x).object.data.data_len) +# define AMU_LOOKUP3RES_FH_DATA(x) (AMU_LOOKUP3RES_OK(x).object.data.data_val) +# endif /* not HAVE_XDR_LOOKUP3RES */ /* since we don't use Am-utils's aux/macros/struct_nfs_fh3.m4, we don't get their special searching. So restore the standard name. */ diff --git a/contrib/amd/fixmount/fixmount.c b/contrib/amd/fixmount/fixmount.c index 3e0078620a4a..c7c69102a55b 100644 --- a/contrib/amd/fixmount/fixmount.c +++ b/contrib/amd/fixmount/fixmount.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: fixmount.c,v 1.5.2.4 2004/01/06 03:15:23 ezk Exp $ - * $FreeBSD$ + * File: am-utils/fixmount/fixmount.c * */ @@ -51,10 +49,6 @@ #define CREATE_TIMEOUT 2 /* seconds */ #define CALL_TIMEOUT 5 /* seconds */ -#ifndef INADDR_NONE -# define INADDR_NONE 0xffffffff -#endif /* not INADDR_NONE */ - /* Constant defs */ #define ALL 1 #define DIRS 2 @@ -121,7 +115,7 @@ is_same_host(char *name1, char *name2, struct in_addr addr2) } else if (!(he = gethostbyname(name1))) { return 0; } else { - strncpy(lasthost, name1, sizeof(lasthost) - 1); + xstrlcpy(lasthost, name1, MAXHOSTNAMELEN); memcpy(&addr1, he->h_addr, sizeof(addr1)); return (addr1.s_addr == addr2.s_addr); } @@ -165,7 +159,7 @@ remove_mount(CLIENT *client, char *host, mountlist ml, int fixit) struct timeval tv; char *pathp = dir_path; - strncpy(dir_path, ml->ml_directory, sizeof(dir_path)); + xstrlcpy(dir_path, ml->ml_directory, sizeof(dir_path)); if (!fixit) { printf("%s: bogus mount %s:%s\n", host, ml->ml_hostname, ml->ml_directory); @@ -327,8 +321,7 @@ main(int argc, char *argv[]) break; case 'h': - strncpy(thishost, optarg, sizeof(thishost)); - thishost[sizeof(thishost) - 1] = '\0'; + xstrlcpy(thishost, optarg, sizeof(thishost)); break; case '?': @@ -368,8 +361,7 @@ main(int argc, char *argv[]) inet_ntoa(thisaddr)); exit(1); } - strncpy(thishost, he->h_name, sizeof(thishost)); - thishost[sizeof(thishost) - 1] = '\0'; + xstrlcpy(thishost, he->h_name, sizeof(thishost)); } else { thisaddr.s_addr = INADDR_NONE; } @@ -498,8 +490,10 @@ inetresport(int ty) struct sockaddr_in addr; int fd; - /* Use internet address family */ - addr.sin_family = AF_INET; + memset(&addr, 0, sizeof(addr)); + /* as per POSIX, sin_len need not be set (used internally by kernel) */ + + addr.sin_family = AF_INET; /* use internet address family */ addr.sin_addr.s_addr = INADDR_ANY; if ((fd = socket(AF_INET, ty, 0)) < 0) return -1; @@ -569,7 +563,8 @@ clnt_create_timeout(char *host, struct timeval *tvp) fprintf(stderr, "can't get address of %s\n", host); return NULL; } - memset(&host_addr, 0, sizeof host_addr); + memset(&host_addr, 0, sizeof(host_addr)); + /* as per POSIX, sin_len need not be set (used internally by kernel) */ host_addr.sin_family = AF_INET; if (hp) { memmove((voidp) &host_addr.sin_addr, (voidp) hp->h_addr, diff --git a/contrib/amd/fsinfo/fsinfo.c b/contrib/amd/fsinfo/fsinfo.c index 21f803828007..e441a47fab4b 100644 --- a/contrib/amd/fsinfo/fsinfo.c +++ b/contrib/amd/fsinfo/fsinfo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -37,8 +37,7 @@ * SUCH DAMAGE. * * - * $Id: fsinfo.c,v 1.5.2.7 2004/05/12 15:54:31 ezk Exp $ - * $FreeBSD$ + * File: am-utils/fsinfo/fsinfo.c * */ @@ -125,7 +124,7 @@ fsi_get_args(int c, char *v[]) break; case 'h': - strncpy(hostname, optarg, sizeof(hostname) - 1); + xstrlcpy(hostname, optarg, sizeof(hostname)); break; case 'e': @@ -157,7 +156,8 @@ fsi_get_args(int c, char *v[]) case 'I': case 'D': case 'U': - sprintf(iptr, "-%c%s ", ch, optarg); + /* sizeof(iptr) is actually that of idvbuf. See declaration above */ + xsnprintf(iptr, sizeof(idvbuf), "-%c%s ", ch, optarg); iptr += strlen(iptr); break; @@ -198,7 +198,7 @@ Usage: %s [-v] [-a autodir] [-h hostname] [-b bootparams] [-d dumpsets]\n\ static char * find_username(void) { - char *u = getlogin(); + const char *u = getlogin(); if (!u) { struct passwd *pw = getpwuid(getuid()); @@ -235,6 +235,7 @@ main(int argc, char *argv[]) perror("gethostname"); exit(1); } + hostname[sizeof(hostname) - 1] = '\0'; /* * Get the username diff --git a/contrib/amd/hlfsd/hlfsd.c b/contrib/amd/hlfsd/hlfsd.c index 17ee61f43b9b..8703f5982c5e 100644 --- a/contrib/amd/hlfsd/hlfsd.c +++ b/contrib/amd/hlfsd/hlfsd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: hlfsd.c,v 1.7.2.9 2004/01/19 00:25:55 ezk Exp $ - * $FreeBSD$ + * File: am-utils/hlfsd/hlfsd.c * * HLFSD was written at Columbia University Computer Science Department, by * Erez Zadok and Alexander Dupuy @@ -86,7 +84,7 @@ char *logfile = DEFAULT_LOGFILE; char *passwdfile = NULL; /* alternate passwd file to use */ char *slinkname = 0; char hostname[MAXHOSTNAMELEN + 1] = "localhost"; -int cache_interval = DEFAULT_CACHE_INTERVAL; +u_int cache_interval = DEFAULT_CACHE_INTERVAL; gid_t hlfs_gid = (gid_t) INVALIDID; int masterpid = 0; int noverify = 0; @@ -122,6 +120,17 @@ usage(void) } +void +fatalerror(char *str) +{ +#define ERRM ": %m" + size_t l = strlen(str) + sizeof(ERRM) - 1; + char *tmp = strnsave(str, l); + xstrlcat(tmp, ERRM, l); + fatal(tmp); +} + + int main(int argc, char *argv[]) { @@ -309,12 +318,12 @@ main(int argc, char *argv[]) *dot = '\0'; orig_umask = umask(0); if (logfile) - switch_to_logfile(logfile, orig_umask); + switch_to_logfile(logfile, orig_umask, 0); -#if defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) - if (debug_flags & D_MTAB) +#ifndef MOUNT_TABLE_ON_FILE + if (amuDebug(D_MTAB)) dlog("-D mtab option ignored"); -#endif /* defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) */ +#endif /* not MOUNT_TABLE_ON_FILE */ /* avoid hanging on other NFS servers if started elsewhere */ if (chdir("/") < 0) @@ -338,8 +347,6 @@ main(int argc, char *argv[]) exit(3); } - clock_valid = 0; /* invalidate logging clock */ - if (!forcefast) { /* make sure mount point exists and is at least mode 555 */ if (stat(dir_name, &stmodes) < 0) @@ -384,7 +391,7 @@ main(int argc, char *argv[]) chmod(alt_spooldir, OPEN_SPOOLMODE); /* create failsafe link to alternate spool directory */ - slinkname[-1] = '/'; /* unsplit dir_name to include link */ + *(slinkname-1) = '/'; /* unsplit dir_name to include link */ if (lstat(dir_name, &stmodes) == 0 && (stmodes.st_mode & S_IFMT) != S_IFLNK) { fprintf(stderr, "%s: failsafe %s not a symlink\n", @@ -405,7 +412,7 @@ main(int argc, char *argv[]) } } - slinkname[-1] = '\0'; /* resplit dir_name */ + *(slinkname-1) = '\0'; /* resplit dir_name */ } /* end of "if (!forcefast) {" */ /* @@ -421,7 +428,7 @@ main(int argc, char *argv[]) #ifdef HAVE_SIGACTION sa.sa_handler = proceed; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGUSR2); sigaction(SIGUSR2, &sa, NULL); @@ -434,7 +441,7 @@ main(int argc, char *argv[]) #ifdef HAVE_SIGACTION sa.sa_handler = reaper; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGCHLD); sigaction(SIGCHLD, &sa, NULL); @@ -442,53 +449,57 @@ main(int argc, char *argv[]) signal(SIGCHLD, reaper); #endif /* not HAVE_SIGACTION */ -#ifdef DEBUG /* - * In the parent, if -D nodaemon (or -D daemon) , we don't need to + * In the parent, if -D daemon, we don't need to * set this signal handler. */ - amuDebug(D_DAEMON) { -#endif /* DEBUG */ - /* XXX: port to use pure svr4 signals */ + if (!amuDebug(D_DAEMON)) { s = -99; while (stoplight != SIGUSR2) { plog(XLOG_INFO, "parent waits for child to setup (stoplight=%d)", stoplight); +#ifdef HAVE_SIGSUSPEND + { + sigset_t mask; + sigemptyset(&mask); + s = sigsuspend(&mask); /* wait for child to set up */ + } +#else /* not HAVE_SIGSUSPEND */ s = sigpause(0); /* wait for child to set up */ +#endif /* not HAVE_SIGSUSPEND */ sleep(1); } -#ifdef DEBUG } -#endif /* DEBUG */ /* * setup options to mount table (/etc/{mtab,mnttab}) entry */ - sprintf(hostpid_fs, "%s:(pid%d)", hostname, masterpid); + xsnprintf(hostpid_fs, sizeof(hostpid_fs), + "%s:(pid%d)", hostname, masterpid); memset((char *) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = dir_name; /* i.e., "/mail" */ mnt.mnt_fsname = hostpid_fs; if (mntopts) { mnt.mnt_opts = mntopts; } else { - strcpy(preopts, default_mntopts); + xstrlcpy(preopts, default_mntopts, sizeof(preopts)); /* * Turn off all kinds of attribute and symlink caches as * much as possible. Also make sure that mount does not * show up to df. */ #ifdef MNTTAB_OPT_INTR - strcat(preopts, ","); - strcat(preopts, MNTTAB_OPT_INTR); + xstrlcat(preopts, ",", sizeof(preopts)); + xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts)); #endif /* MNTTAB_OPT_INTR */ #ifdef MNTTAB_OPT_IGNORE - strcat(preopts, ","); - strcat(preopts, MNTTAB_OPT_IGNORE); + xstrlcat(preopts, ",", sizeof(preopts)); + xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts)); #endif /* MNTTAB_OPT_IGNORE */ #ifdef MNT2_GEN_OPT_CACHE - strcat(preopts, ",nocache"); + xstrlcat(preopts, ",nocache", sizeof(preopts)); #endif /* MNT2_GEN_OPT_CACHE */ #ifdef MNT2_NFS_OPT_SYMTTL - strcat(preopts, ",symttl=0"); + xstrlcat(preopts, ",symttl=0", sizeof(preopts)); #endif /* MNT2_NFS_OPT_SYMTTL */ mnt.mnt_opts = preopts; } @@ -499,11 +510,15 @@ main(int argc, char *argv[]) * If they don't appear to support the either the "ignore" mnttab * option entry, or the "auto" one, set the mount type to "nfs". */ +#ifdef HIDE_MOUNT_TYPE mnt.mnt_type = HIDE_MOUNT_TYPE; +#else /* not HIDE_MOUNT_TYPE */ + mnt.mnt_type = "nfs"; +#endif /* not HIDE_MOUNT_TYPE */ /* some systems don't have a mount type, but a mount flag */ #ifndef HAVE_TRANSPORT_TYPE_TLI - amu_get_myaddress(&localsocket.sin_addr); + amu_get_myaddress(&localsocket.sin_addr, NULL); localsocket.sin_family = AF_INET; localsocket.sin_port = htons(nfsxprt->xp_port); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ @@ -512,11 +527,13 @@ main(int argc, char *argv[]) * Update hostname field. * Make some name prog:pid (i.e., hlfsd:174) for hostname */ - sprintf(progpid_fs, "%s:%d", am_get_progname(), masterpid); + xsnprintf(progpid_fs, sizeof(progpid_fs), + "%s:%d", am_get_progname(), masterpid); /* Most kernels have a name length restriction. */ if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN) - strcpy(progpid_fs + MAXHOSTNAMELEN - 3, ".."); + xstrlcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..", + sizeof(progpid_fs) - MAXHOSTNAMELEN + 3); genflags = compute_mount_flags(&mnt); @@ -524,7 +541,7 @@ main(int argc, char *argv[]) if (retry <= 0) retry = 1; /* XXX */ - memmove(&anh.v2.fhs_fh, root_fhp, sizeof(*root_fhp)); + memmove(&anh.v2, root_fhp, sizeof(*root_fhp)); #ifdef HAVE_TRANSPORT_TYPE_TLI compute_nfs_args(&nfs_args, &mnt, @@ -550,6 +567,7 @@ main(int argc, char *argv[]) compute_nfs_args(&nfs_args, &mnt, genflags, + NULL, &localsocket, NFS_VERSION, /* version 2 */ "udp", /* XXX: shouldn't this be "udp"? */ @@ -565,33 +583,26 @@ main(int argc, char *argv[]) *************************************************************************/ compute_automounter_nfs_args(&nfs_args, &mnt); - clock_valid = 0; /* invalidate logging clock */ - -/* - * The following code could be cleverly ifdef-ed, but I duplicated the - * mount_fs call three times for simplicity and readability. - */ -#ifdef DEBUG /* * For some reason, this mount may have to be done in the background, if I am - * using -D nodebug. I suspect that the actual act of mounting requires + * using -D daemon. I suspect that the actual act of mounting requires * calling to hlfsd itself to invoke one or more of its nfs calls, to stat - * /mail. That means that even if you say -D nodaemon, at least the mount + * /mail. That means that even if you say -D daemon, at least the mount * of hlfsd itself on top of /mail will be done in the background. * The other alternative I have is to run svc_run, but set a special * signal handler to perform the mount in N seconds via some alarm. * -Erez Zadok. */ - if (debug_flags & D_DAEMON) { /* asked for -D daemon */ - plog(XLOG_INFO, "parent NFS mounting hlfsd service points"); - if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0) + if (!amuDebug(D_DAEMON)) { /* Normal case */ + plog(XLOG_INFO, "normal NFS mounting hlfsd service points"); + if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0) fatal("nfsmount: %m"); - } else { /* asked for -D nodaemon */ + } else { /* asked for -D daemon */ if (fork() == 0) { /* child runs mount */ am_set_mypid(); foreground = 0; plog(XLOG_INFO, "child NFS mounting hlfsd service points"); - if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0) { + if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0) { fatal("nfsmount: %m"); } exit(0); /* all went well */ @@ -599,11 +610,6 @@ main(int argc, char *argv[]) plog(XLOG_INFO, "parent waiting 1sec for mount..."); } } -#else /* not DEBUG */ - plog(XLOG_INFO, "normal NFS mounting hlfsd service points"); - if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 2, "udp", mnttab_file_name) < 0) - fatal("nfsmount: %m"); -#endif /* not DEBUG */ #ifdef HAVE_TRANSPORT_TYPE_TLI /* @@ -621,15 +627,14 @@ main(int argc, char *argv[]) printf("%d\n", masterpid); plog(XLOG_INFO, "hlfsd ready to serve"); -#ifdef DEBUG /* - * If asked not to fork a daemon (-D nodaemon), then hlfsd_init() + * If asked not to fork a daemon (-D daemon), then hlfsd_init() * will not run svc_run. We must start svc_run here. */ - dlog("starting no-daemon debugging svc_run"); - amuDebugNo(D_DAEMON) + if (amuDebug(D_DAEMON)) { + plog(XLOG_DEBUG, "starting no-daemon debugging svc_run"); svc_run(); -#endif /* DEBUG */ + } cleanup(0); /* should never happen here */ return (0); /* everything went fine? */ @@ -644,20 +649,16 @@ hlfsd_init(void) struct sigaction sa; #endif /* HAVE_SIGACTION */ - clock_valid = 0; /* invalidate logging clock */ - /* * Initialize file handles. */ plog(XLOG_INFO, "initializing hlfsd file handles"); hlfsd_init_filehandles(); -#ifdef DEBUG /* - * If -D daemon then we must fork. + * If not -D daemon then we must fork. */ - amuDebug(D_DAEMON) -#endif /* DEBUG */ + if (!amuDebug(D_DAEMON)) child = fork(); if (child < 0) @@ -686,7 +687,7 @@ hlfsd_init(void) */ #ifdef HAVE_SIGACTION sa.sa_handler = reload; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGALRM); sigaddset(&(sa.sa_mask), SIGHUP); @@ -702,7 +703,7 @@ hlfsd_init(void) */ #ifdef HAVE_SIGACTION sa.sa_handler = cleanup; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGTERM); sigaction(SIGTERM, &sa, NULL); @@ -715,7 +716,7 @@ hlfsd_init(void) */ #ifdef HAVE_SIGACTION sa.sa_handler = interlock; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGCHLD); sigaction(SIGCHLD, &sa, NULL); @@ -732,7 +733,7 @@ hlfsd_init(void) # else /* not defined(DEBUG) || defined(DEBUG_PRINT) */ sa.sa_handler = SIG_IGN; # endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */ - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGUSR1); sigaction(SIGUSR1, &sa, NULL); @@ -747,17 +748,14 @@ hlfsd_init(void) if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) 0) < 0) fatal("setitimer: %m"); - gettimeofday((struct timeval *) ((void *)&startup), (struct timezone *) 0); + clocktime(&startup); -#ifdef DEBUG /* - * If -D daemon, then start serving here in the child, - * and the parent will exit. But if -D nodaemon, then + * If not -D daemon, then start serving here in the child, + * and the parent will exit. But if -D daemon, then * skip this code and make sure svc_run is entered elsewhere. */ - amuDebug(D_DAEMON) { -#endif /* DEBUG */ - + if (!amuDebug(D_DAEMON)) { /* * Dissociate from the controlling terminal */ @@ -772,9 +770,7 @@ hlfsd_init(void) plog(XLOG_INFO, "starting svc_run"); svc_run(); cleanup(0); /* should never happen, just in case */ -#ifdef DEBUG - } /* end of code that runs iff hlfsd daemonizes */ -#endif /* DEBUG */ + } } @@ -792,8 +788,6 @@ reload(int signum) int child; int status; - clock_valid = 0; /* invalidate logging clock */ - if (getpid() != masterpid) return; @@ -802,7 +796,7 @@ reload(int signum) * can be rotated) */ if (signum == SIGHUP && logfile) - switch_to_logfile(logfile, orig_umask); + switch_to_logfile(logfile, orig_umask, 0); /* * parent performs the reload, while the child continues to serve @@ -845,29 +839,21 @@ cleanup(int signum) struct stat stbuf; int umount_result; - clock_valid = 0; /* invalidate logging clock */ - -#ifdef DEBUG - amuDebug(D_DAEMON) -#endif /* DEBUG */ + if (!amuDebug(D_DAEMON)) { if (getpid() != masterpid) return; -#ifdef DEBUG - amuDebug(D_DAEMON) -#endif /* DEBUG */ if (fork() != 0) { masterpid = 0; am_set_mypid(); return; } + } am_set_mypid(); for (;;) { - while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name)) == EBUSY) { -#ifdef DEBUG + while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name, 0)) == EBUSY) { dlog("cleanup(): umount delaying for 10 seconds"); -#endif /* DEBUG */ sleep(10); } if (stat(dir_name, &stbuf) == 0 && stbuf.st_ino == ROOTID) { @@ -879,19 +865,14 @@ cleanup(int signum) break; } -#ifdef DEBUG - dlog("cleanup(): killing processes and terminating"); - amuDebug(D_DAEMON) -#endif /* DEBUG */ + if (!amuDebug(D_DAEMON)) { + plog(XLOG_INFO, "cleanup(): killing processes and terminating"); kill(masterpid, SIGKILL); - -#ifdef DEBUG - amuDebug(D_DAEMON) -#endif /* DEBUG */ kill(serverpid, SIGKILL); + } plog(XLOG_INFO, "hlfsd terminating with status 0\n"); - exit(0); + _exit(0); } @@ -901,7 +882,7 @@ reaper(int signum) int result; if (wait(&result) == masterpid) { - exit(4); + _exit(4); } } @@ -932,7 +913,7 @@ fatal(char *mess) if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM)) fprintf(stderr, "%s: %s\n", am_get_progname(), mess); else { - strcpy(lessmess, mess); + xstrlcpy(lessmess, mess, sizeof(lessmess)); lessmess[messlen - 4] = '\0'; fprintf(stderr, "%s: %s: %s\n", diff --git a/contrib/amd/hlfsd/hlfsd.h b/contrib/amd/hlfsd/hlfsd.h index 2334d1b14d27..ed136b6f2306 100644 --- a/contrib/amd/hlfsd/hlfsd.h +++ b/contrib/amd/hlfsd/hlfsd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: hlfsd.h,v 1.4.2.7 2004/01/06 03:15:23 ezk Exp $ - * $FreeBSD$ + * File: am-utils/hlfsd/hlfsd.h * * HLFSD was written at Columbia University Computer Science Department, by * Erez Zadok and Alexander Dupuy @@ -101,9 +99,6 @@ # define DEFAULT_LOGFILE 0 #endif /* not HAVE)_SYSLOG */ -#define ERRM ": %m" -#define fatalerror(str) \ - (fatal (strcat (strnsave ((str), strlen ((str)) + sizeof (ERRM) - 1), ERRM))) /* * TYPEDEFS: @@ -144,14 +139,14 @@ extern char *mailbox(int, char *); extern char *passwdfile; extern char *slinkname; extern gid_t hlfs_gid; -extern int cache_interval; +extern u_int cache_interval; extern int noverify; extern int serverpid; extern int untab_index(char *username); extern am_nfs_fh *root_fhp; extern am_nfs_fh root; extern nfstime startup; -extern uid2home_t *plt_search(int); +extern uid2home_t *plt_search(u_int); extern username2uid_t *untab; /* user name table */ extern void fatal(char *); extern void plt_init(void); diff --git a/contrib/amd/hlfsd/homedir.c b/contrib/amd/hlfsd/homedir.c index eef883a8fd9e..2ade32ffb344 100644 --- a/contrib/amd/hlfsd/homedir.c +++ b/contrib/amd/hlfsd/homedir.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: homedir.c,v 1.5.2.11 2004/01/06 03:15:23 ezk Exp $ - * $FreeBSD$ + * File: am-utils/hlfsd/homedir.c * * HLFSD was written at Columbia University Computer Science Department, by * Erez Zadok and Alexander Dupuy @@ -67,7 +65,7 @@ static struct passwd passwd_ent; static uid2home_t *lastchild; static uid2home_t *pwtab; static void delay(uid2home_t *, int); -static void table_add(int, const char *, const char *); +static void table_add(u_int, const char *, const char *); static char mboxfile[MAXPATHLEN]; static char *root_home; /* root's home directory */ @@ -91,8 +89,6 @@ homedir(int userid, int groupid) struct stat homestat; int old_groupid, old_userid; - clock_valid = 0; /* invalidate logging clock */ - if ((found = plt_search(userid)) == (uid2home_t *) NULL) { return alt_spooldir; /* use alt spool for unknown uid */ } @@ -103,9 +99,9 @@ homedir(int userid, int groupid) return alt_spooldir; /* use alt spool for / or rel. home */ } if ((int) userid == 0) /* force all uid 0 to use root's home */ - sprintf(linkval, "%s/%s", root_home, home_subdir); + xsnprintf(linkval, sizeof(linkval), "%s/%s", root_home, home_subdir); else - sprintf(linkval, "%s/%s", homename, home_subdir); + xsnprintf(linkval, sizeof(linkval), "%s/%s", homename, home_subdir); if (noverify) { found->last_status = 0; @@ -136,41 +132,18 @@ homedir(int userid, int groupid) } } -#ifdef DEBUG /* - * only run this forking code if asked for -D fork - * or if did not ask for -D nofork + * only run this forking code if did not ask for -D fork */ - amuDebug(D_FORK) { -#endif /* DEBUG */ + if (!amuDebug(D_FORK)) { /* fork child to process request if none in progress */ - if (found->child && kill(found->child, 0) < 0) + if (found->child && kill(found->child, 0)) found->child = 0; if (found->child) delay(found, 5); /* wait a bit if in progress */ - -#if defined(DEBUG) && defined(HAVE_WAITPID) - if (found->child) { - /* perhaps it's a child we lost count of? let's wait on it */ - int status, child; - if ((child = waitpid((pid_t) found->child, &status, WNOHANG)) > 0) { - plog(XLOG_ERROR, "found lost child %d", child); - found->child = 0; - if (WIFEXITED(status)) - found->last_status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - found->last_status = -WTERMSIG(status); - else { - plog(XLOG_ERROR, "unknown child exit status (%d) ???", status); - found->last_status = 255; - } - } - } -#endif /* DEBUG && HAVE_WAITPID */ - - if (found->child) { - found->last_status = 1; /* better safe than sorry - maybe */ + if (found->child) { /* better safe than sorry - maybe */ + found->last_status = 1; return alt_spooldir; } if ((found->child = fork()) < 0) { @@ -178,21 +151,17 @@ homedir(int userid, int groupid) return alt_spooldir; } if (found->child) { /* PARENT */ -#ifdef DEBUG if (lastchild) - plog(XLOG_INFO, "cache spill uid = %ld, pid = %ld, home = %s", + dlog("cache spill uid = %ld, pid = %ld, home = %s", (long) lastchild->uid, (long) lastchild->child, lastchild->home); -#endif /* DEBUG */ lastchild = found; return (char *) NULL; /* return NULL to parent, so it can continue */ } -#ifdef DEBUG - } /* end of Debug(D_FORK) */ -#endif /* DEBUG */ + } /* - * CHILD: (or parent if -D nofork) + * CHILD: (or parent if -D fork) * * Check and create dir if needed. * Check disk space and/or quotas too. @@ -258,9 +227,7 @@ hlfsd_diskspace(char *path) char buf[MAXPATHLEN]; int fd, len; - clock_valid = 0; /* invalidate logging clock */ - - sprintf(buf, "%s/._hlfstmp_%lu", path, (long) getpid()); + xsnprintf(buf, sizeof(buf), "%s/._hlfstmp_%lu", path, (long) getpid()); if ((fd = open(buf, O_RDWR | O_CREAT, 0600)) < 0) { plog(XLOG_ERROR, "cannot open %s: %m", buf); return -1; @@ -298,10 +265,7 @@ delay(uid2home_t *found, int secs) { struct timeval tv; -#ifdef DEBUG - if (found) - dlog("delaying on child %ld for %d seconds", (long) found->child, secs); -#endif /* DEBUG */ + dlog("delaying on child %ld for %d seconds", (long) found->child, secs); tv.tv_usec = 0; @@ -324,55 +288,30 @@ interlock(int signum) int child; uid2home_t *lostchild; int status; - int max_errors = 10; /* avoid infinite loops */ #ifdef HAVE_WAITPID - while ((child = waitpid((pid_t) -1, &status, WNOHANG)) != 0) { + while ((child = waitpid((pid_t) -1, &status, WNOHANG)) > 0) { #else /* not HAVE_WAITPID */ - while ((child = wait3(&status, WNOHANG, (struct rusage *) 0)) != 0) { + while ((child = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0) { #endif /* not HAVE_WAITPID */ - if (child < 0) { - plog(XLOG_WARNING, "waitpid/wait3: %m"); - if (--max_errors > 0) - continue; - else - break; - } - /* high chances this was the last child forked */ if (lastchild && lastchild->child == child) { lastchild->child = 0; if (WIFEXITED(status)) lastchild->last_status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - lastchild->last_status = -WTERMSIG(status); - else { - plog(XLOG_ERROR, "unknown child exit status (%d) ???", status); - lastchild->last_status = 255; - } lastchild = (uid2home_t *) NULL; } else { /* and if not, we have to search for it... */ - int found = 0; for (lostchild = pwtab; lostchild < &pwtab[cur_pwtab_num]; lostchild++) { if (lostchild->child == child) { - lostchild->child = 0; if (WIFEXITED(status)) lostchild->last_status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - lostchild->last_status = -WTERMSIG(status); - else { - plog(XLOG_ERROR, "unknown child exit status (%d) ???", status); - lostchild->last_status = 255; - } - found = 1; + lostchild->child = 0; break; } } - if (!found) - plog(XLOG_ERROR, "no record of child %d found???", child); } } } @@ -456,15 +395,18 @@ mailbox(int uid, char *username) if ((home = homeof(username)) == (char *) NULL) return (char *) NULL; if (STREQ(home, "/")) - sprintf(mboxfile, "/%s/%s", home_subdir, username); + xsnprintf(mboxfile, sizeof(mboxfile), + "/%s/%s", home_subdir, username); else - sprintf(mboxfile, "%s/%s/%s", home, home_subdir, username); + xsnprintf(mboxfile, sizeof(mboxfile), + "%s/%s/%s", home, home_subdir, username); return mboxfile; } static int plt_compare_fxn(const voidp x, const voidp y) + { uid2home_t *i = (uid2home_t *) x; uid2home_t *j = (uid2home_t *) y; @@ -539,8 +481,6 @@ hlfsd_getpwent(void) return getpwent(); } - clock_valid = 0; /* invalidate logging clock */ - /* return here to read another entry */ readent: @@ -563,7 +503,8 @@ hlfsd_getpwent(void) plog(XLOG_ERROR, "no user name on line %d of %s", passwd_line, passwdfile); goto readent; } - strcpy(pw_name, cp); /* will show up in passwd_ent.pw_name */ + /* pw_name will show up in passwd_ent.pw_name */ + xstrlcpy(pw_name, cp, sizeof(pw_name)); /* skip passwd */ strtok(NULL, ":"); @@ -586,7 +527,8 @@ hlfsd_getpwent(void) plog(XLOG_ERROR, "no home dir on line %d of %s", passwd_line, passwdfile); goto readent; } - strcpy(pw_dir, cp); /* will show up in passwd_ent.pw_dir */ + /* pw_dir will show up in passwd_ent.pw_dir */ + xstrlcpy(pw_dir, cp, sizeof(pw_dir)); /* the rest of the fields are unimportant and not being considered */ @@ -649,8 +591,6 @@ plt_reset(void) { int i; - clock_valid = 0; /* invalidate logging clock */ - hlfsd_setpwent(); if (hlfsd_getpwent() == (struct passwd *) NULL) { hlfsd_endpwent(); @@ -691,12 +631,10 @@ plt_reset(void) * n: user ID name */ static void -table_add(int u, const char *h, const char *n) +table_add(u_int u, const char *h, const char *n) { int i; - clock_valid = 0; /* invalidate logging clock */ - if (max_pwtab_num <= 0) { /* was never initialized */ max_pwtab_num = 1; pwtab = (uid2home_t *) xmalloc(max_pwtab_num * @@ -727,10 +665,8 @@ table_add(int u, const char *h, const char *n) /* do NOT add duplicate entries (this is an O(N^2) algorithm... */ for (i=0; iopt; opt++) { - flags |= hasmntopt(mntp, opt->opt) ? opt->flag : 0; + flags |= amu_hasmntopt(mntp, opt->opt) ? opt->flag : 0; } return flags; @@ -158,31 +159,33 @@ compute_automounter_mount_flags(mntent_t *mntp) 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) +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) { int error = 0; #ifdef MOUNT_TABLE_ON_FILE -# ifdef MNTTAB_OPT_DEV - struct stat stb; -# endif /* MNTTAB_OPT_DEV */ char *zopts = NULL, *xopts = NULL; -# if defined(MNTTAB_OPT_DEV) || (defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)) || defined(MNTTAB_OPT_PROTO) - char optsbuf[48]; -# endif /* defined(MNTTAB_OPT_DEV) || (defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)) || defined(MNTTAB_OPT_PROTO) */ + size_t l; #endif /* MOUNT_TABLE_ON_FILE */ + char *mnt_dir = 0; -#ifdef DEBUG - dlog("%s fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)", - mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); -#endif /* DEBUG */ +#ifdef NEED_AUTOFS_SPACE_HACK + char *old_mnt_dir = 0; + /* perform space hack */ + if (on_autofs) { + old_mnt_dir = mnt->mnt_dir; + mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir); + } else +#endif /* NEED_AUTOFS_SPACE_HACK */ + mnt_dir = strdup(mnt->mnt_dir); + + dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)", + mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); again: - clock_valid = 0; - error = MOUNT_TRAP(type, mnt, flags, mnt_data); if (error < 0) { - plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir); + plog(XLOG_ERROR, "'%s': mount: %m", mnt_dir); /* * The following code handles conditions which shouldn't * occur. They are possible either because amd screws up @@ -190,33 +193,18 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, * messed with the mount point. Both have been known to * happen. -- stolcke 2/22/95 */ - if (errno == ENOENT) { - /* - * Occasionally the mount point vanishes, probably - * due to some race condition. Just recreate it - * as necessary. - */ - errno = mkdirs(mnt->mnt_dir, 0555); - if (errno != 0 && errno != EEXIST) - plog(XLOG_ERROR, "%s: mkdirs: %m", mnt->mnt_dir); - else { - plog(XLOG_WARNING, "extra mkdirs required for %s", - mnt->mnt_dir); - error = MOUNT_TRAP(type, mnt, flags, mnt_data); - } - } else if (errno == EBUSY) { + if (errno == EBUSY) { /* * Also, sometimes unmount isn't called, e.g., because * our mountlist is garbled. This leaves old mount * points around which need to be removed before we * can mount something new in their place. */ - errno = umount_fs(mnt->mnt_dir, mnttabname); + errno = umount_fs(mnt_dir, mnttabname, on_autofs); if (errno != 0) - plog(XLOG_ERROR, "%s: umount: %m", mnt->mnt_dir); + plog(XLOG_ERROR, "'%s': umount: %m", mnt_dir); else { - plog(XLOG_WARNING, "extra umount required for %s", - mnt->mnt_dir); + plog(XLOG_WARNING, "extra umount required for '%s'", mnt_dir); error = MOUNT_TRAP(type, mnt, flags, mnt_data); } } @@ -226,8 +214,16 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, sleep(1); goto again; } + +#ifdef NEED_AUTOFS_SPACE_HACK + /* Undo space hack */ + if (on_autofs) + mnt->mnt_dir = old_mnt_dir; +#endif /* NEED_AUTOFS_SPACE_HACK */ + if (error < 0) { - return errno; + error = errno; + goto out; } #ifdef MOUNT_TABLE_ON_FILE @@ -235,23 +231,28 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, * Allocate memory for options: * dev=..., vers={2,3}, proto={tcp,udp} */ - zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 48); + l = strlen(mnt->mnt_opts) + 48; + zopts = (char *) xmalloc(l); /* copy standard options */ xopts = mnt->mnt_opts; - strcpy(zopts, xopts); + xstrlcpy(zopts, xopts, l); # ifdef MNTTAB_OPT_DEV - /* add the extra dev= field to the mount table */ - if (lstat(mnt->mnt_dir, &stb) == 0) { - if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */ - sprintf(optsbuf, "%s=%04lx", - MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff); - else /* e.g. System Vr4 */ - sprintf(optsbuf, "%s=%08lx", - MNTTAB_OPT_DEV, (u_long) stb.st_dev); - append_opts(zopts, optsbuf); + { + /* add the extra dev= field to the mount table */ + struct stat stb; + if (lstat(mnt_dir, &stb) == 0) { + char optsbuf[48]; + if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */ + xsnprintf(optsbuf, sizeof(optsbuf), "%s=%04lx", + MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff); + else /* e.g. System Vr4 */ + xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx", + MNTTAB_OPT_DEV, (u_long) stb.st_dev); + append_opts(zopts, l, optsbuf); + } } # endif /* MNTTAB_OPT_DEV */ @@ -262,8 +263,10 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, */ if (nfs_version == NFS_VERSION3 && hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) { - sprintf(optsbuf, "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3); - append_opts(zopts, optsbuf); + char optsbuf[48]; + xsnprintf(optsbuf, sizeof(optsbuf), + "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3); + append_opts(zopts, l, optsbuf); } # endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */ @@ -272,9 +275,10 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, * add the extra proto={tcp,udp} field to the mount table, * unless already specified by user. */ - if (nfs_proto && !hasmntopt(mnt, MNTTAB_OPT_PROTO)) { - sprintf(optsbuf, "%s=%s", MNTTAB_OPT_PROTO, nfs_proto); - append_opts(zopts, optsbuf); + if (nfs_proto && !amu_hasmntopt(mnt, MNTTAB_OPT_PROTO)) { + char optsbuf[48]; + xsnprintf(optsbuf, sizeof(optsbuf), "%s=%s", MNTTAB_OPT_PROTO, nfs_proto); + append_opts(zopts, l, optsbuf); } # endif /* MNTTAB_OPT_PROTO */ @@ -290,14 +294,15 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, # endif /* HAVE_MNTENT_T_MNT_CNODE */ # ifdef HAVE_MNTENT_T_MNT_RO - mnt->mnt_ro = (hasmntopt(mnt, MNTTAB_OPT_RO) != NULL); + mnt->mnt_ro = (amu_hasmntopt(mnt, MNTTAB_OPT_RO) != NULL); # endif /* HAVE_MNTENT_T_MNT_RO */ # ifdef HAVE_MNTENT_T_MNT_TIME # ifdef HAVE_MNTENT_T_MNT_TIME_STRING { /* allocate enough space for a long */ - char *str = (char *) xmalloc(13 * sizeof(char)); - sprintf(str, "%ld", time((time_t *) NULL)); + size_t l = 13 * sizeof(char); + char *str = (char *) xmalloc(l); + xsnprintf(str, l, "%ld", time((time_t *) NULL)); mnt->mnt_time = str; } # else /* not HAVE_MNTENT_T_MNT_TIME_STRING */ @@ -315,7 +320,126 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, # endif /* MNTTAB_OPT_DEV */ #endif /* MOUNT_TABLE_ON_FILE */ - return 0; + out: + XFREE(mnt_dir); + return error; +} + + +/* + * Compute all NFS attribute cache related flags separately. Note that this + * function now computes attribute-cache flags for both Amd's automount + * points (NFS) as well as any normal NFS mount that Amd performs. Edit + * with caution. + */ +static void +compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp) +{ + int acval = 0; + int err_acval = 1; /* 1 means we found no 'actimeo' value */ +#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) + int err_acrdmm; /* for ac{reg,dir}{min,max} */ +#endif /* HAVE_NFS_ARGS_T_AC{REG,DIR}{MIN,MAX} */ + + /************************************************************************/ + /*** ATTRIBUTE CACHES ***/ + /************************************************************************/ + /* + * acval is set to 0 at the top of the function. If actimeo mount option + * exists and defined in mntopts, then its acval is set to it. + * If the value is non-zero, then we set all attribute cache fields to it. + * If acval is zero, it means it was never defined in mntopts or the + * actimeo mount option does not exist, in which case we check for + * individual mount options per attribute cache. + * Regardless of the value of acval, mount flags are set based directly + * on the values of the attribute caches. + */ +#ifdef MNTTAB_OPT_ACTIMEO + err_acval = hasmntvalerr(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */ +#endif /* MNTTAB_OPT_ACTIMEO */ + + /*** acregmin ***/ +#ifdef HAVE_NFS_ARGS_T_ACREGMIN + err_acrdmm = 1; /* 1 means we found no acregmin value */ + if (!err_acval) { + nap->acregmin = acval; /* min ac timeout for reg files (sec) */ + } else { +# ifdef MNTTAB_OPT_ACREGMIN + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, (int *) &nap->acregmin); +# else /* not MNTTAB_OPT_ACREGMIN */ + nap->acregmin = 0; +# endif /* not MNTTAB_OPT_ACREGMIN */ + } + /* set this flag iff we changed acregmin (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACREGMIN + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACREGMIN; +# endif /* MNT2_NFS_OPT_ACREGMIN */ +#endif /* HAVE_NFS_ARGS_T_ACREGMIN */ + + /*** acregmax ***/ +#ifdef HAVE_NFS_ARGS_T_ACREGMAX + err_acrdmm = 1; /* 1 means we found no acregmax value */ + if (!err_acval) { + nap->acregmax = acval; /* max ac timeout for reg files (sec) */ + } else { +# ifdef MNTTAB_OPT_ACREGMAX + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, (int *) &nap->acregmax); +# else /* not MNTTAB_OPT_ACREGMAX */ + nap->acregmax = 0; +# endif /* not MNTTAB_OPT_ACREGMAX */ + } + /* set this flag iff we changed acregmax (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACREGMAX + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACREGMAX; +# endif /* MNT2_NFS_OPT_ACREGMAX */ +#endif /* HAVE_NFS_ARGS_T_ACREGMAX */ + + /*** acdirmin ***/ +#ifdef HAVE_NFS_ARGS_T_ACDIRMIN + err_acrdmm = 1; /* 1 means we found no acdirmin value */ + if (!err_acval) { + nap->acdirmin = acval; /* min ac timeout for dirs (sec) */ + } else { +# ifdef MNTTAB_OPT_ACDIRMIN + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, (int *) &nap->acdirmin); +# else /* not MNTTAB_OPT_ACDIRMIN */ + nap->acdirmin = 0; +# endif /* not MNTTAB_OPT_ACDIRMIN */ + } + /* set this flag iff we changed acdirmin (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACDIRMIN + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACDIRMIN; +# endif /* MNT2_NFS_OPT_ACDIRMIN */ +#endif /* HAVE_NFS_ARGS_T_ACDIRMIN */ + + /*** acdirmax ***/ +#ifdef HAVE_NFS_ARGS_T_ACDIRMAX + err_acrdmm = 1; /* 1 means we found no acdirmax value */ + if (!err_acval) { + nap->acdirmax = acval; /* max ac timeout for dirs (sec) */ + } else { +# ifdef MNTTAB_OPT_ACDIRMAX + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, (int *) &nap->acdirmax); +# else /* not MNTTAB_OPT_ACDIRMAX */ + nap->acdirmax = 0; +# endif /* not MNTTAB_OPT_ACDIRMAX */ + } + /* set this flag iff we changed acdirmax (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACDIRMAX + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACDIRMAX; +# endif /* MNT2_NFS_OPT_ACDIRMAX */ +#endif /* HAVE_NFS_ARGS_T_ACDIRMAX */ + + + /* don't cache attributes */ +#if defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NOAC) != NULL) + nap->flags |= MNT2_NFS_OPT_NOAC; +#endif /* defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) */ } @@ -334,31 +458,28 @@ mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, * fs_name: remote file system name to mount */ void -#ifdef HAVE_TRANSPORT_TYPE_TLI -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) -#else /* not HAVE_TRANSPORT_TYPE_TLI */ -compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_in *ip_addr, u_long nfs_version, char *nfs_proto, am_nfs_handle_t *fhp, char *host_name, char *fs_name) -#endif /* not HAVE_TRANSPORT_TYPE_TLI */ +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) { - int acval = 0; -#ifdef HAVE_FS_NFS3 - static am_nfs_fh3 fh3; /* static, b/c gcc on aix corrupts stack */ -#endif /* HAVE_FS_NFS3 */ - /* 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) { - memset((voidp) &fh3, 0, sizeof(am_nfs_fh3)); - fh3.fh3_length = fhp->v3.mountres3_u.mountinfo.fhandle.fhandle3_len; - memmove(fh3.fh3_u.data, - fhp->v3.mountres3_u.mountinfo.fhandle.fhandle3_val, - fh3.fh3_length); - # 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 @@ -366,9 +487,9 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ * the file handle set in nfs_args be plain bytes, and not * include the length field. */ - NFS_FH_DREF(nap->NFS_FH_FIELD, &(fh3.fh3_u.data)); + 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, &fh3); + 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; @@ -378,12 +499,12 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ # endif /* MNT2_NFS_OPT_VER3 */ } else #endif /* HAVE_FS_NFS3 */ - NFS_FH_DREF(nap->NFS_FH_FIELD, &(fhp->v2.fhs_fh)); + 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 = fh3.fh3_length; + nap->fhsize = fhp->v3.am_fh3_length; else # endif /* HAVE_FS_NFS3 */ nap->fhsize = FHSIZE; @@ -393,7 +514,7 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #ifdef HAVE_NFS_ARGS_T_FH_LEN # ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3) - nap->fh_len = fh3.fh3_length; + nap->fh_len = fhp->v3.am_fh3_length; else # endif /* HAVE_FS_NFS3 */ nap->fh_len = FHSIZE; @@ -402,74 +523,16 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ /************************************************************************/ /*** 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 */ - /************************************************************************/ - /*** ATTRIBUTE CACHES ***/ - /************************************************************************/ - /* - * acval is set to 0 at the top of the function. If actimeo mount option - * exists and defined in mntopts, then it acval is set to it. - * If the value is non-zero, then we set all attribute cache fields to it. - * If acval is zero, it means it was never defined in mntopts or the - * actimeo mount option does not exist, in which case we check for - * individual mount options per attribute cache. - * Regardless of the value of acval, mount flags are set based directly - * on the values of the attribute caches. - */ -#ifdef MNTTAB_OPT_ACTIMEO - acval = hasmntval(mntp, MNTTAB_OPT_ACTIMEO); /* attr cache timeout (sec) */ -#endif /* MNTTAB_OPT_ACTIMEO */ - - if (acval) { -#ifdef HAVE_NFS_ARGS_T_ACREGMIN - nap->acregmin = acval; /* min ac timeout for reg files (sec) */ - nap->acregmax = acval; /* max ac timeout for reg files (sec) */ -#endif /* HAVE_NFS_ARGS_T_ACREGMIN */ -#ifdef HAVE_NFS_ARGS_T_ACDIRMIN - nap->acdirmin = acval; /* min ac timeout for dirs (sec) */ - nap->acdirmax = acval; /* max ac timeout for dirs (sec) */ -#endif /* HAVE_NFS_ARGS_T_ACDIRMIN */ - } else { -#ifdef MNTTAB_OPT_ACREGMIN - nap->acregmin = hasmntval(mntp, MNTTAB_OPT_ACREGMIN); -#endif /* MNTTAB_OPT_ACREGMIN */ -#ifdef MNTTAB_OPT_ACREGMAX - nap->acregmax = hasmntval(mntp, MNTTAB_OPT_ACREGMAX); -#endif /* MNTTAB_OPT_ACREGMAX */ -#ifdef MNTTAB_OPT_ACDIRMIN - nap->acdirmin = hasmntval(mntp, MNTTAB_OPT_ACDIRMIN); -#endif /* MNTTAB_OPT_ACDIRMIN */ -#ifdef MNTTAB_OPT_ACDIRMAX - nap->acdirmax = hasmntval(mntp, MNTTAB_OPT_ACDIRMAX); -#endif /* MNTTAB_OPT_ACDIRMAX */ - } /* end of "if (acval)" statement */ - -#ifdef MNT2_NFS_OPT_ACREGMIN - if (nap->acregmin) - nap->flags |= MNT2_NFS_OPT_ACREGMIN; -#endif /* MNT2_NFS_OPT_ACREGMIN */ -#ifdef MNT2_NFS_OPT_ACREGMAX - if (nap->acregmax) - nap->flags |= MNT2_NFS_OPT_ACREGMAX; -#endif /* MNT2_NFS_OPT_ACREGMAX */ -#ifdef MNT2_NFS_OPT_ACDIRMIN - if (nap->acdirmin) - nap->flags |= MNT2_NFS_OPT_ACDIRMIN; -#endif /* MNT2_NFS_OPT_ACDIRMIN */ -#ifdef MNT2_NFS_OPT_ACDIRMAX - if (nap->acdirmax) - nap->flags |= MNT2_NFS_OPT_ACDIRMAX; -#endif /* MNT2_NFS_OPT_ACDIRMAX */ - -#ifdef MNTTAB_OPT_NOAC /* don't cache attributes */ - if (hasmntopt(mntp, MNTTAB_OPT_NOAC) != NULL) - nap->flags |= MNT2_NFS_OPT_NOAC; -#endif /* MNTTAB_OPT_NOAC */ - /************************************************************************/ /*** IP ADDRESS OF REMOTE HOST ***/ /************************************************************************/ @@ -524,9 +587,9 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ /************************************************************************/ #ifdef MNT2_NFS_OPT_NOCONN /* check if user specified to use unconnected or connected sockets */ - if (hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL) nap->flags |= MNT2_NFS_OPT_NOCONN; - else if (hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL) + else if (amu_hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL) nap->flags &= ~MNT2_NFS_OPT_NOCONN; else { /* @@ -554,7 +617,7 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #ifdef MNT2_NFS_OPT_RESVPORT # ifdef MNTTAB_OPT_RESVPORT - if (hasmntopt(mntp, MNTTAB_OPT_RESVPORT) != NULL) + 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; @@ -588,12 +651,16 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ 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 @@ -612,11 +679,13 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ nap->flags |= MNT2_NFS_OPT_BIODS; #endif /* MNT2_NFS_OPT_BIODS */ - if (hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL) +#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 (hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) { + 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"); @@ -632,7 +701,7 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #endif /* defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) */ #ifdef MNTTAB_OPT_INTR - if (hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL) /* * Either turn on the "allow interrupts" option, or * turn off the "disallow interrupts" option" @@ -652,17 +721,17 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #endif /* MNTTAB_OPT_INTR */ #ifdef MNTTAB_OPT_NODEVS - if (hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL) nap->flags |= MNT2_NFS_OPT_NODEVS; #endif /* MNTTAB_OPT_NODEVS */ #ifdef MNTTAB_OPT_COMPRESS - if (hasmntopt(mntp, MNTTAB_OPT_COMPRESS) != NULL) + 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 (hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL) nap->flags |= MNT2_NFS_OPT_PRIVATE; #endif /* MNTTAB_OPT_PRIVATE */ @@ -677,33 +746,38 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #endif /* MNT2_NFS_OPT_PGTHRESH */ #if defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) - if (hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL) + 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 (hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) { + if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) { nap->flags |= MNT2_NFS_OPT_POSIX; nap->pathconf = NULL; } #endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */ #if defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) - if (hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL) + 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 != NULL) + 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 (hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL) + 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 */ @@ -762,28 +836,9 @@ compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp) nap->flags |= MNT2_NFS_OPT_DUMBTIMR; #endif /* MNT2_NFS_OPT_DUMBTIMR */ -#ifdef MNT2_NFS_OPT_NOAC - /* - * Don't cache attributes - they are changing under the kernel's feet. - * For example, IRIX5.2 will dispense with nfs lookup calls and hand stale - * filehandles to getattr unless we disable attribute caching on the - * automount points. - */ - nap->flags |= MNT2_NFS_OPT_NOAC; -#else /* not MNT2_NFS_OPT_NOAC */ - /* - * Setting these to 0 results in an error on some systems, which is why - * it's better to use "noac" if possible. - */ -# if defined(MNT2_NFS_OPT_ACREGMIN) && defined(MNT2_NFS_OPT_ACREGMAX) - nap->acregmin = nap->acregmax = 0; /* XXX: was 1, but why? */ - nap->flags |= MNT2_NFS_OPT_ACREGMIN | MNT2_NFS_OPT_ACREGMAX; -# endif /* defined(MNT2_NFS_OPT_ACREGMIN) && defined(MNT2_NFS_OPT_ACREGMAX) */ -# if defined(MNT2_NFS_OPT_ACDIRMIN) && defined(MNT2_NFS_OPT_ACDIRMAX) - nap->acdirmin = nap->acdirmax = 0; /* XXX: was 1, but why? */ - nap->flags |= MNT2_NFS_OPT_ACDIRMIN | MNT2_NFS_OPT_ACDIRMAX; -# endif /* defined(MNT2_NFS_OPT_ACDIRMIN) && defined(MNT2_NFS_OPT_ACDIRMAX) */ -#endif /* not MNT2_NFS_OPT_NOAC */ + /* compute all of the NFS attribute-cache flags */ + compute_nfs_attrcache_flags(nap, mntp); + /* * Provide a slight bit more security by requiring the kernel to use * reserved ports. @@ -799,7 +854,7 @@ compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp) static char * get_hex_string(u_int len, const char *fhdata) { - int i; + u_int i; static char buf[128]; /* better not go over it! */ char str[16]; short int arr[64]; @@ -809,9 +864,9 @@ get_hex_string(u_int len, const char *fhdata) buf[0] = '\0'; memset(&arr[0], 0, (64 * sizeof(short int))); memcpy(&arr[0], &fhdata[0], len); - for (i=0; imaxlen, nbp->len, get_hex_string(nbp->len, nbp->buf)); nbp = nap->syncaddr; - plog(XLOG_DEBUG, "NA->syncaddr {netbuf} 0x%x", (int) nbp); + plog(XLOG_DEBUG, "NA->syncaddr {netbuf} %p", nbp); kncp = nap->knconf; plog(XLOG_DEBUG, "NA->knconf->semantics %lu", (u_long) kncp->knc_semantics); plog(XLOG_DEBUG, "NA->knconf->protofmly \"%s\"", kncp->knc_protofmly); @@ -859,18 +914,26 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version) plog(XLOG_DEBUG, "NA->knconf->rdev %lu", (u_long) kncp->knc_rdev); /* don't print knconf->unused field */ #else /* not HAVE_TRANSPORT_TYPE_TLI */ - sap = (struct sockaddr_in *) &nap->addr; +# ifdef NFS_ARGS_T_ADDR_IS_POINTER + sap = (struct sockaddr_in *) nap->addr; +# else /* not NFS_ARGS_T_ADDR_IS_POINTER */ + sap = (struct sockaddr_in *) &nap->addr; +# endif /* not NFS_ARGS_T_ADDR_IS_POINTER */ plog(XLOG_DEBUG, "NA->addr {sockaddr_in} (len=%d) = \"%s\"", (int) sizeof(struct sockaddr_in), get_hex_string(sizeof(struct sockaddr_in), (const char *)sap)); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - plog(XLOG_DEBUG, "NA->addr.sin_len = \"%d\"", sap->sin_len); + /* as per POSIX, sin_len need not be set (used internally by kernel) */ + plog(XLOG_DEBUG, "NA->addr.sin_len = %d", sap->sin_len); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - plog(XLOG_DEBUG, "NA->addr.sin_family = \"%d\"", sap->sin_family); - plog(XLOG_DEBUG, "NA->addr.sin_port = \"%d\"", sap->sin_port); + plog(XLOG_DEBUG, "NA->addr.sin_family = %d", sap->sin_family); + plog(XLOG_DEBUG, "NA->addr.sin_port = %d", sap->sin_port); plog(XLOG_DEBUG, "NA->addr.sin_addr = \"%s\"", get_hex_string(sizeof(struct in_addr), (const char *) &sap->sin_addr)); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ +#ifdef HAVE_NFS_ARGS_T_ADDRLEN + plog(XLOG_DEBUG, "NA->addrlen = %d", nap->addrlen); +#endif /* ifdef HAVE_NFS_ARGS_T_ADDRLEN */ plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname ? nap->hostname : "null"); #ifdef HAVE_NFS_ARGS_T_NAMLEN diff --git a/contrib/amd/mk-amd-map/mk-amd-map.c b/contrib/amd/mk-amd-map/mk-amd-map.c index d72850eeba94..48d82b0bd0d7 100644 --- a/contrib/amd/mk-amd-map/mk-amd-map.c +++ b/contrib/amd/mk-amd-map/mk-amd-map.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: mk-amd-map.c,v 1.5.2.6 2004/01/06 03:15:25 ezk Exp $ - * $FreeBSD$ + * File: am-utils/mk-amd-map/mk-amd-map.c */ /* @@ -224,7 +222,7 @@ main(int argc, char *argv[]) char maptpag[16], maptdir[16]; char *map_name_pag = (char *) NULL, *map_name_dir = (char *) NULL; #endif /* not HAVE_DB_SUFFIX */ - int len; + size_t l = 0; char *sl; int printit = 0; int usage = 0; @@ -273,13 +271,14 @@ main(int argc, char *argv[]) #endif /* DEBUG */ if (!printit) { - len = strlen(mapsrc); + /* enough space for ".db" or ".pag" or ".dir" appended */ + l = strlen(mapsrc) + 5; #ifdef HAVE_DB_SUFFIX - map_name_db = (char *) malloc(len + 4); + map_name_db = (char *) malloc(l); error = (map_name_db == NULL); #else /* not HAVE_DB_SUFFIX */ - map_name_pag = (char *) malloc(len + 5); - map_name_dir = (char *) malloc(len + 5); + map_name_pag = (char *) malloc(l); + map_name_dir = (char *) malloc(l); error = (map_name_pag == NULL || map_name_dir == NULL); #endif /* not HAVE_DB_SUFFIX */ if (error) { @@ -306,15 +305,15 @@ main(int argc, char *argv[]) /* remove existing temps (if any) */ #ifdef HAVE_DB_SUFFIX - sprintf(maptdb, "%s.db", maptmp); + xsnprintf(maptdb, sizeof(maptdb), "%s.db", maptmp); if (remove_file(maptdb) < 0) { fprintf(stderr, "Can't remove existing temporary file; "); perror(maptdb); exit(1); } #else /* not HAVE_DB_SUFFIX */ - sprintf(maptpag, "%s.pag", maptmp); - sprintf(maptdir, "%s.dir", maptmp); + xsnprintf(maptpag, sizeof(maptpag), "%s.pag", maptmp); + xsnprintf(maptdir, sizeof(maptdir), "%s.dir", maptmp); if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { fprintf(stderr, "Can't remove existing temporary files; %s and ", maptpag); perror(maptdir); @@ -349,7 +348,8 @@ main(int argc, char *argv[]) /* all went well */ #ifdef HAVE_DB_SUFFIX - sprintf(map_name_db, "%s.db", mapsrc); + /* sizeof(map_name_db) is malloc'ed above */ + xsnprintf(map_name_db, l, "%s.db", mapsrc); if (rename(maptdb, map_name_db) < 0) { fprintf(stderr, "Couldn't rename %s to ", maptdb); perror(map_name_db); @@ -358,8 +358,9 @@ main(int argc, char *argv[]) exit(1); } #else /* not HAVE_DB_SUFFIX */ - sprintf(map_name_pag, "%s.pag", mapsrc); - sprintf(map_name_dir, "%s.dir", mapsrc); + /* sizeof(map_name_{pag,dir}) are malloc'ed above */ + xsnprintf(map_name_pag, l, "%s.pag", mapsrc); + xsnprintf(map_name_dir, l, "%s.dir", mapsrc); if (rename(maptpag, map_name_pag) < 0) { fprintf(stderr, "Couldn't rename %s to ", maptpag); perror(map_name_pag); diff --git a/contrib/amd/wire-test/wire-test.c b/contrib/amd/wire-test/wire-test.c index 593cf4538786..bcaaf5a31519 100644 --- a/contrib/amd/wire-test/wire-test.c +++ b/contrib/amd/wire-test/wire-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,10 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: wire-test.c,v 1.5.2.4 2004/01/06 03:15:25 ezk Exp $ - * $FreeBSD$ + * File: am-utils/wire-test/wire-test.c * */ @@ -80,7 +78,7 @@ main(int argc, char **argv) } /* also print my IP address */ - amu_get_myaddress(&myipaddr); + amu_get_myaddress(&myipaddr, NULL); fprintf(stderr, "My IP address is 0x%x.\n", (unsigned int) htonl(myipaddr.s_addr)); /* @@ -99,6 +97,7 @@ main(int argc, char **argv) } ip = (struct sockaddr_in *) xmalloc(sizeof(struct sockaddr_in)); memset((voidp) ip, 0, sizeof(*ip)); + /* as per POSIX, sin_len need not be set (used internally by kernel) */ ip->sin_family = AF_INET; memmove((voidp) &ip->sin_addr, (voidp) hp->h_addr, sizeof(ip->sin_addr)); ip->sin_port = htons(NFS_PORT);