Put stock 6.1.5 file into HEAD.

This commit is contained in:
obrien 2007-12-05 16:57:05 +00:00
parent 0e36aeab45
commit 4487f06b05
16 changed files with 1172 additions and 904 deletions

View File

@ -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);
}

View File

@ -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 <build_version.h>
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<AMU_TYPE_MAX; ++i)
gopt.amfs_auto_timeo[i] = atoi(optarg);
}
if (dot) {
gopt.amfs_auto_retrans = atoi(dot + 1);
for (i=0; i<AMU_TYPE_MAX; ++i)
gopt.amfs_auto_retrans[i] = atoi(dot + 1);
*dot = '.';
}
}
break;
case 'v':
fputs(get_version_string(), stderr);
exit(0);
/*
* defer to print version info after every variable had been
* initialized.
*/
print_version++;
break;
case 'w':
@ -226,6 +273,10 @@ get_args(int argc, char *argv[])
#endif /* not HAVE_MAP_NIS */
break;
case 'A':
gopt.arch = optarg;
break;
case 'C':
gopt.cluster = optarg;
break;
@ -240,12 +291,13 @@ get_args(int argc, char *argv[])
break;
case 'F':
conf_file = optarg;
amu_conf_file = optarg;
use_conf_file = 1;
break;
case 'H':
goto show_usage;
show_usage();
exit(1);
break;
case 'O':
@ -270,18 +322,19 @@ get_args(int argc, char *argv[])
* specified, then use that amd.conf file. If the file cannot be opened,
* abort amd. If it can be found, open it, parse it, and then close it.
*/
if (use_conf_file && conf_file) {
fp = fopen(conf_file, "r");
if (use_conf_file && amu_conf_file) {
fp = fopen(amu_conf_file, "r");
if (!fp) {
char buf[128];
sprintf(buf, "Amd configuration file (%s)", conf_file);
xsnprintf(buf, sizeof(buf), "Amd configuration file (%s)",
amu_conf_file);
perror(buf);
exit(1);
}
yyin = fp;
yyparse();
fclose(fp);
if (process_last_regular_map() != 0)
if (process_all_regular_maps() != 0)
exit(1);
}
@ -294,8 +347,8 @@ get_args(int argc, char *argv[])
#endif /* DEBUG */
/* log information regarding amd.conf file */
if (use_conf_file && conf_file)
plog(XLOG_INFO, "using configuration file %s", conf_file);
if (use_conf_file && amu_conf_file)
plog(XLOG_INFO, "using configuration file %s", amu_conf_file);
#ifdef HAVE_MAP_LDAP
/* ensure that if ldap_base is specified, that also ldap_hostports is */
@ -305,8 +358,10 @@ get_args(int argc, char *argv[])
}
#endif /* HAVE_MAP_LDAP */
if (usage)
goto show_usage;
if (usage) {
show_usage();
exit(1);
}
while (optind <= argc - 2) {
char *dir = argv[optind++];
@ -328,76 +383,55 @@ get_args(int argc, char *argv[])
hostdomain = gopt.sub_domain;
if (*hostdomain == '.')
hostdomain++;
strcat(hostd, ".");
strcat(hostd, hostdomain);
xstrlcat(hostd, ".", sizeof(hostd));
xstrlcat(hostd, hostdomain, sizeof(hostd));
#ifdef MOUNT_TABLE_ON_FILE
# ifdef DEBUG
if (debug_flags & D_MTAB)
mnttab_file_name = DEBUG_MNTTAB;
if (amuDebug(D_MTAB))
if (gopt.debug_mtab_file)
mnttab_file_name = gopt.debug_mtab_file; /* user supplied debug mtab path */
else
mnttab_file_name = DEBUG_MNTTAB_FILE; /* default debug mtab path */
else
# endif /* DEBUG */
mnttab_file_name = MNTTAB_FILE_NAME;
#else /* not MOUNT_TABLE_ON_FILE */
# ifdef DEBUG
if (debug_flags & D_MTAB)
if (amuDebug(D_MTAB))
dlog("-D mtab option ignored");
# endif /* DEBUG */
# ifdef MNTTAB_FILE_NAME
mnttab_file_name = MNTTAB_FILE_NAME;
# endif /* MNTTAB_FILE_NAME */
#endif /* not MOUNT_TABLE_ON_FILE */
if (switch_to_logfile(gopt.logfile, orig_umask) != 0)
plog(XLOG_USER, "Cannot switch logfile");
/*
* If the kernel architecture was not specified
* then use the machine architecture.
*/
if (gopt.karch == 0)
if (gopt.karch == NULL)
gopt.karch = gopt.arch;
if (gopt.cluster == 0)
if (gopt.cluster == NULL)
gopt.cluster = hostdomain;
if (gopt.amfs_auto_timeo <= 0)
gopt.amfs_auto_timeo = AMFS_AUTO_TIMEO;
if (gopt.amfs_auto_retrans <= 0)
gopt.amfs_auto_retrans = AMFS_AUTO_RETRANS;
if (gopt.amfs_auto_retrans <= 0)
gopt.amfs_auto_retrans = 3; /* XXX */
return;
/* sanity checking, normalize values just in case (toplvl too) */
for (i=0; i<AMU_TYPE_MAX; ++i) {
if (gopt.amfs_auto_timeo[i] == 0)
gopt.amfs_auto_timeo[i] = AMFS_AUTO_TIMEO;
if (gopt.amfs_auto_retrans[i] == 0)
gopt.amfs_auto_retrans[i] = AMFS_AUTO_RETRANS(i);
if (gopt.amfs_auto_retrans[i] == 0)
gopt.amfs_auto_retrans[i] = 3; /* under very unusual circumstances, could be zero */
}
}
show_usage:
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] [-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 */
);
/* finally print version string and exit, if asked for */
if (print_version) {
fputs(get_version_string(), stderr);
exit(0);
}
#ifdef HAVE_MAP_NIS
fputs(" [-y nis-domain]\n", stderr);
#else /* not HAVE_MAP_NIS */
fputc('\n', stderr);
#endif /* HAVE_MAP_NIS */
if (switch_to_logfile(gopt.logfile, orig_umask,
(gopt.flags & CFM_TRUNCATE_LOG)) != 0)
plog(XLOG_USER, "Cannot switch logfile");
show_opts('x', xlog_opt);
#ifdef DEBUG
show_opts('D', dbg_opt);
#endif /* DEBUG */
fprintf(stderr, "\t[directory mapname [-map_options]] ...\n");
exit(1);
return;
}

View File

@ -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: nfs_prot_svc.c,v 1.5.2.6 2004/01/21 04:04:58 ib42 Exp $
* $FreeBSD$
* File: am-utils/amd/nfs_prot_svc.c
*
*/
@ -70,7 +68,7 @@ extern nfsreaddirres *nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *);
extern nfsstatfsres *nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *);
/* global variables */
SVCXPRT *nfs_program_2_transp;
SVCXPRT *current_transp;
/* typedefs */
typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
@ -99,30 +97,60 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
char *result;
xdrproc_t xdr_argument, xdr_result;
nfssvcproc_t local;
#ifdef HAVE_TRANSPORT_TYPE_TLI
/*
* On TLI systems we don't use an INET network type, but a "ticlts" (see
* /etc/netconfig and conf/transp_tli.c:create_nfs_service). This means
* that packets could only come from the loopback interface, and we don't
* need to check them and filter possibly spoofed packets. Therefore we
* only need to check if the UID caller is correct.
*/
# ifdef HAVE___RPC_GET_LOCAL_UID
uid_t u;
/* extern definition for an internal libnsl function */
extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
if (__rpc_get_local_uid(transp, &u) >= 0 && u != 0) {
plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
return;
}
# else /* not HAVE___RPC_GET_LOCAL_UID */
dlog("cannot verify local uid for rpc request");
# endif /* HAVE___RPC_GET_LOCAL_UID */
#else /* not HAVE_TRANPORT_TYPE_TLI */
struct sockaddr_in *sinp;
char dq[20], dq2[28];
sinp = amu_svc_getcaller(rqstp->rq_xprt);
#ifdef MNT2_NFS_OPT_RESVPORT
# 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,

View File

@ -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);
}

View File

@ -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
* <mcm@unx.sas.com>
* 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 <mcm@unx.sas.com>
* 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;
}
/*

View File

@ -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 <sys/cdefs.h>
__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 <config.h>
#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);

View File

@ -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
*
*/

View File

@ -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 <nfsserver/nfs.h>
#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 <ufs/ufs/ufsmount.h>.
*/
struct ufs_extattr_per_mount;
# endif /* HAVE_UFS_UFS_EXTATTR_H */
# include <ufs/ufs/ufsmount.h>
#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. */

View File

@ -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,

View File

@ -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

View File

@ -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 <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
@ -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",

View File

@ -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 <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
@ -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);

View File

@ -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 <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
@ -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; i<cur_pwtab_num; ++i)
if (u == pwtab[i].uid && u != 0 ) {
#ifdef DEBUG
dlog("ignoring duplicate home %s for uid %d (already %s)",
h, u, pwtab[i].home);
#endif /* DEBUG */
return;
}
@ -758,7 +694,7 @@ table_add(int u, const char *h, const char *n)
* return entry in lookup table
*/
uid2home_t *
plt_search(int u)
plt_search(u_int u)
{
int max, min, mid;

View File

@ -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: mount_fs.c,v 1.11.2.12 2004/01/06 03:15:24 ezk Exp $
* $FreeBSD$
* File: am-utils/libamu/mount_fs.c
*
*/
@ -51,9 +49,10 @@
/* ensure that mount table options are delimited by a comma */
#define append_opts(old, new) { \
if (*(old) != '\0') strcat(old, ","); \
strcat(old, new); }
#define append_opts(old, l, new) { \
if (*(old) != '\0') \
xstrlcat(old, ",", l); \
xstrlcat(old, new, l); }
/*
* Standard mount flags
@ -108,7 +107,9 @@ struct opt_tab mnt_flags[] =
/*
* Do not define MNT2_NFS_OPT_* entries here! This is for generic
* mount(2) options only, not for NFS mount options.
* mount(2) options only, not for NFS mount options. If you need to put
* something here, it's probably not the right place: see
* include/am_compat.h.
*/
{0, 0}
@ -123,7 +124,7 @@ compute_mount_flags(mntent_t *mntp)
int flags = 0;
#ifdef MNT2_GEN_OPT_NEWTYPE
flags = MNT2_GEN_OPT_NEWTYPE;
flags |= MNT2_GEN_OPT_NEWTYPE;
#endif /* MNT2_GEN_OPT_NEWTYPE */
#ifdef MNT2_GEN_OPT_AUTOMOUNTED
flags |= MNT2_GEN_OPT_AUTOMOUNTED;
@ -133,7 +134,7 @@ compute_mount_flags(mntent_t *mntp)
* Crack basic mount options
*/
for (opt = mnt_flags; opt->opt; 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; i<len/sizeof(short int); i++) {
sprintf(str, "%04x", ntohs(arr[i]));
strcat(buf, str);
for (i=0; i<len/sizeof(unsigned short int); i++) {
xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i]));
xstrlcat(buf, str, sizeof(buf));
}
return buf;
}
@ -824,7 +879,7 @@ get_hex_string(u_int len, const char *fhdata)
void
print_nfs_args(const nfs_args_t *nap, u_long nfs_version)
{
int fhlen = 32; /* default: NFS V.2 file handle length is 32 */
int fhlen = 32; /* default: NFS V.2 file handle length is 32 */
#ifdef HAVE_TRANSPORT_TYPE_TLI
struct netbuf *nbp;
struct knetconfig *kncp;
@ -851,7 +906,7 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version)
nbp->maxlen, 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

View File

@ -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);

View File

@ -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);