* NEWS: Document WebNFS support.
* configure.in: Check for public mount option.
* include/am_compat.h (MNTTAB_OPT_PUBLIC): Define if missing.
* doc/am-utils.texi (opts Option): Renamed webnfs to public,
update description.
* amd/amd.h (FSF_WEBNFS): New mntfs flag.
* include/am_utils.h (RPC_XID_WEBNFS): New XID type.
* amd/amfs_host.c (amfs_host_mount, amfs_host_umounted): Reject
WebNFS mount/umount attempts.
* amd/ops_nfs.c (got_nfs_fh_mount): Renamed from got_nfs_fh.
(got_nfs_fh_webnfs): New function.
(flush_nfs_fhandle_cache): Don't invalidate port for WebNFS servers.
(prime_nfs_fhandle_cache): Likewise.
Remove unconditional return of public file handle for WebNFS, but
get NFS file handles via mountd or WebNFS instead.
(webnfs_lookup): New function.
(nfs_umounted): Don't inform mountd if MFF_WEBNFS.
* amd/rpc_fwd.c (fwd_packet, fwd_reply): Send/receive WebNFS
packets.
* amd/srvr_nfs.c (recompute_portmap): Don't contact portmap for
WebNFS servers.
Mention host in info message.
(find_nfs_srvr): Handle public mount option.
Prefer NFSv3/tcp if the client supports it.
Allow port mount option to override default or result from portmap
lookup.
* libamu/xdr_func.c (xdr_diropargs3, xdr_filename3,
xdr_LOOKUP3args, xdr_LOOKUP3res, xdr_LOOKUP3resfail,
xdr_LOOKUP3resok, xdr_nfs_fh3, xdr_nfsstat3): New functions.
* include/am_xdr_func.h: Declare them.
* configure.in: Check for them.
* conf/nfs_prot/nfs_prot_linux.h: Provide missing NFSv3
definitions and types.
+2003-10-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ Use WebNFS to obtain file handles for mount(2).
+
+ * NEWS: Document WebNFS support.
+
+ * configure.in: Check for public mount option.
+ * include/am_compat.h (MNTTAB_OPT_PUBLIC): Define if missing.
+ * doc/am-utils.texi (opts Option): Renamed webnfs to public,
+ update description.
+
+ * amd/amd.h (FSF_WEBNFS): New mntfs flag.
+ * include/am_utils.h (RPC_XID_WEBNFS): New XID type.
+
+ * amd/amfs_host.c (amfs_host_mount, amfs_host_umounted): Reject
+ WebNFS mount/umount attempts.
+ * amd/ops_nfs.c (got_nfs_fh_mount): Renamed from got_nfs_fh.
+ (got_nfs_fh_webnfs): New function.
+ (flush_nfs_fhandle_cache): Don't invalidate port for WebNFS servers.
+ (prime_nfs_fhandle_cache): Likewise.
+ Remove unconditional return of public file handle for WebNFS, but
+ get NFS file handles via mountd or WebNFS instead.
+ (webnfs_lookup): New function.
+ (nfs_umounted): Don't inform mountd if MFF_WEBNFS.
+ * amd/rpc_fwd.c (fwd_packet, fwd_reply): Send/receive WebNFS
+ packets.
+ * amd/srvr_nfs.c (recompute_portmap): Don't contact portmap for
+ WebNFS servers.
+ Mention host in info message.
+ (find_nfs_srvr): Handle public mount option.
+ Prefer NFSv3/tcp if the client supports it.
+ Allow port mount option to override default or result from portmap
+ lookup.
+
+ * libamu/xdr_func.c (xdr_diropargs3, xdr_filename3,
+ xdr_LOOKUP3args, xdr_LOOKUP3res, xdr_LOOKUP3resfail,
+ xdr_LOOKUP3resok, xdr_nfs_fh3, xdr_nfsstat3): New functions.
+ * include/am_xdr_func.h: Declare them.
+ * configure.in: Check for them.
+ * conf/nfs_prot/nfs_prot_linux.h: Provide missing NFSv3
+ definitions and types.
+
2003-10-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
Support IRIX 6 private mount option.
sparc-sun-solaris2.10
x86_64-unknown-linux-rh2.9.5AS
+- fully support WebNFS as per RFC 2054. It now tries v3/TCP first, falling
+ back to v2/UDP if this doesn't work. The "webnfs" pseudo-mount options
+ has been renamed (again) to "public" to match Solaris 2.
+
- bugs fixed:
* fixed nfsx support
* fixed a race involving late replies to mountd, etc queries
* SUCH DAMAGE.
*
*
- * $Id: amd.h,v 1.47 2003/10/09 05:13:58 ib42 Exp $
+ * $Id: amd.h,v 1.48 2003/10/09 20:33:45 ro Exp $
*
*/
#define FSF_ERROR 0x0004 /* Permanent error has occurred */
#define FSF_WANT 0x0008 /* Want a wakeup call */
#define FSF_PINGING 0x0010 /* Already doing pings */
+#define FSF_WEBNFS 0x0020 /* Don't try to contact portmapper */
#define FSRV_ERROR(fs) ((fs) && (((fs)->fs_flags & FSF_ERROR) == FSF_ERROR))
#define FSRV_ISDOWN(fs) ((fs) && (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_DOWN|FSF_VALID)))
#define FSRV_ISUP(fs) (!(fs) || (((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_VALID)))
* SUCH DAMAGE.
*
*
- * $Id: amfs_host.c,v 1.24 2003/10/02 16:29:28 ro Exp $
+ * $Id: amfs_host.c,v 1.25 2003/10/09 20:33:45 ro Exp $
*
*/
struct timeval tv;
u_long mnt_version;
+ /*
+ * WebNFS servers don't necessarily run mountd.
+ */
+ if (mf->mf_flags & MFF_WEBNFS) {
+ plog(XLOG_ERROR, "amfs_host_mount: cannot support WebNFS");
+ return EIO;
+ }
+
/*
* Read the mount list
*/
if (mf->mf_error || mf->mf_refc > 1 || !mf->mf_server)
return;
+ /*
+ * WebNFS servers shouldn't ever get here.
+ */
+ if (mf->mf_flags & MFF_WEBNFS) {
+ plog(XLOG_ERROR, "amfs_host_umounted: cannot support WebNFS");
+ return;
+ }
+
/*
* Take a copy of the server hostname, address, and NFS version
* to mount version conversion.
* SUCH DAMAGE.
*
*
- * $Id: ops_nfs.c,v 1.33 2003/10/02 16:29:28 ro Exp $
+ * $Id: ops_nfs.c,v 1.34 2003/10/09 20:33:45 ro Exp $
*
*/
static int nfs_umount(am_node *am, mntfs *mf);
static void nfs_umounted(mntfs *mf);
static int call_mountd(fh_cache *fp, u_long proc, fwd_fun f, wchan_t wchan);
+static int webnfs_lookup(fh_cache *fp, fwd_fun f, wchan_t wchan);
static int fh_id = 0;
/* globals */
/*
- * Called when a filehandle appears
+ * Called when a filehandle appears via the mount protocol
*/
static void
-got_nfs_fh(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, opaque_t arg, int done)
+got_nfs_fh_mount(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, opaque_t arg, int done)
{
fh_cache *fp;
struct fhstatus res;
}
+/*
+ * Called when a filehandle appears via WebNFS
+ */
+static void
+got_nfs_fh_webnfs(voidp pkt, int len, struct sockaddr_in *sa, struct sockaddr_in *ia, opaque_t arg, int done)
+{
+ fh_cache *fp;
+ nfsdiropres res;
+#ifdef HAVE_FS_NFS3
+ LOOKUP3res res3;
+#endif /* HAVE_FS_NFS3 */
+
+ fp = find_nfs_fhandle_cache(arg, done);
+ if (!fp)
+ return;
+
+ /*
+ * retrieve the correct RPC reply for the file handle, based on the
+ * NFS protocol version.
+ */
+#ifdef HAVE_FS_NFS3
+ if (fp->fh_nfs_version == NFS_VERSION3) {
+ memset(&res3, 0, sizeof(res3));
+ fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &res3,
+ (XDRPROC_T_TYPE) xdr_LOOKUP3res);
+ fp->fh_status = unx_error(res3.status);
+ memset(&fp->fh_nfs_handle.v3, 0, sizeof(am_nfs_fh3));
+ fp->fh_nfs_handle.v3.fh3_length = res3.res_u.ok.object.fh3_length;
+ memmove(fp->fh_nfs_handle.v3.fh3_u.data,
+ res3.res_u.ok.object.fh3_u.data,
+ fp->fh_nfs_handle.v3.fh3_length);
+ } else {
+#endif /* HAVE_FS_NFS3 */
+ memset(&res, 0, sizeof(res));
+ fp->fh_error = pickup_rpc_reply(pkt, len, (voidp) &res,
+ (XDRPROC_T_TYPE) xdr_diropres);
+ fp->fh_status = unx_error(res.dr_status);
+ memmove(&fp->fh_nfs_handle.v2, &res.dr_u.dr_drok_u.drok_fhandle, NFS_FHSIZE);
+#ifdef HAVE_FS_NFS3
+ }
+#endif /* HAVE_FS_NFS3 */
+
+ if (!fp->fh_error) {
+ dlog("got filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
+ } else {
+ plog(XLOG_USER, "filehandle denied for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
+ /*
+ * Force the error to be EACCES. It's debatable whether it should be
+ * ENOENT instead, but the server really doesn't give us any clues, and
+ * EACCES is more in line with the "filehandle denied" message.
+ */
+ fp->fh_error = EACCES;
+ }
+
+ /*
+ * Wakeup anything sleeping on this filehandle
+ */
+ if (fp->fh_wchan) {
+ dlog("Calling wakeup on %#lx", (unsigned long) fp->fh_wchan);
+ wakeup(fp->fh_wchan);
+ }
+}
+
+
void
flush_nfs_fhandle_cache(fserver *fs)
{
ITER(fp, fh_cache, &fh_head) {
if (fp->fh_fs == fs || fs == 0) {
- fp->fh_sin.sin_port = (u_short) 0;
+ /*
+ * Only invalidate port info for non-WebNFS servers
+ */
+ if (!(fp->fh_fs->fs_flags & FSF_WEBNFS))
+ fp->fh_sin.sin_port = (u_short) 0;
fp->fh_error = -1;
}
}
}
/*
- * If the address has changed then don't try to re-use the
- * port information
+ * Either fp has been freshly allocated or the address has changed.
+ * Initialize address and nfs version. Don't try to re-use the port
+ * information unless using WebNFS where the port is fixed either by
+ * the spec or the "port" mount option.
*/
if (fp->fh_sin.sin_addr.s_addr != fs->fs_ip->sin_addr.s_addr) {
fp->fh_sin = *fs->fs_ip;
- fp->fh_sin.sin_port = 0;
+ if (!(mf->mf_flags & MFF_WEBNFS))
+ fp->fh_sin.sin_port = 0;
fp->fh_nfs_version = fs->fs_version;
}
+
fp->fh_fs = dup_srvr(fs);
fp->fh_path = strdup(path);
- if (mf->mf_flags & MFF_WEBNFS) {
- dlog("Using public filehandle for '%s'", mf->mf_info);
- memset(&fp->fh_nfs_handle, 0, sizeof(fp->fh_nfs_handle));
- if (fhbuf) {
-#ifdef HAVE_FS_NFS3
- if (fp->fh_nfs_version == NFS_VERSION3)
- memmove((voidp) &(fhbuf->v3), (voidp) &(fp->fh_nfs_handle.v3),
- sizeof(fp->fh_nfs_handle.v3));
- else
-#endif /* HAVE_FS_NFS3 */
- memmove((voidp) &(fhbuf->v2), (voidp) &(fp->fh_nfs_handle.v2),
- sizeof(fp->fh_nfs_handle.v2));
- }
- wakeup(get_mntfs_wchan(mf));
- fp->fh_error = 0;
- return 0;
- }
-
- error = call_mountd(fp, MOUNTPROC_MNT, got_nfs_fh, get_mntfs_wchan(mf));
+ if (mf->mf_flags & MFF_WEBNFS)
+ error = webnfs_lookup(fp, got_nfs_fh_webnfs, get_mntfs_wchan(mf));
+ else
+ error = call_mountd(fp, MOUNTPROC_MNT, got_nfs_fh_mount, get_mntfs_wchan(mf));
if (error) {
/*
* Local error - cache for a short period
}
+static int
+webnfs_lookup(fh_cache *fp, fwd_fun fun, wchan_t wchan)
+{
+ struct rpc_msg wnfs_msg;
+ int len;
+ char iobuf[UDPMSGSIZE];
+ int error;
+ u_long proc;
+ XDRPROC_T_TYPE xdr_fn;
+ voidp argp;
+ nfsdiropargs args;
+#ifdef HAVE_FS_NFS3
+ LOOKUP3args args3;
+#endif
+ char *wnfs_path;
+
+ if (!nfs_auth) {
+ error = make_nfs_auth();
+ if (error)
+ return error;
+ }
+
+ if (fp->fh_sin.sin_port == 0) {
+ /* FIXME: wrong, don't discard sin_port in the first place for WebNFS. */
+ plog(XLOG_WARNING, "webnfs_lookup: port == 0 for nfs on %s, fixed",
+ fp->fh_fs->fs_host);
+ fp->fh_sin.sin_port = htons(NFS_PORT);
+ }
+
+ /*
+ * Use native path like the rest of amd (cf. RFC 2054, 6.1).
+ */
+ wnfs_path = (char *) xmalloc(strlen(fp->fh_path) + 2);
+ wnfs_path[0] = 0x80;
+ strcpy(wnfs_path + 1, fp->fh_path);
+
+ /* find the right program and lookup procedure */
+#ifdef HAVE_FS_NFS3
+ if (fp->fh_nfs_version == NFS_VERSION3) {
+ proc = NFSPROC3_LOOKUP;
+ xdr_fn = (XDRPROC_T_TYPE) xdr_LOOKUP3args;
+ argp = &args3;
+ /* WebNFS public file handle */
+ args3.what.dir.fh3_length = 0;
+ args3.what.name = wnfs_path;
+ } else {
+#endif /* HAVE_FS_NFS3 */
+ proc = NFSPROC_LOOKUP;
+ xdr_fn = (XDRPROC_T_TYPE) xdr_diropargs;
+ argp = &args;
+ /* WebNFS public file handle */
+ memset(&args.da_fhandle, 0, NFS_FHSIZE);
+ args.da_name = wnfs_path;
+#ifdef HAVE_FS_NFS3
+ }
+#endif /* HAVE_FS_NFS3 */
+
+ plog(XLOG_INFO, "webnfs_lookup: NFS version %d", (int) fp->fh_nfs_version);
+
+ rpc_msg_init(&wnfs_msg, NFS_PROGRAM, fp->fh_nfs_version, proc);
+ len = make_rpc_packet(iobuf,
+ sizeof(iobuf),
+ proc,
+ &wnfs_msg,
+ argp,
+ (XDRPROC_T_TYPE) xdr_fn,
+ nfs_auth);
+
+ if (len > 0) {
+ error = fwd_packet(MK_RPC_XID(RPC_XID_WEBNFS, fp->fh_id),
+ iobuf,
+ len,
+ &fp->fh_sin,
+ &fp->fh_sin,
+ (opaque_t) ((long) fp->fh_id), /* cast to long needed for 64-bit archs */
+ fun);
+ } else {
+ error = -len;
+ }
+
+ XFREE(wnfs_path);
+ return error;
+}
+
+
/*
* NFS needs the local filesystem, remote filesystem
* remote hostname.
if (mf->mf_error || mf->mf_refc > 1)
return;
+ /*
+ * No need to inform mountd when WebNFS is in use.
+ */
if (mf->mf_flags & MFF_WEBNFS)
return;
* SUCH DAMAGE.
*
*
- * $Id: rpc_fwd.c,v 1.16 2003/10/02 17:13:22 ro Exp $
+ * $Id: rpc_fwd.c,v 1.17 2003/10/09 20:33:46 ro Exp $
*
*/
case RPC_XID_NFSPING:
dlog("Sending NFS ping %#x", type_id);
break;
+ case RPC_XID_WEBNFS:
+ dlog("Sending WebNFS lookup %#x", type_id);
+ break;
default:
dlog("UNKNOWN RPC XID %#x", type_id);
break;
case RPC_XID_NFSPING:
dlog("Receiving NFS ping %#x", pkt_xid);
break;
+ case RPC_XID_WEBNFS:
+ dlog("Receiving WebNFS lookup %#x", pkt_xid);
+ break;
default:
dlog("UNKNOWN RPC XID %#x", pkt_xid);
break;
* SUCH DAMAGE.
*
*
- * $Id: srvr_nfs.c,v 1.32 2003/10/01 02:45:12 ib42 Exp $
+ * $Id: srvr_nfs.c,v 1.33 2003/10/09 20:33:46 ro Exp $
*
*/
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
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;
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;
/*
#endif /* not HAVE_FS_NFS3 */
- if (amu_hasmntopt(&mnt, "webnfs")) {
- plog(XLOG_INFO, "webnfs option used, NOT contacting the portmapper on %s", host);
+ 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) {
- plog(XLOG_INFO, "No NFS version specified, will use NFSv2");
+#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) {
- plog(XLOG_INFO, "No NFS protocol transport specified, will use udp");
+#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 {
/*
}
}
+ /*
+ * 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);
+
+ dlog("find_nfs_srvr: using port %d for nfs on %s",
+ (int) ntohs(nfs_port), host);
ip->sin_port = nfs_port;
no_dns:
if (hp && fs->fs_ip)
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;
+
/*
* following if statement from Mike Mitchell
* <mcm@unx.sas.com>
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;
* SUCH DAMAGE.
*
*
- * $Id: nfs_prot_linux.h,v 1.17 2002/12/27 22:44:00 ezk Exp $
+ * $Id: nfs_prot_linux.h,v 1.18 2003/10/09 20:33:46 ro Exp $
*
*/
typedef struct nfs_args nfs_args_t;
#ifdef HAVE_FS_NFS3
+#define NFSPROC3_LOOKUP ((u_long) 3)
+enum nfsstat3 {
+ NFS3_OK = 0,
+ NFS3ERR_PERM = 1,
+ NFS3ERR_NOENT = 2,
+ NFS3ERR_IO = 5,
+ NFS3ERR_NXIO = 6,
+ NFS3ERR_ACCES = 13,
+ NFS3ERR_EXIST = 17,
+ NFS3ERR_XDEV = 18,
+ NFS3ERR_NODEV = 19,
+ NFS3ERR_NOTDIR = 20,
+ NFS3ERR_ISDIR = 21,
+ NFS3ERR_INVAL = 22,
+ NFS3ERR_FBIG = 27,
+ NFS3ERR_NOSPC = 28,
+ NFS3ERR_ROFS = 30,
+ NFS3ERR_MLINK = 31,
+ NFS3ERR_NAMETOOLONG = 63,
+ NFS3ERR_NOTEMPTY = 66,
+ NFS3ERR_DQUOT = 69,
+ NFS3ERR_STALE = 70,
+ NFS3ERR_REMOTE = 71,
+ NFS3ERR_BADHANDLE = 10001,
+ NFS3ERR_NOT_SYNC = 10002,
+ NFS3ERR_BAD_COOKIE = 10003,
+ NFS3ERR_NOTSUPP = 10004,
+ NFS3ERR_TOOSMALL = 10005,
+ NFS3ERR_SERVERFAULT = 10006,
+ NFS3ERR_BADTYPE = 10007,
+ NFS3ERR_JUKEBOX = 10008
+};
+typedef enum nfsstat3 nfsstat3;
+
typedef struct {
u_int fhandle3_len;
char *fhandle3_val;
} fh3_u;
};
typedef struct nfs_fh3 am_nfs_fh3;
+
+typedef char *filename3;
+
+struct diropargs3 {
+ am_nfs_fh3 dir;
+ filename3 name;
+};
+typedef struct diropargs3 diropargs3;
+
+struct LOOKUP3args {
+ diropargs3 what;
+};
+typedef struct LOOKUP3args LOOKUP3args;
+
+struct LOOKUP3resok {
+ am_nfs_fh3 object;
+#if 0
+ post_op_attr obj_attributes;
+ post_op_attr dir_attributes;
+#endif
+};
+typedef struct LOOKUP3resok LOOKUP3resok;
+
+struct LOOKUP3resfail {
+#if 0
+ post_op_attr dir_attributes;
+#endif
+};
+typedef struct LOOKUP3resfail LOOKUP3resfail;
+
+struct LOOKUP3res {
+ nfsstat3 status;
+ union {
+ LOOKUP3resok ok;
+ LOOKUP3resfail fail;
+ } res_u;
+};
+typedef struct LOOKUP3res LOOKUP3res;
#endif /* HAVE_FS_NFS3 */
/*
dnl
dnl AC_CONFIG_AUX_DIR(m4)
AC_PREREQ(2.52)
-AC_REVISION($Revision: 1.64 $)
+AC_REVISION($Revision: 1.65 $)
AC_COPYRIGHT([Copyright (c) 1997-2003 Erez Zadok])
dnl find out system type
AC_MSG_NOTICE(*** SYSTEM TYPES ***)
xdr_createargs \
xdr_dirlist \
xdr_diropargs \
+ xdr_diropargs3 \
xdr_diropokres \
xdr_diropres \
xdr_dirpath \
xdr_fhandle \
xdr_fhstatus \
xdr_filename \
+ xdr_filename3 \
xdr_ftype \
xdr_groupnode \
xdr_groups \
xdr_linkargs \
+ xdr_LOOKUP3args \
+ xdr_LOOKUP3res \
+ xdr_LOOKUP3resfail \
+ xdr_LOOKUP3resok \
xdr_mountbody \
xdr_mountlist \
xdr_mountres3 \
xdr_name \
xdr_nfs_fh \
+ xdr_nfs_fh3 \
xdr_nfscookie \
xdr_nfspath \
xdr_nfsstat \
+ xdr_nfsstat3 \
xdr_nfstime \
xdr_pointer \
xdr_readargs \
private \
proplist \
proto \
+ public \
retrans \
retry \
ro \
@c
@c %W% (Berkeley) %G%
@c
-@c $Id: am-utils.texi,v 1.74 2003/10/09 19:31:13 ro Exp $
+@c $Id: am-utils.texi,v 1.75 2003/10/09 20:33:47 ro Exp $
@c
@setfilename am-utils.info
@item vers=@var{n}
@cindex Mount flags; vers
- Use NFS protocol version number @var{n} (can be 2 or 3).
+Use NFS protocol version number @var{n} (can be 2 or 3).
@item wsize=@var{n}
@cindex Mount flags; wsize
no pings are sent and the host is assumed to be always up, which can
cause unmounts to hang. See the @i{softlookup} option for a better alternative.
+@item public
+@cindex Mount flags; public
+Use WebNFS multi-component lookup on the public file handle instead of
+the mount protocol to obtain NFS file handles, as documented in the
+WebNFS Client Specification, RFC 2054. This means that @i{Amd} will not
+attempt to contact the remote portmapper or remote mountd daemon, and
+will only connect to the well-known NFS port 2049 or the port specified
+with the @i{port} mount option, thus making it easier to use NFS through
+a firewall.
+
@item retry=@var{n}
@cindex Mount flags; retry=@var{n}
The number of times to retry the mount system call.
attempted, to avoid thrashing. The default value is 120 seconds (two
minutes) or as set by the @code{-w} command line option.
-@item webnfs
-@cindex Mount flags; webnfs
-Tells amd to mount the public share from the remote server (rfs is
-effectively ignored), using the public filehandle as documented in the
-WebNFS RFC. This means that amd will not attempt to contact the remote
-portmapper or remote mountd daemon, and will only connect to the
-well-known NFS port 2049, thus making it easier to use NFS through a
-firewall.
-
-Caveats:
-- since here is only one public filehandle, it necessarily means that
-only one share per fileserver can be mounted via WebNFS. This is a
-limitation of the WebNFS specification, not of amd itself.
-
-- since there is no portmapper communication, amd will not attempt any
-sort of discovery of remote server capabilities, and will default to
-using NFSv2/UDP. It is the admin's responsibility to alter this
-behavior by explicitly specifying the desired NFS version and protocol
-within the mount options for each webnfs map entry.
-
@item xlatecookie
@cindex Mount flags; xlatecookie
Translate directory cookies between 32-long and 64-long lengths.
# define MNTTAB_OPT_PORT "port"
#endif /* not MNTTAB_OPT_PORT */
+#ifndef MNTTAB_OPT_PUBLIC
+# define MNTTAB_OPT_PUBLIC "public"
+#endif /* not MNTTAB_OPT_PUBLIC */
+
#ifndef MNTTAB_OPT_RETRANS
# define MNTTAB_OPT_RETRANS "retrans"
#endif /* not MNTTAB_OPT_RETRANS */
* SUCH DAMAGE.
*
*
- * $Id: am_utils.h,v 1.53 2003/10/02 16:29:29 ro Exp $
+ * $Id: am_utils.h,v 1.54 2003/10/09 20:33:48 ro Exp $
*
*/
#define RPC_XID_PORTMAP 0
#define RPC_XID_MOUNTD 1
#define RPC_XID_NFSPING 2
+#define RPC_XID_WEBNFS 3
#define RPC_XID_MASK (0x0f) /* 16 id's for now */
#define MK_RPC_XID(type_id, uniq) ((type_id) | ((uniq) << 4))
* SUCH DAMAGE.
*
*
- * $Id: am_xdr_func.h,v 1.10 2002/12/27 22:44:09 ezk Exp $
+ * $Id: am_xdr_func.h,v 1.11 2003/10/09 20:33:48 ro Exp $
*
*/
#ifndef HAVE_XDR_WRITEARGS
bool_t xdr_writeargs(XDR *xdrs, nfswriteargs *objp);
#endif /* not HAVE_XDR_WRITEARGS */
+
+/*
+ * NFS3 XDR FUNCTIONS:
+ */
+#ifdef HAVE_FS_NFS3
+# ifndef HAVE_XDR_DIROPARGS3
+bool_t xdr_diropargs3(XDR *xdrs, diropargs3 *objp);
+#endif /* not HAVE_XDR_DIROPARGS3 */
+# ifndef HAVE_XDR_FILENAME3
+bool_t xdr_filename3(XDR *xdrs, filename3 *objp);
+# endif /* not HAVE_XDR_FILENAME3 */
+# ifndef HAVE_XDR_LOOKUP3ARGS
+bool_t xdr_LOOKUP3args(XDR *xdrs, LOOKUP3args *objp);
+# endif /* not HAVE_XDR_LOOKUP3ARGS */
+# ifndef HAVE_XDR_LOOKUP3RES
+bool_t xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp);
+# endif /* not HAVE_XDR_LOOKUP3RES */
+# ifndef HAVE_XDR_LOOKUP3RESFAIL
+bool_t xdr_LOOKUP3resfail(XDR *xdrs, LOOKUP3resfail *objp);
+# endif /* not HAVE_XDR_LOOKUP3RESFAIL */
+# ifndef HAVE_XDR_LOOKUP3RESOK
+bool_t xdr_LOOKUP3resok(XDR *xdrs, LOOKUP3resok *objp);
+# endif /* not HAVE_XDR_LOOKUP3RESOK */
+# ifndef HAVE_XDR_NFS_FH3
+bool_t xdr_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp);
+# endif /* not HAVE_XDR_NFS_FH3 */
+# ifndef HAVE_XDR_NFSSTAT3
+bool_t xdr_nfsstat3(XDR *xdrs, nfsstat3 *objp);
+# endif /* not HAVE_XDR_NFSSTAT3 */
+#endif /* HAVE_FS_NFS3 */
#endif /* not _AM_XDR_FUNC_H */
* SUCH DAMAGE.
*
*
- * $Id: xdr_func.c,v 1.17 2002/12/29 01:09:08 ezk Exp $
+ * $Id: xdr_func.c,v 1.18 2003/10/09 20:33:48 ro Exp $
*
*/
return (TRUE);
}
#endif /* not HAVE_XDR_WRITEARGS */
+
+
+/*
+ * NFS V3 XDR FUNCTIONS:
+ */
+#ifdef HAVE_FS_NFS3
+# ifndef HAVE_XDR_DIROPARGS3
+bool_t
+xdr_diropargs3(XDR *xdrs, diropargs3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_diropargs3:");
+
+ if (!xdr_nfs_fh3(xdrs, &objp->dir))
+ return (FALSE);
+ if (!xdr_filename3(xdrs, &objp->name))
+ return (FALSE);
+ return (TRUE);
+}
+#endif /* not HAVE_XDR_DIROPARGS3 */
+
+
+# ifndef HAVE_XDR_FILENAME3
+bool_t
+xdr_filename3(XDR *xdrs, filename3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_filename3:");
+
+ if (!xdr_string(xdrs, objp, ~0))
+ return (FALSE);
+ return (TRUE);
+}
+# endif /* not HAVE_XDR_FILENAME3 */
+
+
+# ifndef HAVE_XDR_LOOKUP3ARGS
+bool_t
+xdr_LOOKUP3args(XDR *xdrs, LOOKUP3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_LOOKUP3args:");
+
+ if (!xdr_diropargs3(xdrs, &objp->what))
+ return (FALSE);
+ return (TRUE);
+}
+# endif /* not HAVE_XDR_LOOKUP3ARGS */
+
+
+# ifndef HAVE_XDR_LOOKUP3RES
+bool_t
+xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_LOOKUP3res:");
+
+ if (!xdr_nfsstat3(xdrs, &objp->status))
+ return (FALSE);
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_LOOKUP3resok(xdrs, &objp->res_u.ok))
+ return (FALSE);
+ break;
+ default:
+ if (!xdr_LOOKUP3resfail(xdrs, &objp->res_u.fail))
+ return (FALSE);
+ break;
+ }
+ return (TRUE);
+}
+# endif /* not HAVE_XDR_LOOKUP3RES */
+
+
+# ifndef HAVE_XDR_LOOKUP3RESFAIL
+bool_t
+xdr_LOOKUP3resfail(XDR *xdrs, LOOKUP3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_LOOKUP3resfail:");
+
+ /*
+ * Don't xdr post_op_attr: amd doesn't need them, but they require many
+ * additional xdr functions.
+ */
+#if 0
+ if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+ return (FALSE);
+#endif
+ return (TRUE);
+}
+# endif /* not HAVE_XDR_LOOKUP3RESFAIL */
+
+
+# ifndef HAVE_XDR_LOOKUP3RESOK
+bool_t
+xdr_LOOKUP3resok(XDR *xdrs, LOOKUP3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_LOOKUP3resok:");
+
+ if (!xdr_nfs_fh3(xdrs, &objp->object))
+ return (FALSE);
+ /*
+ * Don't xdr post_op_attr: amd doesn't need them, but they require many
+ * additional xdr functions.
+ */
+#if 0
+ if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+ return (FALSE);
+ if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+ return (FALSE);
+#endif
+ return (TRUE);
+}
+# endif /* not HAVE_XDR_LOOKUP3RESOK */
+
+
+# ifndef HAVE_XDR_NFS_FH3
+bool_t
+xdr_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_nfs_fh3:");
+
+ /*
+ * nfs_fh3 used by the kernel differs from the definition generated from
+ * nfs_prot.x, so cannot use the generated xdr_nfs_fh3().
+ */
+ if (!xdr_u_int(xdrs, &objp->fh3_length))
+ return (FALSE);
+ if (objp->fh3_length > NFS3_FHSIZE)
+ return (FALSE);
+ if (!xdr_opaque(xdrs, objp->fh3_u.data, objp->fh3_length))
+ return (FALSE);
+ return (TRUE);
+}
+# endif /* not HAVE_XDR_NFS_FH3 */
+
+
+# ifndef HAVE_XDR_NFSSTAT3
+bool_t
+xdr_nfsstat3(XDR *xdrs, nfsstat3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_nfsstat3:");
+
+ if (!xdr_enum(xdrs, (enum_t *)objp))
+ return (FALSE);
+ return (TRUE);
+}
+# endif /* not HAVE_XDR_NFSSTAT3 */
+#endif /* not HAVE_FS_NFS3 */