summaryrefslogtreecommitdiffstats
path: root/usr.sbin/amd
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1997-04-22 10:24:29 +0000
committerdfr <dfr@FreeBSD.org>1997-04-22 10:24:29 +0000
commite52cdb3cdfcdcb00a2c146e954e7b11a7966340a (patch)
tree6cb88efec26361c97876fb7da27fce5e8176bb59 /usr.sbin/amd
parent5e1197d908cdd207923561eabb3c956e064c1484 (diff)
downloadFreeBSD-src-e52cdb3cdfcdcb00a2c146e954e7b11a7966340a.zip
FreeBSD-src-e52cdb3cdfcdcb00a2c146e954e7b11a7966340a.tar.gz
Update the host filesystem so that it works with NFSv3
Diffstat (limited to 'usr.sbin/amd')
-rw-r--r--usr.sbin/amd/amd/host_ops.c110
-rw-r--r--usr.sbin/amd/amd/nfs_ops.c16
-rw-r--r--usr.sbin/amd/include/mountres.h40
3 files changed, 129 insertions, 37 deletions
diff --git a/usr.sbin/amd/amd/host_ops.c b/usr.sbin/amd/amd/host_ops.c
index bf71fc0..bf9eb92 100644
--- a/usr.sbin/amd/amd/host_ops.c
+++ b/usr.sbin/amd/amd/host_ops.c
@@ -37,7 +37,7 @@
*
* @(#)host_ops.c 8.1 (Berkeley) 6/6/93
*
- * $Id$
+ * $Id: host_ops.c,v 1.4 1997/02/22 16:01:29 peter Exp $
*
*/
@@ -46,6 +46,7 @@
#ifdef HAS_HOST
#include "mount.h"
+#include "mountres.h"
#include <sys/stat.h>
/*
@@ -132,9 +133,9 @@ caddr_t args_ptr;
return ((*xdr_args)(&xdr, args_ptr));
}
-static int do_mount P((fhstatus *fhp, char *dir, char *fs_name, char *opts, mntfs *mf));
-static int do_mount(fhp, dir, fs_name, opts, mf)
-fhstatus *fhp;
+static int do_mount P((mountres *mrp, char *dir, char *fs_name, char *opts, mntfs *mf));
+static int do_mount(mrp, dir, fs_name, opts, mf)
+mountres *mrp;
char *dir;
char *fs_name;
char *opts;
@@ -152,7 +153,7 @@ mntfs *mf;
return ENOENT;
}
- return mount_nfs_fh(fhp, dir, fs_name, opts, mf);
+ return mount_nfs_fh(mrp, dir, fs_name, opts, mf);
}
static int sortfun P((exports *a, exports *b));
@@ -165,14 +166,16 @@ exports *a,*b;
/*
* Get filehandle
*/
-static int fetch_fhandle P((CLIENT *client, char *dir, fhstatus *fhp));
-static int fetch_fhandle(client, dir, fhp)
+static int fetch_fhandle P((CLIENT *client, xdrproc_t xdr_mountres, char *dir, mountres *mrp));
+static int fetch_fhandle(client, xdr_mountres, dir, mrp)
CLIENT *client;
+xdrproc_t xdr_mountres;
char *dir;
-fhstatus *fhp;
+mountres *mrp;
{
struct timeval tv;
enum clnt_stat clnt_stat;
+ int status;
/*
* Pick a number, any number...
@@ -187,7 +190,9 @@ fhstatus *fhp;
* Call the mount daemon on the remote host to
* get the filehandle.
*/
- clnt_stat = clnt_call(client, MOUNTPROC_MNT, xdr_dirpath, &dir, xdr_fhstatus, fhp, tv);
+ clnt_stat = clnt_call(client, MOUNTPROC_MNT, xdr_dirpath, &dir, xdr_mountres, &mrp->mr_mountres, tv);
+ if (clnt_stat == 0)
+ status = mrp->mr_fhstatus.fhs_status; /* XXX assumes fhstatus and mountres3 start the same */
if (clnt_stat != RPC_SUCCESS) {
extern char *clnt_sperrno();
char *msg = clnt_sperrno(clnt_stat);
@@ -197,12 +202,12 @@ fhstatus *fhp;
/*
* Check status of filehandle
*/
- if (fhp->fhs_status) {
+ if (status) {
#ifdef DEBUG
- errno = fhp->fhs_status;
+ errno = status;
dlog("fhandle fetch failed: %m");
#endif /* DEBUG */
- return fhp->fhs_status;
+ return status;
}
return 0;
}
@@ -224,12 +229,35 @@ char *dir;
}
/*
- * Mount the export tree from a host
+ * Return TRUE if mount opts contains nfsv2 flag.
*/
-static int host_fmount P((mntfs *mf));
-static int host_fmount(mf)
+static int forcev2(mf)
+mntfs *mf;
+{
+ struct mntent mnt;
+
+ mnt.mnt_dir = mf->mf_mount;
+ mnt.mnt_fsname = mf->mf_info;
+ mnt.mnt_type = MTAB_TYPE_NFS;
+ mnt.mnt_opts = mf->mf_mopts;
+ mnt.mnt_freq = 0;
+ mnt.mnt_passno = 0;
+
+ if (hasmntopt(&mnt, "nfsv2") != NULL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*
+ * A helper for host_fmount.
+ */
+static int try_fmount P((mntfs *mf, int mountvers));
+static int try_fmount(mf, mountvers)
mntfs *mf;
+int mountvers;
{
+ xdrproc_t xdr_mountres;
struct timeval tv2;
CLIENT *client;
enum clnt_stat clnt_stat;
@@ -237,7 +265,7 @@ mntfs *mf;
int j, k;
exports exlist = 0, ex;
exports *ep = 0;
- fhstatus *fp = 0;
+ mountres *mrp = 0;
char *host = mf->mf_server->fs_host;
int error = 0;
struct sockaddr_in sin;
@@ -249,6 +277,11 @@ mntfs *mf;
struct timeval tv;
tv.tv_sec = 10; tv.tv_usec = 0;
+ if (mountvers == MOUNTVERS)
+ xdr_mountres = xdr_fhstatus;
+ else
+ xdr_mountres = xdr_mountres3;
+
/*
* Read the mount list
*/
@@ -272,8 +305,8 @@ mntfs *mf;
* Make a client end-point.
* Try TCP first
*/
- if ((client = clnttcp_create(&sin, MOUNTPROG, MOUNTVERS, &sock, 0, 0)) == NULL &&
- (client = clntudp_create(&sin, MOUNTPROG, MOUNTVERS, tv, &sock)) == NULL) {
+ if ((client = clnttcp_create(&sin, MOUNTPROG, mountvers, &sock, 0, 0)) == NULL &&
+ (client = clntudp_create(&sin, MOUNTPROG, mountvers, tv, &sock)) == NULL) {
plog(XLOG_ERROR, "Failed to make rpc connection to mountd on %s", host);
error = EIO;
goto out;
@@ -337,8 +370,9 @@ mntfs *mf;
/*
* Allocate an array of filehandles
*/
- fp = (fhstatus *) xmalloc(n_export * sizeof(fhstatus));
-
+ mrp = (mountres *) xmalloc(n_export * sizeof(mountres));
+ bzero(mrp, n_export * sizeof(mountres));
+
/*
* Try to obtain filehandles for each directory.
* If a fetch fails then just zero out the array
@@ -353,7 +387,8 @@ mntfs *mf;
ep[j] = 0;
} else {
k = j;
- if (error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j]))
+ mrp[j].mr_version = mountvers;
+ if (error = fetch_fhandle(client, xdr_mountres, ep[j]->ex_dir, &mrp[j]))
ep[j] = 0;
}
}
@@ -376,7 +411,7 @@ mntfs *mf;
if (ex) {
strcpy(rfs_dir, ex->ex_dir);
MAKE_MNTPT(mntpt, ex, mf);
- if (do_mount(&fp[j], mntpt, fs_name, mf->mf_mopts, mf) == 0)
+ if (do_mount(&mrp[j], mntpt, fs_name, mf->mf_mopts, mf) == 0)
ok = TRUE;
}
}
@@ -388,8 +423,11 @@ out:
discard_mntlist(mlist);
if (ep)
free(ep);
- if (fp)
- free(fp);
+ if (mrp) {
+ for (j = 0; j < n_export; j++)
+ xdr_free(xdr_mountres, (char *) &mrp->mr_mountres);
+ free(mrp);
+ }
if (client)
clnt_destroy(client);
if (exlist)
@@ -400,6 +438,30 @@ out:
}
/*
+ * Mount the export tree from a host
+ */
+static int host_fmount P((mntfs *mf));
+static int host_fmount(mf)
+mntfs *mf;
+{
+ int error = -1;
+
+#ifdef DEBUG
+ dlog("host_fmount: trying to mount v3");
+#endif
+ if (!forcev2(mf))
+ error = try_fmount(mf, MOUNTVERS3);
+ if (error) {
+#ifdef DEBUG
+ dlog("host_fmount: trying to mount v2");
+#endif
+ error = try_fmount(mf, MOUNTVERS);
+ }
+
+ return error;
+}
+
+/*
* Return true if pref is a directory prefix of dir.
*
* TODO:
diff --git a/usr.sbin/amd/amd/nfs_ops.c b/usr.sbin/amd/amd/nfs_ops.c
index 9fd81cf..1d94943 100644
--- a/usr.sbin/amd/amd/nfs_ops.c
+++ b/usr.sbin/amd/amd/nfs_ops.c
@@ -57,6 +57,7 @@ typedef nfs_fh fhandle_t;
#endif /* NFS_HDR */
#include <sys/mount.h>
#include "mount.h"
+#include "mountres.h"
/*
* Network file system
@@ -93,16 +94,6 @@ typedef nfs_fh fhandle_t;
* changes. If it does, then you have other
* problems...
*/
-typedef struct mountres {
- int mr_version; /* 1 or 3 */
- union {
- struct fhstatus mru_fhstatus; /* mount v1 result */
- struct mountres3 mru_mountres3; /* mount v3 result */
- } mr_un;
-} mountres;
-#define mr_fhstatus mr_un.mru_fhstatus
-#define mr_mountres3 mr_un.mru_mountres3
-
typedef struct fh_cache fh_cache;
struct fh_cache {
qelem fh_q; /* List header */
@@ -232,9 +223,8 @@ fh_cache *fp;
dlog("Discarding filehandle for %s:%s", fp->fh_fs->fs_host, fp->fh_path);
#endif /* DEBUG */
free_srvr(fp->fh_fs);
- if (fp->fh_mountres.mr_version == MOUNTVERS3
- && fp->fh_mountres.mr_mountres3.mountres3_u.mountinfo.fhandle.fhandle3_val)
- free(fp->fh_mountres.mr_mountres3.mountres3_u.mountinfo.fhandle.fhandle3_val);
+ if (fp->fh_mountres.mr_version == MOUNTVERS3)
+ xdr_free(xdr_mountres3, (char *) &fp->fh_mountres.mr_mountres3);
free((voidp) fp->fh_path);
free((voidp) fp);
}
diff --git a/usr.sbin/amd/include/mountres.h b/usr.sbin/amd/include/mountres.h
new file mode 100644
index 0000000..cb3681d
--- /dev/null
+++ b/usr.sbin/amd/include/mountres.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 1997 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * A reply from mountd, either v1 (for nfsv2) or v2 (for nfsv3).
+ */
+typedef struct mountres {
+ int mr_version; /* 1 or 3 */
+ union {
+ struct fhstatus mru_fhstatus; /* mount v1 result */
+ struct mountres3 mru_mountres3; /* mount v3 result */
+ } mr_mountres;
+} mountres;
+#define mr_fhstatus mr_mountres.mru_fhstatus
+#define mr_mountres3 mr_mountres.mru_mountres3
OpenPOWER on IntegriCloud