Compare commits

...
Sign in to create a new pull request.

6 commits

30 changed files with 2428 additions and 7 deletions

View file

@ -0,0 +1,145 @@
commit a6bbb7d9b098dacd2636925c232c630452e4b46e
Author: Christos Zoulas <christos@zoulas.com>
Date: Sun Jan 18 18:03:37 2015 -0500
32 bit fixes
diff --git a/amd/amq_subr.c b/amd/amq_subr.c
index 8783611..86f0351 100644
--- a/amd/amq_subr.c
+++ b/amd/amq_subr.c
@@ -528,6 +528,7 @@ xdr_amq_map_info_qelem(XDR *xdrs, qelem *qhead)
u_int len = 0;
int x;
char *n;
+ long modify;
/*
* Compute length of list
@@ -552,7 +553,8 @@ xdr_amq_map_info_qelem(XDR *xdrs, qelem *qhead)
return (FALSE);
}
- if (!xdr_long(xdrs, &m->modify)) {
+ modify = (long)m->modify;
+ if (!xdr_long(xdrs, &modify)) {
return (FALSE);
}
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
index e463ff7..7192a6a 100644
--- a/amd/nfs_subr.c
+++ b/amd/nfs_subr.c
@@ -1104,9 +1104,9 @@ am_nfs3_getattr_3_svc(am_GETATTR3args *argp, struct svc_req *rqstp)
result.status = AM_NFS3_OK;
if (amuDebug(D_TRACE))
- plog(XLOG_DEBUG, "\tstat(%s), size = %lu, mtime=%d.%d",
+ plog(XLOG_DEBUG, "\tstat(%s), size = %llu, mtime=%d.%d",
mp->am_path,
- (am_size3) fattr3->size,
+ (unsigned long long)fattr3->size,
(u_int) fattr3->mtime.seconds,
(u_int) fattr3->mtime.nseconds);
diff --git a/amd/readdir.c b/amd/readdir.c
index 4b5e61b..57773a5 100644
--- a/amd/readdir.c
+++ b/amd/readdir.c
@@ -635,7 +635,7 @@ static size_t needroom3(void)
/* This one is called only if map is browsable */
static int
-amfs_readdir3_browsable(am_node *mp, am_cookie3 cookie,
+amfs_readdir3_browsable(am_node *mp, voidp cookie,
am_dirlist3 *dp, am_entry3 *ep, u_int count,
int fully_browsable)
{
@@ -647,7 +647,8 @@ amfs_readdir3_browsable(am_node *mp, am_cookie3 cookie,
dp->eof = FALSE; /* assume readdir not done */
if (amuDebug(D_READDIR))
- plog(XLOG_DEBUG, "amfs_readdir3_browsable gen=%lu, count=%d", gen, count);
+ plog(XLOG_DEBUG, "%s: gen=%llu, count=%d", __func__,
+ (unsigned long long)gen, count);
if (gen == 0) {
size_t needed = needroom3();
@@ -732,8 +733,9 @@ amfs_readdir3_browsable(am_node *mp, am_cookie3 cookie,
for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
plog(XLOG_DEBUG, "gen2 key %4d \"%s\"", j++, ne->name);
for (j = 0, ne = ep; ne; ne = ne->ne_nextentry) {
- plog(XLOG_DEBUG, "gen2+ key %4d \"%s\" fi=%lu ck=%lu",
- j++, ne->name, ne->fileid, ne->cookie);
+ plog(XLOG_DEBUG, "gen2+ key %4d \"%s\" fi=%llu ck=%llu",
+ j++, ne->name, (unsigned long long)ne->fileid,
+ (unsigned long long)ne->cookie);
}
plog(XLOG_DEBUG, "EOF is %d", dp->eof);
}
@@ -793,14 +795,15 @@ amfs_readdir3_browsable(am_node *mp, am_cookie3 cookie,
}
static int
-amfs_readdir3(am_node *mp, am_cookie3 cookie,
+amfs_readdir3(am_node *mp, voidp cookie,
am_dirlist3 *dp, am_entry3 *ep, u_int count)
{
uint64 gen = *(uint64 *) cookie;
am_node *xp;
if (amuDebug(D_READDIR))
- plog(XLOG_DEBUG, "amfs_readdir3 gen=%lu, count=%d", gen, count);
+ plog(XLOG_DEBUG, "%s: gen=%llu, count=%d", __func__,
+ (unsigned long long)gen, count);
dp->eof = FALSE; /* assume readdir not done */
@@ -847,8 +850,9 @@ amfs_readdir3(am_node *mp, am_cookie3 cookie,
am_entry3 *ne;
int j;
for (j = 0, ne = ep; ne; ne = ne->nextentry) {
- plog(XLOG_DEBUG, "gen1 key %4d \"%s\" fi=%lu ck=%lu",
- j++, ne->name, ne->fileid, ne->cookie);
+ plog(XLOG_DEBUG, "gen1 key %4d \"%s\" fi=%llu ck=%llu",
+ j++, ne->name, (unsigned long long)ne->fileid,
+ (unsigned long long)ne->cookie);
}
}
return 0;
@@ -907,8 +911,9 @@ amfs_readdir3(am_node *mp, am_cookie3 cookie,
am_entry3 *ne;
int j;
for (j = 0, ne = ep; ne; ne = ne->nextentry) {
- plog(XLOG_DEBUG, "gen2 key %4d \"%s\" fi=%lu ck=%lu",
- j++, ne->name, ne->fileid, ne->cookie);
+ plog(XLOG_DEBUG, "gen2 key %4d \"%s\" fi=%llu ck=%llu",
+ j++, ne->name, (unsigned long long)ne->fileid,
+ (unsigned long long)ne->cookie);
}
}
return 0;
@@ -944,8 +949,8 @@ amfs_generic_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count)
return amfs_readdir(mp, cookie, dp, ep, count);
} else {
if (browsable)
- return amfs_readdir3_browsable(mp, (am_cookie3) cookie, dp, ep, count, full);
+ return amfs_readdir3_browsable(mp, cookie, dp, ep, count, full);
else
- return amfs_readdir3(mp, (am_cookie3) cookie, dp, ep, count);
+ return amfs_readdir3(mp, cookie, dp, ep, count);
}
}
diff --git a/amq/amq.c b/amq/amq.c
index 5d4ed7a..dc5fe02 100644
--- a/amq/amq.c
+++ b/amq/amq.c
@@ -79,7 +79,7 @@ enum show_opt {
static void
time_print(time_type tt)
{
- time_t t = (time_t)tt;
+ time_t t = (time_t)*tt;
struct tm *tp = localtime(&t);
printf("%02d/%02d/%04d %02d:%02d:%02d",
tp->tm_mon + 1, tp->tm_mday,

View file

@ -0,0 +1,64 @@
commit cb493f02ca3b8fbf0dba18d5a733345f54513300
Author: zoulasc <christos@zoulas.com>
Date: Mon Mar 7 18:03:19 2016 -0500
1. Add the "sys" alias for "unix", as well as "none", and "null"
2. Properly handle multiple flavors, although the linux kernel does not (yet?)
3. Don't add the "sec=" field, because it is already there.
diff --git a/libamu/mount_fs.c b/libamu/mount_fs.c
index 87f64c3..366eb8b 100644
--- a/libamu/mount_fs.c
+++ b/libamu/mount_fs.c
@@ -1076,7 +1076,10 @@ struct {
const char *name;
int num;
} flavours[] = {
+ { "none", AUTH_NONE },
+ { "null", AUTH_NULL },
{ "unix", AUTH_UNIX },
+ { "sys", AUTH_SYS },
{ "krb5", RPC_AUTH_GSS_KRB5 },
{ "krb5i", RPC_AUTH_GSS_KRB5I },
{ "krb5p", RPC_AUTH_GSS_KRB5P },
@@ -1104,12 +1107,13 @@ set_nfs4_security(nfs4_args_t *nap, mntent_t *mntp)
nap->auth_flavours = xmalloc(l * sizeof(*nap->auth_flavours));
s = ss = xstrdup(o);
+ l = 0;
for (;;) {
q = strchr(s, ',');
if (q)
*q = '\0';
- for (l = 0, i = 0; i < sizeof(flavours) / sizeof(flavours[0]); i++)
+ for (i = 0; i < sizeof(flavours) / sizeof(flavours[0]); i++)
if (strcmp(flavours[i].name, s) == 0) {
nap->auth_flavours[l++] = flavours[i].num;
break;
@@ -1125,6 +1129,9 @@ set_nfs4_security(nfs4_args_t *nap, mntent_t *mntp)
s = ++q;
}
+ if (l == 0) {
+ nap->auth_flavours[l++] = AUTH_UNIX;
+ }
nap->auth_flavourlen = l;
return ss;
}
@@ -1172,12 +1179,15 @@ add_nfs4_mntopts(const nfs4_args_t *nap, mntent_t *mntp, char *sec)
opts = xrealloc(mntp->mnt_opts, len);
xstrlcat(opts, buf, len);
+#ifdef notdef
+ /* Already in the options */
if (sec) {
xstrlcat(opts, ",", len);
xstrlcat(opts, MNTTAB_OPT_SEC, len);
xstrlcat(opts, "=", len);
xstrlcat(opts, sec, len);
}
+#endif
mntp->mnt_opts = opts;
}

View file

@ -0,0 +1,58 @@
commit 3369871a5e68484e231705bb0a893b4c6da85d17
Author: zoulasc <christos@zoulas.com>
Date: Mon Mar 7 18:05:07 2016 -0500
Default to "string" mount options for NFSv4 because the kernel does not
properly handle the auth_flavours[] field. Tested with nfs-utils-1.3.3 and
it always defaults to krb5i if string options are not used. Please note
that the "rw" option is not recognized by the linux kernel.
diff --git a/conf/mount/mount_linux.c b/conf/mount/mount_linux.c
index d3841ce..de7708d 100644
--- a/conf/mount/mount_linux.c
+++ b/conf/mount/mount_linux.c
@@ -450,7 +450,7 @@ do_mount_linux(MTYPE_TYPE type, mntent_t *mnt, int flags, caddr_t data)
return mount(mnt->mnt_fsname,
mnt->mnt_dir,
type,
- MS_MGC_VAL | flags,
+ flags,
data);
}
@@ -566,9 +566,9 @@ mount_linux_nfs(MTYPE_TYPE type, mntent_t *mnt, int flags, caddr_t data)
plog(XLOG_DEBUG, "%s: port %d\n", __func__,
htons(mnt_data->addr.sin_port));
}
+ flags |= MS_MGC_VAL;
if (amuDebug(D_TRACE)) {
- plog(XLOG_DEBUG, "%s: Generic mount flags 0x%x", __func__,
- MS_MGC_VAL | flags);
+ plog(XLOG_DEBUG, "%s: Generic mount flags 0x%x", __func__, flags);
plog(XLOG_DEBUG, "%s: updated nfs_args...", __func__);
print_nfs_args(mnt_data, 0);
}
@@ -610,14 +610,21 @@ mount_linux_nfs4(MTYPE_TYPE type, mntent_t *mnt, int flags, caddr_t data)
plog(XLOG_DEBUG, "%s: type %s\n", __func__, type);
plog(XLOG_DEBUG, "%s: version %d\n", __func__, mnt_data->version);
}
+#if 0
+ flags |= MS_MGC_VAL;
+#endif
if (amuDebug(D_TRACE)) {
- plog(XLOG_DEBUG, "%s: Generic mount flags 0x%x", __func__,
- MS_MGC_VAL | flags);
+ plog(XLOG_DEBUG, "%s: Generic mount flags 0x%x", __func__, flags);
plog(XLOG_DEBUG, "%s: updated nfs_args...", __func__);
print_nfs_args(mnt_data, NFS_VERSION4);
}
+#if 0
errorcode = do_mount_linux(type, mnt, flags, data);
+#else
+ errorcode = do_mount_linux(type, mnt, flags, mnt->mnt_opts);
+#endif
+
return errorcode;
}

View file

@ -0,0 +1,19 @@
commit 6a12fc0acb3afb654ba5e6efdeb28b943e2efd3e
Author: zoulasc <christos@zoulas.com>
Date: Thu Mar 31 14:56:53 2016 -0400
Fix SEGV on amq entries that print times.
diff --git a/amq/amq.c b/amq/amq.c
index dc5fe02..04f9e4d 100644
--- a/amq/amq.c
+++ b/amq/amq.c
@@ -79,7 +79,7 @@ enum show_opt {
static void
time_print(time_type tt)
{
- time_t t = (time_t)*tt;
+ time_t t = (time_t)(intptr_t)tt;
struct tm *tp = localtime(&t);
printf("%02d/%02d/%04d %02d:%02d:%02d",
tp->tm_mon + 1, tp->tm_mday,

View file

@ -0,0 +1,71 @@
commit 1c4c00a489d7aef115020b903dcd10201eb56ac0
Author: zoulasc <christos@zoulas.com>
Date: Thu Apr 30 14:24:39 2015 -0400
Fix nfs args setting code (raven at the maw dot net)
diff --git a/ChangeLog b/ChangeLog
index fd05087..64be682 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-30 Christos Zoulas <christos@zoulas.com>
+
+ * fix compilation error in nfs args set code.
+ (raven at themaw.net)
+
2015-01-17 Christos Zoulas <christos@zoulas.com>
* Move libtool macro functions from m4/macros to m4 and delete
diff --git a/libamu/mount_fs.c b/libamu/mount_fs.c
index b577bab..87f64c3 100644
--- a/libamu/mount_fs.c
+++ b/libamu/mount_fs.c
@@ -1001,12 +1001,12 @@ compute_nfs23_args(nfs_args_t *nap,
#ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */
if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL)))
- nap->args.flags |= MNT2_NFS_OPT_SYMTTL;
+ nap->flags |= MNT2_NFS_OPT_SYMTTL;
#endif /* MNTTAB_OPT_SYMTTL */
#ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */
if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH)))
- nap->args.flags |= MNT2_NFS_OPT_PGTHRESH;
+ nap->flags |= MNT2_NFS_OPT_PGTHRESH;
#endif /* MNT2_NFS_OPT_PGTHRESH */
#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
@@ -1029,12 +1029,12 @@ compute_nfs23_args(nfs_args_t *nap,
return;
}
/* update the flags field for knconf */
- nap->args.flags |= MNT2_NFS_OPT_KNCONF;
+ nap->flags |= MNT2_NFS_OPT_KNCONF;
#endif /* HAVE_TRANSPORT_TYPE_TLI */
#ifdef MNT2_NFS_OPT_FSNAME
nap->fsname = fs_name;
- nap->args.flags |= MNT2_NFS_OPT_FSNAME;
+ nap->flags |= MNT2_NFS_OPT_FSNAME;
#endif /* MNT2_NFS_OPT_FSNAME */
@@ -1323,7 +1323,7 @@ compute_nfs4_args(nfs4_args_t *nap,
#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) {
- nap->args.flags |= MNT2_NFS_OPT_POSIX;
+ nap->flags |= MNT2_NFS_OPT_POSIX;
# ifdef HAVE_NFS_ARGS_T_PATHCONF
nap->pathconf = NULL;
# endif /* HAVE_NFS_ARGS_T_PATHCONF */
@@ -1333,7 +1333,7 @@ compute_nfs4_args(nfs4_args_t *nap,
#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
if (nap->maxgrouplist != 0)
- nap->args.flags |= MNT2_NFS_OPT_MAXGRPS;
+ nap->flags |= MNT2_NFS_OPT_MAXGRPS;
#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
#ifdef HAVE_NFS_ARGS_T_OPTSTR

View file

@ -0,0 +1,36 @@
commit 227ce116a307a7f38967639c94ad74970ee83700
Author: zoulasc <christos@zoulas.com>
Date: Tue Mar 8 23:30:38 2016 -0500
Improve debugging for unmounting.
diff --git a/amd/map.c b/amd/map.c
index bcb2156..a6df44b 100644
--- a/amd/map.c
+++ b/amd/map.c
@@ -904,10 +904,8 @@ unmount_mp(am_node *mp)
int was_backgrounded = 0;
mntfs *mf = mp->am_al->al_mnt;
-#ifdef notdef
plog(XLOG_INFO, "\"%s\" on %s timed out (flags 0x%x)",
- mp->am_path, mf->mf_mount, (int) mf->mf_flags);
-#endif /* notdef */
+ mp->am_path, mf->mf_mount, (int) mf->mf_flags);
#ifndef MNT2_NFS_OPT_SYMTTL
/*
@@ -938,11 +936,12 @@ unmount_mp(am_node *mp)
plog(XLOG_STATS, "file server %s is down - timeout of \"%s\" ignored", mf->mf_server->fs_host, mp->am_path);
mf->mf_flags |= MFF_LOGDOWN;
}
+ dlog("\"%s\" on %s server is down, deferred", mp->am_path, mf->mf_mount);
notify_child(mp, AMQ_UMNT_SERVER, 0, 0);
return 0;
}
- dlog("\"%s\" on %s timed out", mp->am_path, mf->mf_mount);
+ dlog("\"%s\" on %s timed out, unmounting", mp->am_path, mf->mf_mount);
mf->mf_flags |= MFF_UNMOUNTING;
#ifdef HAVE_FS_AUTOFS

View file

@ -0,0 +1,530 @@
commit 1c9cd2d03ab1561b7eee831af381eff781fcf41e
Author: zoulasc <christos@zoulas.com>
Date: Fri Apr 8 15:29:33 2016 -0400
* Make hasmntval() return an 0 on error, 1 on success and
place the value in an argument. Update all users and
check properly for errors. Get rid of hasmntvalerr().
* Add hasmntvaldelim() which takes a string delimiter. This
is now used to chop vers=4.1 to 4, so that we can parse the
version correctly (we don't care about the .1 part yet)
---
amd/autil.c | 10 ++----
amd/ops_cdfs.c | 7 ++++
amd/ops_nfs.c | 3 --
amd/ops_pcfs.c | 10 ++++--
amd/ops_ufs.c | 6 +++-
amd/srvr_nfs.c | 24 ++++++++++------
hlfsd/hlfsd.c | 3 --
include/am_utils.h | 4 +-
libamu/mount_fs.c | 79 ++++++++++++++++++++++++++++++++++++++---------------
libamu/mtab.c | 41 ++++++++-------------------
10 files changed, 109 insertions(+), 78 deletions(-)
--- am-utils-6.2.orig/amd/autil.c
+++ am-utils-6.2/amd/autil.c
@@ -279,7 +279,7 @@ am_mounted(am_node *mp)
if (amu_hasmntopt(&mnt, "nounmount") || amu_hasmntopt(&mnt, "noumount"))
notimeout = 1;
/* utimeout=N option: user wants to unmount this option AND set timeout */
- if ((mp->am_timeo = hasmntval(&mnt, "utimeout")) == 0)
+ if (!hasmntval(&mnt, "utimeout", &mp->am_timeo))
mp->am_timeo = gopt.am_timeo; /* otherwise use default timeout */
else
notimeout = 0;
@@ -480,8 +480,7 @@ amfs_mount(am_node *mp, mntfs *mf, char
mnt.mnt_type = HIDE_MOUNT_TYPE;
}
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
+ if (!hasmntval(&mnt, MNTTAB_OPT_RETRY, &retry) || retry <= 0)
retry = 2; /* XXX: default to 2 retries */
/*
@@ -526,7 +525,7 @@ again:
nfs_args_t nfs_args;
am_nfs_handle_t *fhp, anh;
#ifndef HAVE_TRANSPORT_TYPE_TLI
- u_short port;
+ int port;
struct sockaddr_in sin;
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
@@ -547,8 +546,7 @@ again:
/* as per POSIX, sin_len need not be set (used internally by kernel) */
sin.sin_family = AF_INET;
sin.sin_addr = myipaddr;
- port = hasmntval(&mnt, MNTTAB_OPT_PORT);
- if (port) {
+ if (hasmntval(&mnt, MNTTAB_OPT_PORT, &port) && port > 0 && port < 65536) {
sin.sin_port = htons(port);
} else {
plog(XLOG_ERROR, "no port number specified for %s", dir);
--- am-utils-6.2.orig/amd/ops_cdfs.c
+++ am-utils-6.2/amd/ops_cdfs.c
@@ -190,7 +190,12 @@ mount_cdfs(char *mntdir, char *fs_name,
#endif /* HAVE_CDFS_ARGS_T_ISO_FLAGS */
#ifdef HAVE_CDFS_ARGS_T_ISO_PGTHRESH
- cdfs_args.iso_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
+ {
+ int thresh;
+ if (!hasmntval(&mnt, MNTTAB_OPT_PGTHRESH, &thresh) || thresh < 0)
+ thresh = 0;
+ cdfs_args.iso_pgthresh = thresh;
+ }
#endif /* HAVE_CDFS_ARGS_T_ISO_PGTHRESH */
#ifdef HAVE_CDFS_ARGS_T_NORRIP
--- am-utils-6.2.orig/amd/ops_nfs.c
+++ am-utils-6.2/amd/ops_nfs.c
@@ -888,8 +888,7 @@ mount_nfs_fh(am_nfs_handle_t *fhp, char
plog(XLOG_INFO, "mount_nfs_fh: NFS version %d", (int) nfs_version);
plog(XLOG_INFO, "mount_nfs_fh: using NFS transport %s", nfs_proto);
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
+ if (!hasmntval(&mnt, MNTTAB_OPT_RETRY, &retry) || retry <= 0)
retry = 1; /* XXX */
genflags = compute_mount_flags(&mnt);
--- am-utils-6.2.orig/amd/ops_pcfs.c
+++ am-utils-6.2/amd/ops_pcfs.c
@@ -139,17 +139,19 @@ mount_pcfs(char *mntdir, char *fs_name,
#endif /* HAVE_PCFS_ARGS_T_FSPEC */
#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)
+ if (hasmntval(&mnt, MNTTAB_OPT_MASK, &mask) && mask > 0)
pcfs_args.mask = mask;
+ else
+ pcfs_args.mask = 0777; /* this may be the msdos file modes */
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 */
- if ((mask = hasmntval(&mnt, MNTTAB_OPT_DIRMASK)) > 0)
+ if (hasmntval(&mnt, MNTTAB_OPT_DIRMASK, &mask) && mask > 0)
pcfs_args.dirmask = mask;
+ else
+ pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */
if (amuDebug(D_TRACE))
plog(XLOG_DEBUG, "mount_pcfs: dirmask=%o (octal)", (u_int) pcfs_args.dirmask);
#endif /* HAVE_PCFS_ARGS_T_DIRMASK */
--- am-utils-6.2.orig/amd/ops_ufs.c
+++ am-utils-6.2/amd/ops_ufs.c
@@ -144,7 +144,11 @@ mount_ufs(char *mntdir, char *fs_name, c
#endif /* HAVE_UFS_ARGS_T_FSPEC */
#ifdef HAVE_UFS_ARGS_T_UFS_PGTHRESH
- ufs_args.ufs_pgthresh = hasmntval(&mnt, MNTTAB_OPT_PGTHRESH);
+ {
+ int thresh;
+ if (!hasmntval(&mnt, MNTTAB_OPT_PGTHRESH, &thresh) || thresh < 0)
+ thresh = 0;
+ ufs_args.ufs_pgthresh = thresh;
#endif /* HAVE_UFS_ARGS_T_UFS_PGTHRESH */
/*
--- am-utils-6.2.orig/amd/srvr_nfs.c
+++ am-utils-6.2/amd/srvr_nfs.c
@@ -704,10 +704,10 @@ find_nfs_srvr(mntfs *mf)
struct hostent *hp = NULL;
struct sockaddr_in *ip = NULL;
u_long nfs_version = 0; /* default is no version specified */
+ int val;
u_long best_nfs_version = 0;
char *nfs_proto = NULL; /* no IP protocol either */
- int nfs_port = 0;
- int nfs_port_opt = 0;
+ int nfs_port;
int fserver_is_down = 0;
if (mf->mf_fo == NULL) {
@@ -721,7 +721,8 @@ find_nfs_srvr(mntfs *mf)
* are required or not. < 0 = no pings.
*/
mnt.mnt_opts = mf->mf_mopts;
- pingval = hasmntval(&mnt, "ping");
+ if (!hasmntval(&mnt, "ping", &pingval) || pingval < 0)
+ pingval = 0;
if (mf->mf_flags & MFF_NFS_SCALEDOWN) {
/*
@@ -739,7 +740,10 @@ find_nfs_srvr(mntfs *mf)
* to decide the highest NFS version to try.
*/
#ifdef MNTTAB_OPT_VERS
- nfs_version = hasmntval(&mnt, MNTTAB_OPT_VERS);
+ if (!hasmntvaldelim(&mnt, MNTTAB_OPT_VERS, ",.", &val) || val < 0)
+ nfs_version = 0;
+ else
+ nfs_version = val;
#endif /* MNTTAB_OPT_VERS */
#ifdef MNTTAB_OPT_PROTO
@@ -934,11 +938,11 @@ find_nfs_srvr(mntfs *mf)
* 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)
+ if (!hasmntval(&mnt, MNTTAB_OPT_PORT, &nfs_port)
+ || nfs_port > 65535 || nfs_port <= 0)
nfs_port = htons(NFS_PORT);
+ else
+ nfs_port = htons(nfs_port);
dlog("%s: using port %d for nfs on %s", __func__,
(int) ntohs(nfs_port), host);
@@ -1050,7 +1054,9 @@ no_dns:
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 = htons(hasmntval(&mnt, "mountport"));
+ if (!hasmntval(&mnt, "mountport", &val) || val < 0)
+ val = 0;
+ np->np_mountd = htons(val);
if (np->np_mountd == 0) {
np->np_mountd_inval = 'Y';
np->np_xid = XID_ALLOC();
--- am-utils-6.2.orig/hlfsd/hlfsd.c
+++ am-utils-6.2/hlfsd/hlfsd.c
@@ -530,8 +530,7 @@ main(int argc, char *argv[])
genflags = compute_mount_flags(&mnt);
- retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
- if (retry <= 0)
+ if (!hasmntval(&mnt, MNTTAB_OPT_RETRY, &retry) || retry <= 0)
retry = 1; /* XXX */
memmove(&anh.v2, root_fhp, sizeof(*root_fhp));
--- am-utils-6.2.orig/include/am_utils.h
+++ am-utils-6.2/include/am_utils.h
@@ -290,8 +290,8 @@ extern int compute_mount_flags(mntent_t
extern void discard_nfs_args(void *, u_long);
extern u_long get_amd_program_number(void);
extern int getcreds(struct svc_req *, uid_t *, gid_t *, SVCXPRT *);
-extern int hasmntval(mntent_t *, char *);
-extern unsigned int hasmntvalerr(mntent_t *, char *, int *);
+extern int hasmntval(mntent_t *, char *, int *);
+extern int hasmntvaldelim(mntent_t *, char *, const char *, int *);
extern char *hasmntstr(mntent_t *, char *);
extern char *hasmnteq(mntent_t *, char *);
extern char *haseq(char *);
--- am-utils-6.2.orig/libamu/mount_fs.c
+++ am-utils-6.2/libamu/mount_fs.c
@@ -188,8 +188,10 @@ static void
addvers(char *zopts, size_t l, mntent_t *mnt, u_long have_vers,
u_long want_vers)
{
- if (have_vers == want_vers &&
- hasmntval(mnt, MNTTAB_OPT_VERS) != want_vers) {
+ int val;
+ if (have_vers == want_vers
+ && hasmntvaldelim(mnt, MNTTAB_OPT_VERS, ".,", &val)
+ && (u_long)val != want_vers) {
char optsbuf[48];
xsnprintf(optsbuf, sizeof(optsbuf),
"%s=%d", MNTTAB_OPT_VERS, want_vers);
@@ -391,7 +393,7 @@ compute_nfs_attrcache_flags(struct nfs_c
* on the values of the attribute caches.
*/
#ifdef MNTTAB_OPT_ACTIMEO
- err_acval = hasmntvalerr(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */
+ err_acval = !hasmntval(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */
#endif /* MNTTAB_OPT_ACTIMEO */
/*** acregmin ***/
@@ -402,7 +404,7 @@ compute_nfs_attrcache_flags(struct nfs_c
} else {
# ifdef MNTTAB_OPT_ACREGMIN
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACREGMIN, &tmp);
nap->acregmin = tmp;
# else /* not MNTTAB_OPT_ACREGMIN */
nap->acregmin = 0;
@@ -423,7 +425,7 @@ compute_nfs_attrcache_flags(struct nfs_c
} else {
# ifdef MNTTAB_OPT_ACREGMAX
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACREGMAX, &tmp);
nap->acregmax = tmp;
# else /* not MNTTAB_OPT_ACREGMAX */
nap->acregmax = 0;
@@ -444,7 +446,7 @@ compute_nfs_attrcache_flags(struct nfs_c
} else {
# ifdef MNTTAB_OPT_ACDIRMIN
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACDIRMIN, &tmp);
nap->acdirmin = tmp;
# else /* not MNTTAB_OPT_ACDIRMIN */
nap->acdirmin = 0;
@@ -465,7 +467,7 @@ compute_nfs_attrcache_flags(struct nfs_c
} else {
# ifdef MNTTAB_OPT_ACDIRMAX
int tmp;
- err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, &tmp);
+ err_acrdmm = !hasmntval(mntp, MNTTAB_OPT_ACDIRMAX, &tmp);
nap->acdirmax = tmp;
# else /* not MNTTAB_OPT_ACDIRMAX */
nap->acdirmax = 0;
@@ -492,6 +494,7 @@ static void
compute_nfs_common_args(struct nfs_common_args *nap, mntent_t *mntp,
const char *nfs_proto, u_long nfs_version)
{
+ int val;
#ifdef MNT2_NFS_OPT_TCP
if (nfs_proto && STREQ(nfs_proto, "tcp"))
nap->flags |= MNT2_NFS_OPT_TCP;
@@ -536,7 +539,10 @@ compute_nfs_common_args(struct nfs_commo
# endif /* not MNTTAB_OPT_RESVPORT */
#endif /* MNT2_NFS_OPT_RESVPORT */
- nap->rsize = hasmntval(mntp, MNTTAB_OPT_RSIZE);
+ if (!hasmntval(mntp, MNTTAB_OPT_RSIZE, &val) || val <= 0)
+ nap->rsize = 0;
+ else
+ nap->rsize = val;
#ifdef MNT2_NFS_OPT_RSIZE
if (nap->rsize)
nap->flags |= MNT2_NFS_OPT_RSIZE;
@@ -544,7 +550,10 @@ compute_nfs_common_args(struct nfs_commo
if (nfs_version == NFS_VERSION && nap->rsize > 8192)
nap->rsize = 8192;
- nap->wsize = hasmntval(mntp, MNTTAB_OPT_WSIZE);
+ if (!hasmntval(mntp, MNTTAB_OPT_WSIZE, &val) || val <= 0)
+ nap->wsize = 0;
+ else
+ nap->wsize = val;
#ifdef MNT2_NFS_OPT_WSIZE
if (nap->wsize)
nap->flags |= MNT2_NFS_OPT_WSIZE;
@@ -552,13 +561,19 @@ compute_nfs_common_args(struct nfs_commo
if (nfs_version == NFS_VERSION && nap->wsize > 8192)
nap->wsize = 8192;
- nap->timeo = hasmntval(mntp, MNTTAB_OPT_TIMEO);
+ if (!hasmntval(mntp, MNTTAB_OPT_TIMEO, &val) || val <= 0)
+ nap->timeo = 0;
+ else
+ nap->timeo = val;
#ifdef MNT2_NFS_OPT_TIMEO
if (nap->timeo)
nap->flags |= MNT2_NFS_OPT_TIMEO;
#endif /* MNT2_NFS_OPT_TIMEO */
- nap->retrans = hasmntval(mntp, MNTTAB_OPT_RETRANS);
+ if (!hasmntval(mntp, MNTTAB_OPT_RETRANS, &val) || val <= 0)
+ nap->retrans = 0;
+ else
+ nap->retrans = val;
#ifdef MNT2_NFS_OPT_RETRANS
if (nap->retrans)
nap->flags |= MNT2_NFS_OPT_RETRANS;
@@ -861,6 +876,7 @@ compute_nfs23_args(nfs_args_t *nap,
char *host_name,
char *fs_name)
{
+ int val;
struct nfs_common_args a;
/* initialize just in case */
memset((voidp) nap, 0, sizeof(nfs_args_t));
@@ -995,18 +1011,30 @@ compute_nfs23_args(nfs_args_t *nap,
/************************************************************************/
#ifdef MNT2_NFS_OPT_BIODS
- if ((nap->biods = hasmntval(mntp, MNTTAB_OPT_BIODS)))
+ if (!hasmntval(mntp, MNTTAB_OPT_BIODS, &val) || val <= 0)
+ nap->biods = 0;
+ else {
+ nap->biods = val;
nap->flags |= MNT2_NFS_OPT_BIODS;
+ }
#endif /* MNT2_NFS_OPT_BIODS */
#ifdef MNTTAB_OPT_SYMTTL /* symlink cache time-to-live */
- if ((nap->symttl = hasmntval(mntp, MNTTAB_OPT_SYMTTL)))
+ if (!hasmntval(mntp, MNTTAB_OPT_SYMTTL, &val) || val <= 0)
+ nap->symttl = 0;
+ else {
+ nap->symttl = val;
nap->flags |= MNT2_NFS_OPT_SYMTTL;
+ }
#endif /* MNTTAB_OPT_SYMTTL */
#ifdef MNT2_NFS_OPT_PGTHRESH /* paging threshold */
- if ((nap->pg_thresh = hasmntval(mntp, MNTTAB_OPT_PGTHRESH)))
+ if (!hasmntval(mntp, MNTTAB_OPT_PGTHRESH, &val) || val <= 0)
+ nap->pg_thresh = 0;
+ else {
+ nap->pg_thresh = val;
nap->flags |= MNT2_NFS_OPT_PGTHRESH;
+ }
#endif /* MNT2_NFS_OPT_PGTHRESH */
#if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX)
@@ -1020,7 +1048,7 @@ compute_nfs23_args(nfs_args_t *nap,
#ifdef HAVE_TRANSPORT_TYPE_TLI
/* set up syncaddr field */
- nap->syncaddr = (struct netbuf *) NULL;
+ nap->syncaddr = NULL;
/* set up knconf field */
if (get_knetconfig(&nap->knconf, nfsncp, nfs_proto) < 0) {
@@ -1043,9 +1071,12 @@ compute_nfs23_args(nfs_args_t *nap,
#endif /* HAVE_NFS_ARGS_T_OPTSTR */
#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
- nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
- if (nap->maxgrouplist != 0)
+ if (!hasmntval(mntp, MNTTAB_OPT_MAXGROUPS, &val) || val <= 0)
+ nap->maxgrouplist = 0;
+ else {
+ nap->maxgrouplist = val;
nap->flags |= MNT2_NFS_OPT_MAXGRPS;
+ }
#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
/************************************************************************/
@@ -1267,6 +1298,7 @@ compute_nfs4_args(nfs4_args_t *nap,
{
char *s;
struct nfs_common_args a;
+ int val;
uint16_t nfs_port;
/* initialize just in case */
@@ -1304,11 +1336,10 @@ compute_nfs4_args(nfs4_args_t *nap,
nap->host_addr = xmalloc(nap->host_addrlen);
memcpy(nap->host_addr, ip_addr, nap->host_addrlen);
- nfs_port = hasmntval(mntp, MNTTAB_OPT_PORT);
- if (nfs_port == 0)
+ if (!hasmntval(mntp, MNTTAB_OPT_PORT, &val) || val <= 0 || val > 65536)
nfs_port = htons(NFS_PORT);
else
- nfs_port = htons(nfs_port);
+ nfs_port = htons(val);
((struct sockaddr_in *)nap->host_addr)->sin_port = nfs_port;
@@ -1341,9 +1372,13 @@ compute_nfs4_args(nfs4_args_t *nap,
#endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */
#if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS)
- nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS);
- if (nap->maxgrouplist != 0)
+ nap->maxgrouplist =
+ if (!hasmntval(mntp, MNTTAB_OPT_MAXGROUPS, &val) || val <= 0)
+ nap->maxgrouplist = 0;
+ else {
+ nap->maxgrouplist = val;
nap->flags |= MNT2_NFS_OPT_MAXGRPS;
+ }
#endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */
#ifdef HAVE_NFS_ARGS_T_OPTSTR
--- am-utils-6.2.orig/libamu/mtab.c
+++ am-utils-6.2/libamu/mtab.c
@@ -133,22 +133,12 @@ hasmnteq(mntent_t *mnt, char *opt)
/*
- * Wrapper around hasmntvalerr(), which retains backwards compatibiliy with
- * older use of hasmntval().
- *
- * XXX: eventually, all use of hasmntval() should be replaced with
- * hasmntvalerr().
+ * Wrapper around hasmntvaldelim(), which uses the standard "," delim
*/
int
-hasmntval(mntent_t *mnt, char *opt)
+hasmntval(mntent_t *mnt, char *opt, int *valp)
{
- int err, val = 0;
-
- err = hasmntvalerr(mnt, opt, &val);
- if (err) /* if there was an error (hasmntvalerr returned 1) */
- return 0; /* redundant: val==0 above, but leave here for clarity */
- /* otherwise there was no error */
- return val;
+ return hasmntvaldelim(mnt, opt, ",", valp);
}
@@ -158,36 +148,31 @@ hasmntval(mntent_t *mnt, char *opt)
* valp (argument won't be touched if no value is set, for example due to an
* error).
*
- * Returns non-zero (1) on error; returns 0 on success.
- *
- * XXX: eventually, all use of hasmntval() should be replaced with
- * hasmntvalerr().
+ * Returns 0 on error; returns 1 on success.
*/
-unsigned int
-hasmntvalerr(mntent_t *mnt, char *opt, int *valp)
+int
+hasmntvaldelim(mntent_t *mnt, char *opt, const char *delim, int *valp)
{
char *str = amu_hasmntopt(mnt, opt);
- int err = 1; /* 1 means no good value was set (an error) */
char *eq, *endptr;
long int i;
/* exit if no option specificed */
- if (!str) {
- goto out;
- }
+ if (!str)
+ return 0;
eq = hasmnteq(mnt, opt);
if (!eq) { /* no argument to option ('=' sign was missing) */
plog(XLOG_MAP, "numeric option to \"%s\" missing", opt);
- goto out;
+ return 0;
}
/* if got here, then we had an '=' after option name */
endptr = NULL;
i = strtol(eq, &endptr, 0); /* hex and octal allowed ;-) */
if (!endptr ||
- (endptr != eq && (*endptr == ',' || *endptr == '\0'))) {
+ (endptr != eq && (*endptr == '\0' || strchr(delim, *endptr)))) {
/*
* endptr set means strtol saw a non-digit. If the non-digit is a
* comma, it's probably the start of the next option. If the comma is
@@ -198,15 +183,13 @@ hasmntvalerr(mntent_t *mnt, char *opt, i
* string.
*/
*valp = (int) i; /* set good value */
- err = 0; /* no error */
+ return 1;
} else {
/* whatever was after the '=' sign wasn't a number */
plog(XLOG_MAP, "invalid numeric option in \"%s\": \"%s\"", opt, str);
/* fall through to error/exit processing */
+ return 0;
}
-
- out:
- return err;
}

View file

@ -0,0 +1,45 @@
commit e7d1bd38b1d1de6b1bec603eeff915ebb57f3c37
Author: zoulasc <christos@zoulas.com>
Date: Thu Mar 10 17:50:34 2016 -0500
- There is really no ti-rpc nfsv4, so don't send one; instead send a v3 for now.
diff --git a/amd/srvr_nfs.c b/amd/srvr_nfs.c
index b7c852c..1418a1a 100644
--- a/amd/srvr_nfs.c
+++ b/amd/srvr_nfs.c
@@ -140,6 +140,7 @@ create_ping_payload(u_long nfs_version)
{
XDR ping_xdr;
struct rpc_msg ping_msg;
+ int rpc_version;
/*
* Non nfs mounts like /afs/glue.umd.edu have ended up here.
@@ -150,7 +151,17 @@ create_ping_payload(u_long nfs_version)
} else
plog(XLOG_INFO, "%s: nfs_version: %d", __func__, (int) nfs_version);
- rpc_msg_init(&ping_msg, NFS_PROGRAM, nfs_version, NFSPROC_NULL);
+ /*
+ * There is really no ti-rpc version for NFSv4; most servers respond
+ * with "program unavailable", which is ok since we don't check the
+ * payload, we just care about the pings. Some servers though are
+ * antisocial (Isilon) and don't respond (which is their right to do).
+ * Eventually we should make a new mechanism to do server pings for
+ * NFSv4, but for now it is easiest to downgrade the RPC version to 3.
+ */
+ rpc_version = nfs_version == 4 ? 3 : nfs_version;
+
+ rpc_msg_init(&ping_msg, NFS_PROGRAM, rpc_version, NFSPROC_NULL);
/*
* Create an XDR endpoint
@@ -600,6 +611,7 @@ nfs_keepalive(voidp v)
case ENETUNREACH:
case EHOSTDOWN:
case EHOSTUNREACH:
+ dlog("Failed to NFS ping to %s (%d)", fs->fs_host, error);
np->np_ping = MAX_ALLOWED_PINGS; /* immediately down */
np->np_ttl = (time_t) 0;
/*

View file

@ -0,0 +1,30 @@
commit ad416c8656c2dff6f1bcffee8517284de94c9d92
Author: zoulasc <christos@zoulas.com>
Date: Thu May 12 10:21:55 2016 -0400
Update the ctime of the directory too, since it changed. From Mark Davies
diff --git a/amd/autil.c b/amd/autil.c
index 35d8708..f44a0e2 100644
--- a/amd/autil.c
+++ b/amd/autil.c
@@ -183,6 +183,7 @@ forcibly_timeout_mp(am_node *mp)
* more.
*/
clocktime(&mp->am_parent->am_fattr.na_mtime);
+ mp->am_parent->am_fattr.na_ctime = mp->am_parent->am_fattr.na_mtime;
reschedule_timeout_mp();
}
}
@@ -312,8 +313,10 @@ am_mounted(am_node *mp)
/*
* Update mtime of parent node (copying "struct nfstime" in '=' below)
*/
- if (mp->am_parent && mp->am_parent->am_al->al_mnt)
+ if (mp->am_parent && mp->am_parent->am_al->al_mnt) {
mp->am_parent->am_fattr.na_mtime = mp->am_fattr.na_mtime;
+ mp->am_parent->am_fattr.na_ctime = mp->am_fattr.na_mtime;
+ }
/*
* This is ugly, but essentially unavoidable

View file

@ -0,0 +1,241 @@
am-utils-6.2 - add NFSv3 nfs_quick_reply() functionality
From: Ian Kent <raven@themaw.net>
The implementation of the NFS v3 server does not use the hack needed
by the nfs_quick_reply() function.
Now that saving the current transort for later use by nfs_quick_reply()
avoids concurrency races it should be ok to use it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/nfs_prot_svc.c | 13 +++++
amd/nfs_subr.c | 137 +++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 120 insertions(+), 30 deletions(-)
diff --git a/amd/nfs_prot_svc.c b/amd/nfs_prot_svc.c
index cbde172..29b7551 100644
--- a/amd/nfs_prot_svc.c
+++ b/amd/nfs_prot_svc.c
@@ -180,7 +180,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
xdr_result = (xdrproc_t) xdr_diropres;
local = (nfssvcproc_t) nfsproc_lookup_2_svc;
/*
- * Cheap way to pass transp down to amfs_auto_lookuppn so it can
+ * Cheap way to pass transp down to amfs_auto_lookup so it can
* be stored in the am_node structure and later used for
* quick_reply().
*/
@@ -327,6 +327,8 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
xdrproc_t _xdr_argument, _xdr_result;
nfssvcproc_t local;
+ current_transp = NULL;
+
switch (rqstp->rq_proc) {
case AM_NFS3_NULL:
_xdr_argument = (xdrproc_t) xdr_void;
@@ -350,6 +352,12 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
_xdr_argument = (xdrproc_t) xdr_am_LOOKUP3args;
_xdr_result = (xdrproc_t) xdr_am_LOOKUP3res;
local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_lookup_3_svc;
+ /*
+ * Cheap way to pass transp down to amfs_auto_lookup so it can
+ * be stored in the am_node structure and later used for
+ * quick_reply().
+ */
+ current_transp = transp;
break;
case AM_NFS3_ACCESS:
@@ -476,6 +484,9 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
}
result = (*local) (&argument, rqstp);
+
+ current_transp = NULL;
+
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
svcerr_systemerr (transp);
}
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
index 07d960d..a383618 100644
--- a/amd/nfs_subr.c
+++ b/amd/nfs_subr.c
@@ -87,6 +87,9 @@ struct am_fh3 {
};
/* forward declarations */
+static int nfs_quick_reply2(am_node *mp, int error);
+static int nfs_quick_reply3(am_node *mp, int error);
+
/* converting am-filehandles to mount-points */
static am_node *fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop);
static am_node *fh_to_mp(am_nfs_fh *fhp);
@@ -255,46 +258,65 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
return &res;
}
-
void
nfs_quick_reply(am_node *mp, int error)
{
- SVCXPRT *transp = mp->am_transp;
- nfsdiropres res;
- xdrproc_t xdr_result = (xdrproc_t) xdr_diropres;
+ int ret;
/*
- * If there's a transp structure then we can reply to the client's
- * nfs lookup request.
+ * If there's no transp structure then we can't reply to the
+ * client's nfs lookup request.
*/
- if (transp) {
- if (error == 0) {
- /*
- * Construct a valid reply to a lookup request. Same
- * code as in nfsproc_lookup_2_svc() above.
- */
- mp_to_fh(mp, &res.dr_u.dr_drok_u.drok_fhandle);
- res.dr_u.dr_drok_u.drok_attributes = mp->am_fattr;
- res.dr_status = NFS_OK;
- } else
- /*
- * Return the error that was passed to us.
- */
- res.dr_status = nfs_error(error);
+ if (!mp->am_transp)
+ return;
+
+ if (nfs_dispatcher == nfs_program_2)
+ ret = nfs_quick_reply2(mp, error);
+ else
+ ret = nfs_quick_reply3(mp, error);
+
+ if (!ret)
+ svcerr_systemerr(mp->am_transp);
+
+ /*
+ * Free up transp. It's only used for one reply.
+ */
+ put_nfs_xprt(mp->am_transp);
+ mp->am_transp = NULL;
+ dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
+}
+
+static int
+nfs_quick_reply2(am_node *mp, int error)
+{
+ SVCXPRT *transp = mp->am_transp;
+ nfsdiropres res;
+ xdrproc_t xdr_result = (xdrproc_t) xdr_diropres;
+ int ret;
+
+ if (error == 0) {
/*
- * Send off our reply
+ * Construct a valid reply to a lookup request. Same
+ * code as in nfsproc_lookup_2_svc() above.
*/
- if (!svc_sendreply(transp, (XDRPROC_T_TYPE) xdr_result, (SVC_IN_ARG_TYPE) & res))
- svcerr_systemerr(transp);
-
+ mp_to_fh(mp, &res.dr_u.dr_drok_u.drok_fhandle);
+ res.dr_u.dr_drok_u.drok_attributes = mp->am_fattr;
+ res.dr_status = NFS_OK;
+ } else
/*
- * Free up transp. It's only used for one reply.
+ * Return the error that was passed to us.
*/
- put_nfs_xprt(mp->am_transp);
- mp->am_transp = NULL;
- dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
- }
+ res.dr_status = nfs_error(error);
+
+ /*
+ * Send off our reply
+ */
+ ret = svc_sendreply(transp,
+ (XDRPROC_T_TYPE) xdr_result,
+ (SVC_IN_ARG_TYPE) & res);
+
+ return ret;
}
@@ -890,6 +912,8 @@ mp_to_fh(am_node *mp, am_nfs_fh *fhp)
/* dlog("mp_to_fh: old filehandle: %d", fp->u.s.fhh_id); */
}
}
+
+
void
mp_to_fh3(am_node *mp, am_nfs_fh3 *fhp)
{
@@ -1257,6 +1281,61 @@ am_nfs3_lookup_3_svc(am_LOOKUP3args *argp, struct svc_req *rqstp)
return &result;
}
+
+static int
+nfs_quick_reply3(am_node *mp, int error)
+{
+ SVCXPRT *transp = mp->am_transp;
+ xdrproc_t xdr_result = (xdrproc_t) xdr_am_LOOKUP3res;
+ am_LOOKUP3res result;
+ am_post_op_attr *post_op_dir;
+ am_post_op_attr *post_op_obj;
+ int ret;
+
+ if (error) {
+ /*
+ * Return the error that was passed to us.
+ */
+ post_op_dir->attributes_follow = 0;
+ result.status = nfs_error(error);
+ } else {
+ post_op_dir = &result.res_u.ok.dir_attributes;
+ post_op_obj = &result.res_u.ok.obj_attributes;
+ am_fattr3 *fattr3;
+ nfsfattr *fattr;
+
+ /*
+ * Construct a valid reply to a lookup request. Same
+ * code as in am_nfs3_lookup_3_svc() above.
+ */
+
+ /* dir attributes */
+ post_op_dir->attributes_follow = 1;
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ parent_fattr_to_fattr3(mp, fattr3);
+
+ mp_to_fh3(mp, &result.res_u.ok.object);
+
+ /* mount attributes */
+ post_op_obj->attributes_follow = 1;
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ result.status = AM_NFS3_OK;
+ }
+
+ /*
+ * Send off our reply
+ */
+ ret = svc_sendreply(transp,
+ (XDRPROC_T_TYPE) xdr_result,
+ (SVC_IN_ARG_TYPE) &result);
+
+ return ret;
+}
+
+
am_ACCESS3res *
am_nfs3_access_3_svc(am_ACCESS3args *argp, struct svc_req *rqstp)
{

View file

@ -0,0 +1,127 @@
am-utils-6.2 - add NFSv3 rpc request validation
From: Ian Kent <raven@themaw.net>
The NFS v2 internal server uses several validation checks for each
RPC request it receives, also add this validation for the NFS v3
internal server.
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/nfs_prot_svc.c | 65 +++++++++++++++++++++++++++++++---------------------
1 file changed, 39 insertions(+), 26 deletions(-)
diff --git a/amd/nfs_prot_svc.c b/amd/nfs_prot_svc.c
index 29b7551..cae12d4 100644
--- a/amd/nfs_prot_svc.c
+++ b/amd/nfs_prot_svc.c
@@ -71,30 +71,9 @@ dispatcher_t nfs_dispatcher = nfs_program_2;
typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
-void
-nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
+static int
+validate_rpc_request(struct svc_req *rqstp, SVCXPRT *transp)
{
- union {
- am_nfs_fh nfsproc_getattr_2_arg;
- nfssattrargs nfsproc_setattr_2_arg;
- nfsdiropargs nfsproc_lookup_2_arg;
- am_nfs_fh nfsproc_readlink_2_arg;
- nfsreadargs nfsproc_read_2_arg;
- nfswriteargs nfsproc_write_2_arg;
- nfscreateargs nfsproc_create_2_arg;
- nfsdiropargs nfsproc_remove_2_arg;
- nfsrenameargs nfsproc_rename_2_arg;
- nfslinkargs nfsproc_link_2_arg;
- nfssymlinkargs nfsproc_symlink_2_arg;
- nfscreateargs nfsproc_mkdir_2_arg;
- nfsdiropargs fsproc_rmdir_2_arg;
- nfsreaddirargs nfsproc_readdir_2_arg;
- am_nfs_fh nfsproc_statfs_2_arg;
- } argument;
- char *result;
- xdrproc_t xdr_argument, xdr_result;
- nfssvcproc_t local;
-
#ifdef HAVE_TRANSPORT_TYPE_TLI
/*
* On TLI systems we don't use an INET network type, but a "ticlts" (see
@@ -109,7 +88,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
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;
+ return 0;
}
# else /* not HAVE___RPC_GET_LOCAL_UID */
dlog("cannot verify local uid for rpc request");
@@ -126,7 +105,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
ntohs(sinp->sin_port));
- return;
+ return 0;
}
# endif /* MNT2_NFS_OPT_RESVPORT */
/* if the address does not match, ignore the request */
@@ -136,16 +115,47 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
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));
+ return 0;
}
} 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;
+ return 0;
}
}
#endif /* not HAVE_TRANPORT_TYPE_TLI */
+ return 1;
+}
+
+
+void
+nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
+{
+ union {
+ am_nfs_fh nfsproc_getattr_2_arg;
+ nfssattrargs nfsproc_setattr_2_arg;
+ nfsdiropargs nfsproc_lookup_2_arg;
+ am_nfs_fh nfsproc_readlink_2_arg;
+ nfsreadargs nfsproc_read_2_arg;
+ nfswriteargs nfsproc_write_2_arg;
+ nfscreateargs nfsproc_create_2_arg;
+ nfsdiropargs nfsproc_remove_2_arg;
+ nfsrenameargs nfsproc_rename_2_arg;
+ nfslinkargs nfsproc_link_2_arg;
+ nfssymlinkargs nfsproc_symlink_2_arg;
+ nfscreateargs nfsproc_mkdir_2_arg;
+ nfsdiropargs fsproc_rmdir_2_arg;
+ nfsreaddirargs nfsproc_readdir_2_arg;
+ am_nfs_fh nfsproc_statfs_2_arg;
+ } argument;
+ char *result;
+ xdrproc_t xdr_argument, xdr_result;
+ nfssvcproc_t local;
+
+ if (!validate_rpc_request(rqstp, transp))
+ return;
current_transp = NULL;
@@ -327,6 +337,9 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
xdrproc_t _xdr_argument, _xdr_result;
nfssvcproc_t local;
+ if (!validate_rpc_request(rqstp, transp))
+ return;
+
current_transp = NULL;
switch (rqstp->rq_proc) {

View file

@ -0,0 +1,170 @@
am-utils-6.2 - add get_nfs_xprt() and put_nfs_xprt() functions
From: Ian Kent <raven@themaw.net>
The nfs_quick_reply() functionality relies on taking a copy of the
current transport for later use.
The problem with this is the context of the RPC message is kept in
the transport and if any RPC message arrives before nfs_quick_reply()
is called that context will be corrupted.
So add a function get_nfs_xprt() to replace the current transport
with a new one returning the passed in transort so nfs_quick_reply()
can use it later.
A function put_nfs_xprt() is also added (although not really needed
since it just destroys the now unused transport) for completeness.
Signed-off-by: Ian Kent <raven@themaw.net>
---
conf/transp/transp_sockets.c | 44 ++++++++++++++++++++++++++++++++++++++++
conf/transp/transp_tli.c | 46 +++++++++++++++++++++++++++++++++++++++++-
include/am_utils.h | 2 ++
3 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/conf/transp/transp_sockets.c b/conf/transp/transp_sockets.c
index 6326007..a6e0054 100644
--- a/conf/transp/transp_sockets.c
+++ b/conf/transp/transp_sockets.c
@@ -45,6 +45,7 @@
#include <am_defs.h>
#include <amu.h>
+static int soNFS = RPC_ANYSOCK;
/*
* find the IP address that can be used to connect to the local host
@@ -273,9 +274,52 @@ create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*
return 3;
}
+ soNFS = *soNFSp;
+
return 0; /* all is well */
}
+/*
+ * Get a pointer to the current NFS SVCXPRT and replace it
+ * with a new one.
+ */
+SVCXPRT *
+get_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ SVCXPRT *newxprt;
+ int newfd;
+
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return NULL;
+
+ newfd = dup(soNFS);
+ if (newfd < 0)
+ return NULL;
+
+ xprt_unregister(nfs_xprt);
+ newxprt = svcudp_create(newfd);
+ if (!newxprt) {
+ plog(XLOG_FATAL, "Can't switch to new transport");
+ xprt_register(nfs_xprt);
+ close(newfd);
+ return NULL;
+ }
+
+ soNFS = newfd;
+
+ return nfs_xprt;
+}
+
+/*
+ * Destroy a transport previously obtained by get_nfs_xprt().
+ */
+void put_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return;
+
+ svc_destroy(nfs_xprt);
+}
/*
* Create the amq service for amd (both TCP and UDP)
diff --git a/conf/transp/transp_tli.c b/conf/transp/transp_tli.c
index d26a511..bfdb526 100644
--- a/conf/transp/transp_tli.c
+++ b/conf/transp/transp_tli.c
@@ -45,7 +45,8 @@
#include <am_defs.h>
#include <amu.h>
-struct netconfig *nfsncp;
+struct netconfig *nfsncp = NULL;
+static int soNFS = RPC_ANYSOCK;
/*
@@ -456,9 +457,52 @@ create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*
return 1;
}
+ soNFS = *soNFSp;
+
return 0; /* all is well */
}
+/*
+ * Get a pointer to the current NFS SVCXPRT and replace it
+ * with a new one.
+ */
+SVCXPRT *
+get_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ SVCXPRT *newxprt;
+ int newfd;
+
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return NULL;
+
+ newfd = dup(soNFS);
+ if (newfd < 0)
+ return NULL;
+
+ xprt_unregister(nfs_xprt);
+ newxprt = svc_tli_create(newfd, nfsncp, NULL, 0, 0);
+ if (!newxprt) {
+ plog(XLOG_FATAL, "Can't switch to new transport");
+ xprt_register(nfs_xprt);
+ close(newfd);
+ return NULL;
+ }
+
+ soNFS = newfd;
+
+ return nfs_xprt;
+}
+
+/*
+ * Destroy a transport previously obtained by get_nfs_xprt().
+ */
+void put_nfs_xprt(SVCXPRT *nfs_xprt)
+{
+ if (!nfs_xprt || soNFS == RPC_ANYSOCK)
+ return;
+
+ svc_destroy(nfs_xprt);
+}
/*
* Bind to preferred AMQ port.
diff --git a/include/am_utils.h b/include/am_utils.h
index 0de881a..ff13c26 100644
--- a/include/am_utils.h
+++ b/include/am_utils.h
@@ -378,6 +378,8 @@ extern void compute_nfs_args(void *nap, mntent_t *mntp, int genflags, struct net
extern void destroy_nfs_args(void *nap, u_long nfs_version);
extern int create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, struct netconfig **udp_amqncpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp, struct netconfig **tcp_amqncpp, u_short preferred_amq_port);
extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp), u_long nfs_version);
+extern SVCXPRT *get_nfs_xprt(SVCXPRT *nfs_xprt);
+extern void put_nfs_xprt(SVCXPRT *nfs_xprt);
extern int amu_svc_register(SVCXPRT *, u_long, u_long, void (*)(struct svc_req *, SVCXPRT *), u_long, struct netconfig *);
#ifdef HAVE_TRANSPORT_TYPE_TLI

View file

@ -0,0 +1,94 @@
commit a5ea57a64a1d70486e8d8ab2da944e50ca51b836
Author: zoulasc <christos@zoulas.com>
Date: Tue Mar 8 23:31:26 2016 -0500
- add more debugging in the unmount path
- if the EXPIRE_MULTI call fails, with EAGAIN, fail back to the EXPIRE call
seems to fix unmounting with nfsv4 volumes.
diff --git a/conf/autofs/autofs_linux.c b/conf/autofs/autofs_linux.c
index d543979..5b4ac06 100644
--- a/conf/autofs/autofs_linux.c
+++ b/conf/autofs/autofs_linux.c
@@ -365,6 +365,7 @@ autofs_expire_one(am_node *mp, char *name, autofs_wqt_t token)
ap = find_ap(ap_path);
if (ap == NULL) {
+ dlog("%s: could not find %s", __func__, ap_path);
/* not found??? not sure what to do here... */
send_fail(fh->ioctlfd, token);
goto out;
@@ -376,6 +377,7 @@ autofs_expire_one(am_node *mp, char *name, autofs_wqt_t token)
p->next = fh->pending_umounts;
fh->pending_umounts = p;
+ dlog("%s: unmount for %s", __func__, ap_path);
unmount_mp(ap);
out:
@@ -426,6 +428,7 @@ autofs_missing_one(am_node *mp, autofs_wqt_t wait_queue_token, char *name)
dlog("Mount still pending, not sending autofs reply yet");
return;
}
+ dlog("%s: lookup failed for %s/%s", __func__, mp->am_path, name);
autofs_lookup_failed(mp, name);
}
mp->am_stats.s_lookup++;
@@ -872,15 +875,42 @@ autofs_compute_mount_flags(mntent_t *mnt)
return 0;
}
+static int autofs_expire_4(am_node *mp)
+{
+ struct autofs_packet_expire pkt;
+ autofs_fh_t *fh = mp->am_autofs_fh;
+
+ dlog("Calling AUTOFS_IOC_EXPIRE");
+ if (ioctl(fh->ioctlfd, AUTOFS_IOC_EXPIRE, &pkt) == -1)
+ {
+ dlog("AUTOFS_IOC_EXPIRE for %s failed %d", mp->am_path, errno);
+ return -1;
+ }
+
+ autofs_handle_expire(mp, &pkt);
+ return 0;
+}
+
#if AUTOFS_MAX_PROTO_VERSION >= 4
static int autofs_timeout_mp_task(void *arg)
{
am_node *mp = (am_node *)arg;
autofs_fh_t *fh = mp->am_autofs_fh;
- int now = 0;
-
- while (ioctl(fh->ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &now) == 0);
+ int how = AUTOFS_EXP_IMMEDIATE;
+
+ for (;;)
+ {
+ dlog("Calling AUTOFS_IOC_EXPIRE_MULTI");
+ if (ioctl(fh->ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &how) == -1)
+ {
+ dlog("AUTOFS_IOC_EXPIRE_MULTI for %s failed %d", mp->am_path, errno);
+ if (errno != EAGAIN)
+ break;
+ if (autofs_expire_4(mp) == -1)
+ break;
+ }
+ }
return 0;
}
#endif /* AUTOFS_MAX_PROTO_VERSION >= 4 */
@@ -895,9 +925,8 @@ void autofs_timeout_mp(am_node *mp)
mp->am_autofs_ttl = now + gopt.am_timeo_w;
if (fh->version < 4) {
- struct autofs_packet_expire pkt;
- while (ioctl(fh->ioctlfd, AUTOFS_IOC_EXPIRE, &pkt) == 0)
- autofs_handle_expire(mp, &pkt);
+ while (autofs_expire_4(mp) == 0)
+ continue;
return;
}

View file

@ -0,0 +1,19 @@
commit a187041e062c5b656def30a3ec282156360003f3
Author: Christos Zoulas <christos@zoulas.com>
Date: Wed Jan 21 23:28:46 2015 -0500
don't use logical && when & is meant
diff --git a/amd/map.c b/amd/map.c
index fce8273..0d404cf 100644
--- a/amd/map.c
+++ b/amd/map.c
@@ -752,7 +752,7 @@ umount_exported(void)
} else {
am_unmounted(mp);
}
- if (!(mf->mf_flags && (MFF_UNMOUNTING|MFF_MOUNTED)))
+ if (!(mf->mf_flags & (MFF_UNMOUNTING|MFF_MOUNTED)))
exported_ap[i] = NULL;
} else {
/*

View file

@ -0,0 +1,39 @@
am-utils-6.2 - fix Linux NFS recognition of umounts
From: Ian Kent <raven@themaw.net>
Recent Linux NFS uses a simulated attibute cache change detection
method based on ctime. Consequenty the amd use of mtime for this
doesn't work properly for some kernel versions.
The problem seen with some kernel versions is a failure to recognize
umounts.
Updating the parent ctime in step with mtime during umount appears
to fix the problem.
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/autil.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/amd/autil.c b/amd/autil.c
index cd9514d..efd18ef 100644
--- a/amd/autil.c
+++ b/amd/autil.c
@@ -709,10 +709,13 @@ am_unmounted(am_node *mp)
--mp->am_parent->am_fattr.na_nlink;
/*
- * Update mtime of parent node
+ * Update mtime and ctime of parent node (as ctime is needed for some
+ * Linux NFS kernel versions to properly recognize attribute changes).
*/
- if (mp->am_parent && mp->am_parent->am_al->al_mnt)
+ if (mp->am_parent && mp->am_parent->am_al->al_mnt) {
clocktime(&mp->am_parent->am_fattr.na_mtime);
+ mp->am_parent->am_fattr.na_ctime = mp->am_parent->am_fattr.na_mtime;
+ }
if (mp->am_parent && (mp->am_flags & AMF_REMOUNT)) {
char *fname = xstrdup(mp->am_name);

View file

@ -0,0 +1,57 @@
am-utils-6.2 - fix compiler assignment warning due to libtirpc
From: Ian Kent <raven@themaw.net>
When using libtirpc there is a compiler warning on an assignment in
the amq_program_1() function.
This warning was due to libtirpc using struct sockaddr_in6 for some
address fields in the transport structure as it is backward compatible
with struct sockaddr_in when IPv4 is in use.
But if TLI is in use svc_getcaller() may not be defined or, if it is,
doesn't work as expected.
So change to using amu_svc_getcaller(), which deals with the needed
cast for libtirpc, and handle the NULL return if TLI is being used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/amq_svc.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/amd/amq_svc.c b/amd/amq_svc.c
index 1f2b3d6..40f79fa 100644
--- a/amd/amq_svc.c
+++ b/amd/amq_svc.c
@@ -162,15 +162,21 @@ amq_program_1(struct svc_req *rqstp, SVCXPRT *transp)
#if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
if (gopt.flags & CFM_USE_TCPWRAPPERS) {
- struct sockaddr_in *remote_addr = svc_getcaller(rqstp->rq_xprt);
- char *remote_hostname = inet_ntoa(remote_addr->sin_addr);
-
- if (!amqsvc_is_client_allowed(remote_addr)) {
- plog(XLOG_WARNING, "Amd denied remote amq service to %s", remote_hostname);
- svcerr_auth(transp, AUTH_FAILED);
- return;
- } else {
- dlog("Amd allowed remote amq service to %s", remote_hostname);
+ struct sockaddr_in *remote_addr = amu_svc_getcaller(rqstp->rq_xprt);
+ char *remote_hostname;
+
+ /* Check the return from amu_svc_getcaller() becuase it's always NULL
+ * if TLI is in use.
+ */
+ if (remote_addr) {
+ remote_hostname = inet_ntoa(remote_addr->sin_addr);
+ if (!amqsvc_is_client_allowed(remote_addr)) {
+ plog(XLOG_WARNING, "Amd denied remote amq service to %s", remote_hostname);
+ svcerr_auth(transp, AUTH_FAILED);
+ return;
+ } else {
+ dlog("Amd allowed remote amq service to %s", remote_hostname);
+ }
}
}
#endif /* defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP) */

View file

@ -0,0 +1,24 @@
am-utils-6.2 - fix logical not comparison in get_ldap_timestamp()
From: Ian Kent <raven@themaw.net>
Looks like the not in this comparison is not meant to be applied to *ts.
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/info_ldap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/amd/info_ldap.c b/amd/info_ldap.c
index cfed6fd..ecfc210 100644
--- a/amd/info_ldap.c
+++ b/amd/info_ldap.c
@@ -446,7 +446,7 @@ get_ldap_timestamp(ALD *a, char *map, time_t *ts)
vals[0], map);
err = ENOENT;
}
- if (!*ts > 0) {
+ if (!(*ts > 0)) {
plog(XLOG_USER, "Nonpositive timestamp %ld for map %s\n",
(u_long) *ts, map);
err = ENOENT;

View file

@ -0,0 +1,123 @@
am-utils-6.2 - fix umount to mount race
From: Ian Kent <raven@themaw.net>
If a mount request arrives while its mount fs is being umounted the
the reference count of the mount fs never reaches 1 so the location
MF_MOUNTED is not cleared and the mount fs instance is not freed.
This leads to amd thinking the mount fs is still mounted and the
mount request succeeds without its corresponding target being
mounted.
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/amd.h | 1 +
amd/amfs_generic.c | 10 +++++++---
amd/autil.c | 9 +++++++++
amd/map.c | 13 ++++++++++++-
4 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/amd/amd.h b/amd/amd.h
index f66f5b7..504bcf7 100644
--- a/amd/amd.h
+++ b/amd/amd.h
@@ -112,6 +112,7 @@
#define AMF_AUTOFS 0x0004 /* This node is part of an autofs filesystem */
#define AMF_REMOUNT 0x0008 /* This node needs to be remounted */
#define AMF_SOFTLOOKUP 0x0010 /* This node returns EIO if server is down */
+#define AMF_SOFTUNMOUNT 0x0020 /* unmount_node() returned EAGAIN, mount still referenced */
/*
* macros for struct mntfs (list of mounted filesystems)
diff --git a/amd/amfs_generic.c b/amd/amfs_generic.c
index 86d0ab7..7ab2829 100644
--- a/amd/amfs_generic.c
+++ b/amd/amfs_generic.c
@@ -178,7 +178,7 @@ amfs_lookup_node(am_node *mp, char *fname, int *error_return)
error = mf->mf_error;
continue;
}
- if (!(mf->mf_flags & MFF_MOUNTED) || (mf->mf_flags & MFF_UNMOUNTING)) {
+ if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) {
in_progrss:
/*
* If the fs is not mounted or it is unmounting then there
@@ -743,9 +743,13 @@ amfs_bgmount(struct continuation *cp)
if (mf->mf_flags & (MFF_MOUNTING | MFF_UNMOUNTING)) {
/*
- * Still mounting - retry later
+ * Still mounting or umounting - retry later
*/
- dlog("mount of \"%s\" already pending", mf->mf_info);
+ if (mf->mf_flags & MFF_MOUNTING) {
+ dlog("mount of \"%s\" already pending", mf->mf_info);
+ } else {
+ dlog("unmount of \"%s\" already pending", mf->mf_info);
+ }
goto retry;
}
diff --git a/amd/autil.c b/amd/autil.c
index f44a0e2..1962c71 100644
--- a/amd/autil.c
+++ b/amd/autil.c
@@ -703,6 +703,15 @@ am_unmounted(am_node *mp)
}
/*
+ * Clear the mounted flag in case there is a pending mount with
+ * the same target fs and this is the last reference to it.
+ */
+ if (mp->am_flags & AMF_SOFTUNMOUNT)
+ mp->am_flags &= ~AMF_SOFTUNMOUNT;
+ else
+ mf->mf_flags &= ~MFF_MOUNTED;
+
+ /*
* If this is a pseudo-directory then adjust the link count
* in the parent
*/
diff --git a/amd/map.c b/amd/map.c
index a6df44b..cf5263e 100644
--- a/amd/map.c
+++ b/amd/map.c
@@ -819,11 +819,17 @@ unmount_node(opaque_t arg)
#endif /* HAVE_FS_AUTOFS */
if (mf->mf_refc == 1)
error = mf->mf_ops->umount_fs(mp, mf);
+
+ /* Mount was not actually unmounted, soft umount.
+ * Tell the caller about it.
+ */
+ if (!error && mf->mf_refc > 1)
+ error = EAGAIN;
}
/* do this again, it might have changed */
mf = mp->am_al->al_mnt;
- if (error) {
+ if (error && error != EAGAIN) {
errno = error; /* XXX */
dlog("%s: unmount: %m", mf->mf_mount);
}
@@ -870,6 +876,10 @@ free_map_if_success(int rc, int term, opaque_t arg)
#endif /* HAVE_FS_AUTOFS */
amd_stats.d_uerr++;
} else if (rc) {
+ if (rc == EAGAIN) {
+ mp->am_flags |= AMF_SOFTUNMOUNT;
+ goto done;
+ }
notify_child(mp, AMQ_UMNT_FAILED, rc, 0);
if (mf->mf_ops == &amfs_program_ops || rc == EBUSY)
plog(XLOG_STATS, "\"%s\" on %s still active", mp->am_path, mf->mf_mount);
@@ -885,6 +895,7 @@ free_map_if_success(int rc, int term, opaque_t arg)
#endif /* HAVE_FS_AUTOFS */
amd_stats.d_uerr++;
} else {
+done:
/*
* am_unmounted() will call notify_child() appropriately.
*/

View file

@ -0,0 +1,52 @@
am-utils-6.2 - fix wcc attr usage in unlink3_or_rmdir3()
From: Ian Kent <raven@themaw.net>
The definition of the wcc post op attributes should be am_fattr3 not
am_wcc_attr in unlink3_or_rmdir3().
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/nfs_subr.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
index a383618..b88a40c 100644
--- a/amd/nfs_subr.c
+++ b/amd/nfs_subr.c
@@ -1058,7 +1058,8 @@ static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
am_pre_op_attr *pre_op_dir = &wcc_data->before;
am_post_op_attr *post_op_dir = &wcc_data->after;
nfsfattr *fattr;
- am_wcc_attr *pre_op_wcc_attr, *post_op_wcc_attr;
+ am_wcc_attr *pre_op_wcc_attr;
+ am_fattr3 *post_op_wcc_attr;
am_node *mp, *ap;
int retry;
@@ -1085,7 +1086,7 @@ static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
fattr_to_wcc_attr(fattr, pre_op_wcc_attr);
if (mp->am_fattr.na_type != NFDIR) {
- fattr_to_wcc_attr(fattr, post_op_wcc_attr);
+ fattr_to_fattr3(fattr, post_op_wcc_attr);
res = nfs_error(ENOTDIR);
goto out;
}
@@ -1105,14 +1106,14 @@ static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
*/
else if (retry == ENOENT)
retry = 0;
- fattr_to_wcc_attr(fattr, post_op_wcc_attr);
+ fattr_to_fattr3(fattr, post_op_wcc_attr);
res = nfs_error(retry);
} else {
forcibly_timeout_mp(mp);
/* we can't wait for the expire so use the attributes as
* they are now for the post op wcc attributes.
*/
- fattr_to_wcc_attr(fattr, post_op_wcc_attr);
+ fattr_to_fattr3(fattr, post_op_wcc_attr);
res = AM_NFS3_OK;
}

View file

@ -0,0 +1,20 @@
commit 54da7c8206e38d0bf08a250835553754a1235360
Author: Christos Zoulas <christos@zoulas.com>
Date: Wed Jan 21 23:28:33 2015 -0500
make sure variables are initialized
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
index 7192a6a..30effba 100644
--- a/amd/nfs_subr.c
+++ b/amd/nfs_subr.c
@@ -1711,6 +1711,9 @@ am_nfs3_fsstat_3_svc(am_FSSTAT3args *argp, struct svc_req *rqstp)
if ((gopt.flags & CFM_SHOW_STATFS_ENTRIES) &&
mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) {
mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts;
+ blocks = 0;
+ bfree = 0;
+ bavail = 0;
if (amu_hasmntopt(&mnt, "browsable")) {
count_map_entries(mp, &blocks, &bfree, &bavail);
}

View file

@ -0,0 +1,26 @@
commit 116309607c437e302dafa1efb60330f54f815761
Author: Christos Zoulas <christos@zoulas.com>
Date: Sat Jan 17 12:21:24 2015 -0500
print_nfs_common_args() is only needed with DEBUG
diff --git a/libamu/mount_fs.c b/libamu/mount_fs.c
index b5576bd..b577bab 100644
--- a/libamu/mount_fs.c
+++ b/libamu/mount_fs.c
@@ -647,6 +647,7 @@ compute_nfs_common_args(struct nfs_common_args *nap, mntent_t *mntp,
#endif /* defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) */
}
+#ifdef DEBUG
static void
print_nfs_common_args(const struct nfs_common_args *a)
{
@@ -664,6 +665,7 @@ print_nfs_common_args(const struct nfs_common_args *a)
plog(XLOG_DEBUG, "NA->acdirmax = %lu", a->acdirmax);
#endif /* HAVE_NFS_ARGS_T_ACREGMIN */
}
+#endif
static void
discard_nfs23_args(nfs_args_t *nap)

View file

@ -0,0 +1,26 @@
commit a87188b9f0596651ce987253a6af23aca4b08b75
Author: Christos Zoulas <christos@zoulas.com>
Date: Sat Jan 17 12:42:55 2015 -0500
remove set but not used variable
diff --git a/conf/transp/transp_sockets.c b/conf/transp/transp_sockets.c
index b3ad5fc..6326007 100644
--- a/conf/transp/transp_sockets.c
+++ b/conf/transp/transp_sockets.c
@@ -418,7 +418,6 @@ u_long
get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const char *proto, u_long def)
{
CLIENT *clnt;
- int again = 0;
enum clnt_stat clnt_stat;
struct timeval tv;
int sock;
@@ -433,7 +432,6 @@ get_nfs_version(char *host, struct sockaddr_in *sin, u_long nfs_version, const c
nfs_version = def;
else
nfs_version = NFS_VERS_MAX;
- again = 1;
}
tv.tv_sec = 2; /* retry every 2 seconds, but also timeout */
tv.tv_usec = 0;

View file

@ -0,0 +1,28 @@
commit ed717dad0fee421744a24e6fb43e09d62b3f898d
Author: Christos Zoulas <christos@zoulas.com>
Date: Sat Jan 17 12:45:22 2015 -0500
remove set but not used variable
diff --git a/amd/amfs_generic.c b/amd/amfs_generic.c
index 25d734b..c352a32 100644
--- a/amd/amfs_generic.c
+++ b/amd/amfs_generic.c
@@ -1153,7 +1153,6 @@ amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op)
{
am_node *new_mp;
am_loc **al_array;
- int mp_error;
dlog("in amfs_generic_lookup_child");
@@ -1178,9 +1177,6 @@ amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op)
return new_mp;
}
- /* save error_return */
- mp_error = *error_return;
-
al_array = amfs_lookup_loc(new_mp, error_return);
if (!al_array) {
new_mp->am_error = new_mp->am_al->al_mnt->mf_error = *error_return;

View file

@ -0,0 +1,38 @@
commit 79bb90caf12d2713b4736c3820135f0f00424f10
Author: Christos Zoulas <christos@zoulas.com>
Date: Sat Jan 17 12:29:03 2015 -0500
remove set but not used variable
diff --git a/hlfsd/hlfsd.c b/hlfsd/hlfsd.c
index 686bb63..701abcd 100644
--- a/hlfsd/hlfsd.c
+++ b/hlfsd/hlfsd.c
@@ -144,7 +144,6 @@ main(int argc, char *argv[])
int opterrs = 0;
int retry;
int soNFS; /* NFS socket */
- int s = -99;
mntent_t mnt;
nfs_args_t nfs_args;
am_nfs_handle_t anh;
@@ -449,17 +448,16 @@ main(int argc, char *argv[])
* set this signal handler.
*/
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 */
+ (void)sigsuspend(&mask); /* wait for child to set up */
}
#else /* not HAVE_SIGSUSPEND */
- s = sigpause(0); /* wait for child to set up */
+ (void)sigpause(0); /* wait for child to set up */
#endif /* not HAVE_SIGSUSPEND */
sleep(1);
}

View file

@ -0,0 +1,22 @@
commit f61becdba8df1d6d515f5476d312d3cf4e933946
Author: Christos Zoulas <christos@zoulas.com>
Date: Sat Jan 17 12:43:32 2015 -0500
remove unused function
diff --git a/amq/amq.c b/amq/amq.c
index e99732f..5d4ed7a 100644
--- a/amq/amq.c
+++ b/amq/amq.c
@@ -256,11 +256,6 @@ show_mi(amq_mount_info_list *ml, enum show_opt e, int *mwid, int *dwid, int *twi
}
static void
-show_map(amq_map_info *mi)
-{
-}
-
-static void
show_mapinfo(amq_map_info_list *ml, enum show_opt e, int *nwid, int *wwid)
{
u_int i;

View file

@ -0,0 +1,59 @@
commit 76e1a5ddc9ef9730205b2da2ed6b654d8fbaef40
Author: Christos Zoulas <christos@zoulas.com>
Date: Sat Jan 17 12:27:56 2015 -0500
uid_t might be a different size than unsigned int, so XXX: truncate.
diff --git a/hlfsd/stubs.c b/hlfsd/stubs.c
index b26e5f4..70876b7 100644
--- a/hlfsd/stubs.c
+++ b/hlfsd/stubs.c
@@ -60,6 +60,21 @@ static int started;
static am_nfs_fh slink;
static am_nfs_fh un_fhandle;
+static void
+xgetuid(uid_t *uid, const void *p)
+{
+ u_int xuid;
+ (void)memcpy(&xuid, p, sizeof(xuid));
+ *uid = xuid;
+}
+
+static void
+xputuid(void *p, uid_t uid)
+{
+ u_int xuid = uid;
+ (void)memcpy(p, &xuid, sizeof(xuid));
+}
+
/*
* GLOBALS:
*/
@@ -160,7 +175,7 @@ nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
if (gid != hlfs_gid) {
res.ns_status = NFSERR_STALE;
} else {
- (void)memcpy(&uid, argp->fh_data, sizeof(uid));
+ xgetuid(&uid, argp->fh_data);
if (plt_search(uid) != (uid2home_t *) NULL) {
res.ns_status = NFS_OK;
un_fattr.na_fileid = uid;
@@ -278,7 +293,7 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
un_fattr.na_fileid = untab[idx].uid;
res.dr_u.dr_drok_u.drok_attributes = un_fattr;
memset(&un_fhandle, 0, sizeof(un_fhandle));
- memcpy(un_fhandle.fh_data, &untab[idx].uid, sizeof(untab[idx].uid));
+ xputuid(un_fhandle.fh_data, untab[idx].uid);
xstrlcpy((char *) &un_fhandle.fh_data[sizeof(int)],
untab[idx].username,
sizeof(am_nfs_fh) - sizeof(int));
@@ -333,7 +348,7 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
}
if (groupid == hlfs_gid) {
- memcpy(&userid, argp->fh_data, sizeof(userid));
+ xgetuid(&userid, argp->fh_data);
username = (char *) &argp->fh_data[sizeof(int)];
if (!(res.rlr_u.rlr_data_u = mailbox(userid, username)))
return (nfsreadlinkres *) NULL;

View file

@ -0,0 +1,93 @@
am-utils-6.2 - use Linux libtirpc if present
From: Ian Kent <raven@themaw.net>
For Linux systems, if the header files and shared libraries of libtirpc
are present use them instead of the glibc RPC implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
Makefile.am | 3 ++-
configure.ac | 4 ++++
include/am_compat.h | 8 ++++++--
m4/macros/check_linux_libtirpc.m4 | 13 +++++++++++++
4 files changed, 25 insertions(+), 3 deletions(-)
create mode 100644 m4/macros/check_linux_libtirpc.m4
diff --git a/Makefile.am b/Makefile.am
index bae4615..e094e95 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,7 +146,8 @@ EXTRA_DIST_M4 = \
m4/macros/type_xdrproc_t.m4 \
m4/macros/type_xfs_args.m4 \
m4/macros/type_yp_order_outorder.m4 \
- m4/macros/with_addon.m4
+ m4/macros/with_addon.m4 \
+ m4/macros/check_linux_libtirpc.m4
EXTRA_DIST_CONF = \
conf/autofs/autofs_default.h \
diff --git a/configure.ac b/configure.ac
index ce61925..98b444d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -222,6 +222,9 @@ dnl lots of code. So I am forced to use a special purpose macro that sets
dnl the libraries based on the OS. Sigh. -Erez.
AMU_CHECK_OS_LIBS
+dnl use Linux libtirpc if possible
+AMU_CHECK_LIBTIRPC
+
dnl librpc and librpcsvc are needed on Solaris
AC_CHECK_LIB(rpc, clnt_sperrno)
AC_CHECK_LIB(rpcsvc, xdr_fhandle)
@@ -433,6 +436,7 @@ AC_CHECK_HEADERS( \
arpa/nameser.h \
arpa/inet.h \
bsd/rpc/rpc.h \
+ tirpc/netconfig.h \
cdfs/cdfsmount.h \
cdfs/cdfs_mount.h \
fs/udf/udf_mount.h \
diff --git a/include/am_compat.h b/include/am_compat.h
index 3463f3f..d6826fc 100644
--- a/include/am_compat.h
+++ b/include/am_compat.h
@@ -454,11 +454,15 @@ struct hsfs_args {
/*
* Define a dummy struct netconfig for non-TLI systems
*/
-#if !defined(HAVE_NETCONFIG_H) && !defined(HAVE_SYS_NETCONFIG_H)
+#if !defined(HAVE_NETCONFIG_H)
+# if !defined(HAVE_SYS_NETCONFIG_H)
+# if !defined(HAVE_TIRPC_NETCONFIG_H)
struct netconfig {
int dummy;
};
-#endif /* not HAVE_NETCONFIG_H and not HAVE_SYS_NETCONFIG_H */
+# endif /* not HAVE_TIRPC_NETCONFIG_H */
+# endif /* not HAVE_SYS_NETCONFIG_H */
+#endif /* not HAVE_NETCONFIG_H */
/* some OSs don't define INADDR_NONE and assume it's unsigned -1 */
#ifndef INADDR_NONE
diff --git a/m4/macros/check_linux_libtirpc.m4 b/m4/macros/check_linux_libtirpc.m4
new file mode 100644
index 0000000..918423c
--- /dev/null
+++ b/m4/macros/check_linux_libtirpc.m4
@@ -0,0 +1,13 @@
+dnl ######################################################################
+dnl Check for Linux libtirpc library
+AC_DEFUN([AMU_CHECK_LIBTIRPC],[
+TIRPC_CPPFLAGS=""
+TIRPC_LIBS=""
+
+AC_CHECK_HEADER(tirpc/netconfig.h,[
+ TIRPC_CPPFLAGS="-I/usr/include/tirpc"
+ AC_DEFINE(HAVE_LIBTIRPC, 1, [Define to 1 if you have libtirpc headers installed])
+ AC_CHECK_LIB(tirpc, clnt_tli_create, [TIRPC_LIBS="-ltirpc"], [TIRPC_CPPFLAGS=""])])
+ AMU_CFLAGS="$AMU_CFLAGS $TIRPC_CPPFLAGS"
+ LIBS="$LIBS $TIRPC_LIBS"
+])

View file

@ -0,0 +1,60 @@
am-utils-6.2 - use new get_nfs_xprt() and put_nfs_xprt() functions
From: Ian Kent <raven@themaw.net>
The nfs_quick_reply() function needs to know the current RPC transport
outside of the NFS LOOKUP method call. It needs this to reply to the
NFS LOOKUP call that initiated the mount.
Now there are functions that avoid transport corruption if another
request comes in during the backgroud mount make nfs_quick_reply()
use them.
Signed-off-by: Ian Kent <raven@themaw.net>
---
amd/amfs_generic.c | 3 +--
amd/map.c | 2 +-
amd/nfs_subr.c | 3 ++-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/amd/amfs_generic.c b/amd/amfs_generic.c
index c352a32..86d0ab7 100644
--- a/amd/amfs_generic.c
+++ b/amd/amfs_generic.c
@@ -1129,8 +1129,7 @@ amfs_generic_mount_child(am_node *new_mp, int *error_return)
*/
if (current_transp && !new_mp->am_transp) {
dlog("Saving RPC transport for %s", new_mp->am_path);
- new_mp->am_transp = (SVCXPRT *) xmalloc(sizeof(SVCXPRT));
- *(new_mp->am_transp) = *current_transp;
+ new_mp->am_transp = get_nfs_xprt(current_transp);
}
if (error && new_mp->am_al && new_mp->am_al->al_mnt &&
(new_mp->am_al->al_mnt->mf_ops == &amfs_error_ops))
diff --git a/amd/map.c b/amd/map.c
index 0d404cf..bcb2156 100644
--- a/amd/map.c
+++ b/amd/map.c
@@ -471,7 +471,7 @@ free_map(am_node *mp)
XFREE(mp->am_name);
XFREE(mp->am_path);
XFREE(mp->am_pref);
- XFREE(mp->am_transp);
+ put_nfs_xprt(mp->am_transp);
if (mp->am_al)
free_loc(mp->am_al);
diff --git a/amd/nfs_subr.c b/amd/nfs_subr.c
index 0a43b98..07d960d 100644
--- a/amd/nfs_subr.c
+++ b/amd/nfs_subr.c
@@ -291,7 +291,8 @@ nfs_quick_reply(am_node *mp, int error)
/*
* Free up transp. It's only used for one reply.
*/
- XFREE(mp->am_transp);
+ put_nfs_xprt(mp->am_transp);
+ mp->am_transp = NULL;
dlog("Quick reply sent for %s", mp->am_al->al_mnt->mf_mount);
}
}

View file

@ -2,7 +2,7 @@ Summary: Automount utilities including an updated version of Amd
Name: am-utils
Version: 6.2.0
%define upstream_version 6.2
Release: 10%{?dist}
Release: 23%{?dist}
License: BSD
Epoch: 5
Group: System Environment/Daemons
@ -27,11 +27,13 @@ BuildRequires: systemd-units
BuildRequires: texinfo
BuildRequires: gcc
BuildRequires: m4
BuildRequires: libtirpc-devel
Requires: rpcbind
Requires: grep
Requires: gawk
Requires: findutils
Requires: libtirpc
Requires(pre): /bin/grep
Requires(post): /sbin/install-info
@ -43,12 +45,43 @@ Requires(preun): /sbin/install-info
# Fix problems with possible future libtool rebases (#1181698)
Patch1: am-utils-6.2-dont-include-auto-generated-macros-in-aclinlude_m4.patch
Patch2: am-utils-6.2-print_nfs_common_args-is-only-needed-with-DEBUG.patch
Patch3: am-utils-6.2-uid_t-might-be-a-different-size-than-unsigned-int.patch
Patch4: am-utils-6.2-remove-set-but-not-used-variable-s.patch
Patch5: am-utils-6.2-remove-set-but-not-used-variable-again.patch
Patch6: am-utils-6.2-remove-unused-function-show_map.patch
Patch7: am-utils-6.2-remove-set-but-not-used-variable-mp_error.patch
Patch8: am-utils-6.2-32-bit-fixes.patch
Patch9: am-utils-6.2-make-sure-variables-are-initialized.patch
Patch10: am-utils-6.2-dont-use-logical-double-ampersand-when-ampersand-is-meant.patch
Patch11: am-utils-6.2-Fix-nfs-args-setting-code.patch
Patch2: am-utils-6.2-add-debug-log-trace-to-NFSv3-readdirplus.patch
Patch3: am-utils-6.2-fix-NFSv3-access-method-return-on-non-existent-mount-point.patch
Patch4: am-utils-6.2-fix-NFSv3-lookup-dir-attribute-return-value.patch
Patch5: am-utils-6.2-fix-NFSv3-readdir-post_op_dir-attributes-return.patch
Patch6: am-utils-6.2-fix-NFSv3-unlink3_or_rmdir3-post_op-attributes-return.patch
Patch12: am-utils-6.2-add-debug-log-trace-to-NFSv3-readdirplus.patch
Patch13: am-utils-6.2-fix-NFSv3-access-method-return-on-non-existent-mount-point.patch
Patch14: am-utils-6.2-fix-NFSv3-lookup-dir-attribute-return-value.patch
Patch15: am-utils-6.2-fix-NFSv3-readdir-post_op_dir-attributes-return.patch
Patch16: am-utils-6.2-fix-NFSv3-unlink3_or_rmdir3-post_op-attributes-return.patch
Patch17: am-utils-6.2-fix-Linux-NFS-recognition-of-umounts.patch
Patch18: am-utils-6.2-add-get_nfs_xprt-and-put_nfs_xprt-functions.patch
Patch19: am-utils-6.2-use-new-get_nfs_xprt-and-put_nfs_xprt-functions.patch
Patch20: am-utils-6.2-add-NFSv3-nfs_quick_reply-functionality.patch
Patch21: am-utils-6.2-add-NFSv3-rpc-request-validation.patch
Patch22: am-utils-6.2-fix-wcc-attr-usage-in-unlink3_or_rmdir3.patch
Patch23: am-utils-6.2-Add-the-sys-alias-for-unix-as-well-as-none-and-null.patch
Patch24: am-utils-6.2-Default-to-string-mount-options-for-NFSv4.patch
Patch25: am-utils-6.2-Improve-debugging-for-unmounting.patch
Patch26: am-utils-6.2-add-more-debugging-in-the-unmount-path.patch
Patch27: am-utils-6.2-There-is-really-no-ti-rpc-nfsv4-so-dont-send-one.patch
Patch28: am-utils-6.2-Fix-SEGV-on-amq-entries-that-print-times.patch
Patch29: am-utils-6.2-Make-hasmntval-return-an-0-on-error-1-on-success.patch
Patch30: am-utils-6.2-Update-the-ctime-of-the-directory-too-since-it-changed.patch
Patch31: am-utils-6.2-use-linux-libtirpc-if-present.patch
Patch32: am-utils-6.2-fix-compiler-assignment-warning-due-to-libtirpc.patch
Patch33: am-utils-6.2-fix-logical-not-comparison-in-get_ldap_timestamp.patch
Patch34: am-utils-6.2-fix-umount-to-mount-race.patch
# Not needed since autoreconf/libtool appear to do this automatically
# Leaving it set doesn't appear to be a problem so leave it set in
@ -79,6 +112,34 @@ mounting and unmounting filesystems.
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
./bootstrap
@ -190,6 +251,50 @@ fi
%{_libdir}/libamu.so*
%changelog
* Thu Dec 1 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-23
- fix fix-umount-to-mount-race patch (bug 1399213).
* Mon Oct 3 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-22
- fix ambiguous else due to dlog() macro usage.
* Mon Oct 3 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-21
- fix typo in libtirpc configure macro.
* Mon Oct 3 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-20
- print_nfs_common_args() is only needed with DEBUG.
- uid_t might be a different size than unsigned int.
- remove set but not used variable s.
- remove set but not used variable again.
- remove unused function show_map().
- remove set but not used variable mp_error.
- 32 bit fixes.
- make sure variables are initialized.
- dont use logical double ampersand when ampersand is meant.
- Fix nfs args setting code.
- Add the sys alias for unix as well as none and null.
- Default to string mount options for NFSv4.
- Improve debugging for unmounting.
- add more debugging in the unmount path.
- There is really no ti-rpc nfsv4 so dont send one.
- Fix SEGV on amq entries that print times.
- Make hasmntval return an 0 on error 1 on success.
- Update the ctime of the directory too since it changed.
- fix compiler assignment warning due to libtirpc.
- fix logical not comparison in get_ldap_timestamp().
- fix umount to mount race.
* Fri Mar 4 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-12
- add get_nfs_xprt() and put_nfs_xprt() functions.
- use new get_nfs_xprt() and put_nfs_xprt() functions.
- add NFSv3 nfs_quick_reply() functionality.
- add NFSv3 rpc request validation.
- fix wcc attr usage in unlink3_or_rmdir3().
- use Linux libtirpc if present.
* Mon Feb 29 2016 Ian Kent <ikent@redhat.com> - 5:6.2.0-11
- fix Linux NFS recognition of umounts.
- add systemd dependency on nfs-lock.service.
* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 5:6.2.0-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild

View file

@ -1,7 +1,7 @@
[Unit]
Description=automount daemon that mounts devices and NFS hosts on demand
After=syslog.target network.target network-online.target rpcbind.service
Wants=network-online.target rpcbind.service
Wants=network-online.target rpcbind.service nfs-lock.service
[Service]
EnvironmentFile=-/etc/sysconfig/amd