Date: Tue, 7 May 2013 13:13:06 +0300 From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/178392: Add support for WebNFS mounts to mount_nfs Message-ID: <20130507101306.GA56075@pm513-1.comsys.ntu-kpi.kiev.ua> Resent-Message-ID: <201305071020.r47AK2qa004907@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 178392 >Category: bin >Synopsis: Add support for WebNFS mounts to mount_nfs >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue May 07 10:20:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Andrey Simonenko >Release: FreeBSD 10-CURRENT amd64 >Organization: >Environment: >Description: The following change adds support for WebNFS mounts to mount_nfs. The new option "public" specifies that WebNFS public filehandle should be used and default NFS server port number 2049 should be tried first. If NFS server does respond on this port, then rpcbind is asked for the correct port number. WebNFS client and server code was checked with NFSSERVER and NFSCLIENT kernel options on 10-CURRENT. >How-To-Repeat: Export some file system for WebNFS in /etc/exports: /fs -public 127.0.0.1 Then, try to mount it: # mount_oldnfs -o nfsv3,public 127.0.0.1:/anything /mnt With kern/178103 it will be possible to use WebNFS index files (not sure how to check whether WebNFS multi-component lookups are supported). >Fix: diff -ruNp mount_nfs.orig/mount_nfs.8 mount_nfs/mount_nfs.8 --- mount_nfs.orig/mount_nfs.8 2012-12-10 13:20:11.000000000 +0200 +++ mount_nfs/mount_nfs.8 2013-04-30 12:37:55.000000000 +0300 @@ -245,6 +245,10 @@ use a reserved socket port number (see b .It Cm port Ns = Ns Aq Ar port_number Use specified port number for NFS requests. The default is to query the portmapper for the NFS port. +.It Cm public +Use +.Tn WebNFS +public filehandle. .It Cm rdirplus Used with NFSV3 to specify that the \fBReaddirPlus\fR RPC should be used. diff -ruNp mount_nfs.orig/mount_nfs.c mount_nfs/mount_nfs.c --- mount_nfs.orig/mount_nfs.c 2013-03-07 13:19:35.000000000 +0200 +++ mount_nfs/mount_nfs.c 2013-04-30 12:43:30.000000000 +0300 @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD: src/sbin/mount_nfs/m #include <errno.h> #include <fcntl.h> #include <netdb.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -114,6 +115,7 @@ u_char *fh = NULL; int fhsize = 0; int secflavor = -1; int got_principal = 0; +static bool opt_public = false; enum mountmode { ANY, @@ -310,6 +312,11 @@ main(int argc, char *argv[]) if (*p || num <= 0) errx(1, "illegal maxgroups value -- %s", val); //set_rpc_maxgrouplist(num); + } else if (strcmp(opt, "public") == 0) { + opt_public = true; + if (portspec == NULL) + portspec = "2049"; + pass_flag_to_nmount=0; } if (pass_flag_to_nmount) build_iovec(&iov, &iovlen, opt, val, @@ -372,6 +379,9 @@ main(int argc, char *argv[]) /* NOTREACHED */ } + if (opt_public && mountmode == V4) + errx(1, "WebNFS public filehandle cannot be used with NFSv4"); + spec = *argv++; name = *argv; @@ -946,6 +956,10 @@ tryagain: clp = clnt_tli_create(RPC_ANYFD, nconf, &nfs_nb, NFS_PROGRAM, nfsvers, 0, 0); if (clp == NULL) { + if (opt_public && portspec != NULL) { + portspec = NULL; + goto tryagain; + } snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", netid, hostp, spec, clnt_spcreateerror("nfsd: RPCPROG_NFS")); return (returncode(rpc_createerr.cf_stat, @@ -1009,41 +1023,45 @@ tryagain: return (TRYRET_SUCCESS); } - /* Send the MOUNTPROC_MNT RPC to get the root filehandle. */ - try.tv_sec = 10; - try.tv_usec = 0; - clp = clnt_tp_create(hostp, MOUNTPROG, mntvers, nconf_mnt); - if (clp == NULL) { - snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", netid_mnt, - hostp, spec, clnt_spcreateerror("RPCMNT: clnt_create")); - return (returncode(rpc_createerr.cf_stat, - &rpc_createerr.cf_error)); - } - clp->cl_auth = authsys_create_default(); - nfhret.auth = secflavor; - nfhret.vers = mntvers; - stat = clnt_call(clp, MOUNTPROC_MNT, (xdrproc_t)xdr_dir, spec, - (xdrproc_t)xdr_fh, &nfhret, - try); - auth_destroy(clp->cl_auth); - if (stat != RPC_SUCCESS) { - if (stat == RPC_PROGVERSMISMATCH && trymntmode == ANY) { + if (!opt_public) { + /* Send the MOUNTPROC_MNT RPC to get the root filehandle. */ + try.tv_sec = 10; + try.tv_usec = 0; + clp = clnt_tp_create(hostp, MOUNTPROG, mntvers, nconf_mnt); + if (clp == NULL) { + snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", + netid_mnt, hostp, spec, + clnt_spcreateerror("RPCMNT: clnt_create")); + return (returncode(rpc_createerr.cf_stat, + &rpc_createerr.cf_error)); + } + clp->cl_auth = authsys_create_default(); + nfhret.auth = secflavor; + nfhret.vers = mntvers; + stat = clnt_call(clp, MOUNTPROC_MNT, (xdrproc_t)xdr_dir, spec, + (xdrproc_t)xdr_fh, &nfhret, try); + auth_destroy(clp->cl_auth); + if (stat != RPC_SUCCESS) { + if (stat == RPC_PROGVERSMISMATCH && + trymntmode == ANY) { + clnt_destroy(clp); + trymntmode = V2; + goto tryagain; + } + clnt_geterr(clp, &rpcerr); + snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", + netid_mnt, hostp, spec, + clnt_sperror(clp, "RPCPROG_MNT")); clnt_destroy(clp); - trymntmode = V2; - goto tryagain; + return (returncode(stat, &rpcerr)); } - clnt_geterr(clp, &rpcerr); - snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", netid_mnt, - hostp, spec, clnt_sperror(clp, "RPCPROG_MNT")); clnt_destroy(clp); - return (returncode(stat, &rpcerr)); - } - clnt_destroy(clp); - if (nfhret.stat != 0) { - snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", netid_mnt, - hostp, spec, strerror(nfhret.stat)); - return (TRYRET_REMOTEERR); + if (nfhret.stat != 0) { + snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", + netid_mnt, hostp, spec, strerror(nfhret.stat)); + return (TRYRET_REMOTEERR); + } } /* @@ -1052,16 +1070,32 @@ tryagain: */ addrlen = nfs_nb.len; addr = malloc(addrlen); - fhsize = nfhret.fhsize; - fh = malloc(fhsize); - if (addr == NULL || fh == NULL) + if (addr == NULL) err(1, "malloc"); bcopy(nfs_nb.buf, addr, addrlen); - bcopy(nfhret.nfh, fh, fhsize); + if (!opt_public) { + fhsize = nfhret.fhsize; + fh = malloc(fhsize); + if (fh == NULL) + err(1, "malloc"); + bcopy(nfhret.nfh, fh, fhsize); + secname = sec_num_to_name(nfhret.auth); + } else { + if (trymntmode == V2) { + fhsize = NFS_FHSIZE; + fh = malloc(fhsize); + if (fh == NULL) + err(1, "malloc"); + memset(fh, 0, fhsize); + } else { + fhsize = 0; + fh = NULL; + } + secname = sec_num_to_name(secflavor); + } build_iovec(iov, iovlen, "addr", addr, addrlen); build_iovec(iov, iovlen, "fh", fh, fhsize); - secname = sec_num_to_name(nfhret.auth); if (secname) build_iovec(iov, iovlen, "sec", secname, (size_t)-1); if (nfsvers == 3) >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130507101306.GA56075>