---
support/include/nfsrpc.h | 3 ++-
support/nfs/getport.c | 10 +++++++---
utils/mount/network.c | 36 ++++++++++++++++++++---------------
-
utils/mount/network.h | 4 ++--
utils/mount/nfsmount.c | 16 +++++++++++-----
utils/mount/stropts.c | 24 +++++++++++++++++++++---
6 files changed, 63 insertions(+), 30 deletions(-)
diff --git a/support/include/nfsrpc.h b/support/include/nfsrpc.h
index fbbdb6a9..9106c195 100644
--- a/support/include/nfsrpc.h
+++ b/support/include/nfsrpc.h
@@ -170,7 +170,8 @@ extern int nfs_rpc_ping(const struct
sockaddr *sap,
const rpcprog_t program,
const rpcvers_t version,
const unsigned short protocol,
- const struct timeval *timeout);
+ const struct timeval *timeout,
+ const int resvport);
/* create AUTH_SYS handle with no supplemental groups */
extern AUTH * nfs_authsys_create(void);
diff --git a/support/nfs/getport.c b/support/nfs/getport.c
index 813f7bf9..ff7e9991 100644
--- a/support/nfs/getport.c
+++ b/support/nfs/getport.c
@@ -730,7 +730,8 @@ static unsigned short nfs_gp_getport(CLIENT
*client,
*/
int nfs_rpc_ping(const struct sockaddr *sap, const socklen_t
salen,
const rpcprog_t program, const rpcvers_t version,
- const unsigned short protocol, const struct
timeval *timeout)
+ const unsigned short protocol, const struct
timeval *timeout,
+ const int resvport)
{
union nfs_sockaddr address;
struct sockaddr *saddr = &address.sa;
@@ -744,8 +745,11 @@ int nfs_rpc_ping(const struct sockaddr *sap,
const socklen_t salen,
nfs_clear_rpc_createerr();
memcpy(saddr, sap, (size_t)salen);
- client = nfs_get_rpcclient(saddr, salen, protocol,
- program, version,
&tout);
+ client = resvport ?
+ nfs_get_priv_rpcclient(saddr, salen, protocol,
+ program, version, &tout) :
+ nfs_get_rpcclient(saddr, salen, protocol,
+ program, version, &tout);
if (client != NULL) {
result = nfs_gp_ping(client, tout);
nfs_gp_map_tcp_errorcodes(protocol);
diff --git a/utils/mount/network.c b/utils/mount/network.c
index 01ead49f..d9221567 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -525,7 +525,7 @@ static void nfs_pp_debug2(const char *str)
*/
static int nfs_probe_port(const struct sockaddr *sap, const
socklen_t salen,
struct pmap *pmap, const unsigned long
*versions,
- const unsigned int *protos)
+ const unsigned int *protos, const int
resvp)
{
union nfs_sockaddr address;
struct sockaddr *saddr = &address.sa;
@@ -550,7 +550,7 @@ static int nfs_probe_port(const struct sockaddr
*sap, const socklen_t salen,
nfs_pp_debug(saddr, salen, prog,
*p_vers,
*p_prot, p_port);
if (nfs_rpc_ping(saddr, salen,
prog,
- *p_vers,
*p_prot, NULL))
+ *p_vers, *p_prot,
NULL, resvp))
goto out_ok;
} else
rpc_createerr.cf_stat =
RPC_PROGNOTREGISTERED;
@@ -603,7 +603,7 @@ out_ok:
* returned; rpccreateerr.cf_stat is set to reflect the nature of
the error.
*/
static int nfs_probe_nfsport(const struct sockaddr *sap, const
socklen_t salen,
- struct pmap *pmap, int checkv4)
+ struct pmap *pmap, int checkv4, int
resvp)
{
if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
return 1;
@@ -617,13 +617,13 @@ static int nfs_probe_nfsport(const struct
sockaddr *sap, const socklen_t salen,
memcpy(&save_sa, sap, salen);
ret = nfs_probe_port(sap, salen, pmap,
- probe_nfs3_only,
probe_proto);
+ probe_nfs3_only, probe_proto,
resvp);
if (!ret || !checkv4 || probe_proto !=
probe_tcp_first)
return ret;
nfs_set_port((struct sockaddr *)&save_sa,
NFS_PORT);
ret = nfs_rpc_ping((struct sockaddr *)&save_sa,
salen,
- NFS_PROGRAM, 4, IPPROTO_TCP, NULL);
+ NFS_PROGRAM, 4, IPPROTO_TCP,
NULL, resvp);
if (ret) {
rpc_createerr.cf_stat = RPC_FAILED;
rpc_createerr.cf_error.re_errno = EAGAIN;
@@ -632,7 +632,7 @@ static int nfs_probe_nfsport(const struct
sockaddr *sap, const socklen_t salen,
return 1;
} else
return nfs_probe_port(sap, salen, pmap,
- probe_nfs2_only,
probe_udp_only);
+ probe_nfs2_only,
probe_udp_only, resvp);
}
/*
@@ -649,17 +649,17 @@ static int nfs_probe_nfsport(const struct
sockaddr *sap, const socklen_t salen,
* returned; rpccreateerr.cf_stat is set to reflect the nature of
the error.
*/
static int nfs_probe_mntport(const struct sockaddr *sap, const
socklen_t salen,
- struct pmap *pmap)
+ struct pmap *pmap)
{
if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
return 1;
if (nfs_mount_data_version >= 4)
return nfs_probe_port(sap, salen, pmap,
- probe_mnt3_only,
probe_udp_first);
+ probe_mnt3_only,
probe_udp_first, 0);
else
return nfs_probe_port(sap, salen, pmap,
- probe_mnt1_first,
probe_udp_only);
+ probe_mnt1_first,
probe_udp_only, 0);
}
/*
@@ -676,9 +676,10 @@ static int nfs_probe_version_fixed(const
struct sockaddr *mnt_saddr,
struct pmap *mnt_pmap,
const struct sockaddr *nfs_saddr,
const socklen_t nfs_salen,
- struct pmap *nfs_pmap)
+ struct pmap *nfs_pmap,
+ const int resvp)
{
- if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap, 0))
+ if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap, 0,
resvp))
return 0;
return nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap);
}
@@ -706,7 +707,8 @@ int nfs_probe_bothports(const struct sockaddr
*mnt_saddr,
const struct sockaddr *nfs_saddr,
const socklen_t nfs_salen,
struct pmap *nfs_pmap,
- int checkv4)
+ int checkv4,
+ int resvp)
{
struct pmap save_nfs, save_mnt;
const unsigned long *probe_vers;
@@ -718,7 +720,8 @@ int nfs_probe_bothports(const struct sockaddr
*mnt_saddr,
if (nfs_pmap->pm_vers)
return nfs_probe_version_fixed(mnt_saddr,
mnt_salen, mnt_pmap,
- nfs_saddr,
nfs_salen, nfs_pmap);
+ nfs_saddr,
nfs_salen, nfs_pmap,
+ resvp);
memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
@@ -727,7 +730,8 @@ int nfs_probe_bothports(const struct sockaddr
*mnt_saddr,
for (; *probe_vers; probe_vers++) {
nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
- if (nfs_probe_nfsport(nfs_saddr, nfs_salen,
nfs_pmap, checkv4) != 0) {
+ if (nfs_probe_nfsport(nfs_saddr, nfs_salen,
nfs_pmap, checkv4,
+ resvp) != 0) {
mnt_pmap->pm_vers = *probe_vers;
if (nfs_probe_mntport(mnt_saddr,
mnt_salen, mnt_pmap) != 0)
return 1;
@@ -759,7 +763,7 @@ int nfs_probe_bothports(const struct sockaddr
*mnt_saddr,
* Otherwise zero is returned; rpccreateerr.cf_stat is set to
reflect
* the nature of the error.
*/
-int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t
*nfs_server)
+int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t
*nfs_server, int resvp)
{
struct sockaddr *mnt_addr = SAFE_SOCKADDR(&mnt_server-
saddr);
struct sockaddr *nfs_addr = SAFE_SOCKADDR(&nfs_server-
saddr);
@@ -767,7 +771,7 @@ int probe_bothports(clnt_addr_t *mnt_server,
clnt_addr_t *nfs_server)
return nfs_probe_bothports(mnt_addr, sizeof(mnt_server-
saddr),
&mnt_server->pmap,
nfs_addr,
sizeof(nfs_server->saddr),
- &nfs_server->pmap, 0);
+ &nfs_server->pmap, 0,
resvp);
}
/**
diff --git a/utils/mount/network.h b/utils/mount/network.h
index 0fc98acd..8bcc7ace 100644
--- a/utils/mount/network.h
+++ b/utils/mount/network.h
@@ -39,10 +39,10 @@ typedef struct {
static const struct timeval TIMEOUT = { 20, 0 };
static const struct timeval RETRY_TIMEOUT = { 3, 0 };
-int probe_bothports(clnt_addr_t *, clnt_addr_t *);
+int probe_bothports(clnt_addr_t *, clnt_addr_t *, int);
int nfs_probe_bothports(const struct sockaddr *, const socklen_t,
struct pmap *, const struct sockaddr *,
- const socklen_t, struct pmap *, int);
+ const socklen_t, struct pmap *, int, int);
int nfs_gethostbyname(const char *, struct sockaddr_in *);
int nfs_lookup(const char *hostname, const sa_family_t family,
struct sockaddr *sap, socklen_t *salen);
diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
index 3d95da94..a792c6e7 100644
--- a/utils/mount/nfsmount.c
+++ b/utils/mount/nfsmount.c
@@ -123,13 +123,13 @@ nfs2_mount(CLIENT *clnt, mnt2arg_t *mnt2arg,
mnt2res_t *mnt2res)
static int
nfs_call_mount(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server,
- mntarg_t *mntarg, mntres_t *mntres)
+ mntarg_t *mntarg, mntres_t *mntres, int resvp)
{
CLIENT *clnt;
enum clnt_stat stat;
int msock;
- if (!probe_bothports(mnt_server, nfs_server))
+ if (!probe_bothports(mnt_server, nfs_server, resvp))
goto out_bad;
clnt = mnt_openclnt(mnt_server, &msock);
@@ -164,7 +164,8 @@ nfs_call_mount(clnt_addr_t *mnt_server,
clnt_addr_t *nfs_server,
static int
parse_options(char *old_opts, struct nfs_mount_data *data,
int *bg, int *retry, clnt_addr_t *mnt_server,
- clnt_addr_t *nfs_server, char *new_opts, const int
opt_size)
+ clnt_addr_t *nfs_server, char *new_opts, const int
opt_size,
+ int *resvp)
{
struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
struct pmap *mnt_pmap = &mnt_server->pmap;
@@ -177,6 +178,7 @@ parse_options(char *old_opts, struct
nfs_mount_data *data,
data->flags = 0;
*bg = 0;
+ *resvp = 1;
len = strlen(new_opts);
tmp_opts = xstrdup(old_opts);
@@ -365,6 +367,8 @@ parse_options(char *old_opts, struct
nfs_mount_data *data,
data->flags &= ~NFS_MOUNT_NOAC;
if (!val)
data->flags |=
NFS_MOUNT_NOAC;
+ } else if (!strcmp(opt, "resvport")) {
+ *resvp = val;
#if NFS_MOUNT_VERSION >= 2
} else if (!strcmp(opt, "tcp")) {
data->flags &= ~NFS_MOUNT_TCP;
@@ -498,6 +502,7 @@ nfsmount(const char *spec, const char *node,
int flags,
static struct nfs_mount_data data;
int val;
static int doonce = 0;
+ int resvp;
clnt_addr_t mnt_server = {
.hostname = &mounthost
@@ -582,7 +587,7 @@ nfsmount(const char *spec, const char *node,
int flags,
/* parse options */
new_opts[0] = 0;
if (!parse_options(old_opts, &data, &bg, &retry,
&mnt_server, &nfs_server,
- new_opts, sizeof(new_opts)))
+ new_opts, sizeof(new_opts), &resvp))
goto fail;
if (!nfsmnt_check_compat(nfs_pmap, mnt_pmap))
goto fail;
@@ -620,6 +625,7 @@ nfsmount(const char *spec, const char *node,
int flags,
#if NFS_MOUNT_VERSION >= 5
printf(_(", sec = %u"), data.pseudoflavor);
printf(_(", readdirplus = %d"), (data.flags &
NFS_MOUNT_NORDIRPLUS) != 0);
+ printf(_(", resvp = %u"), resvp);
#endif
printf("\n");
#endif
@@ -670,7 +676,7 @@ nfsmount(const char *spec, const char *node,
int flags,
sleep(30);
stat = nfs_call_mount(&mnt_server,
&nfs_server,
- &dirname, &mntres);
+ &dirname, &mntres,
resvp);
if (stat)
break;
memcpy(nfs_pmap, &save_nfs,
sizeof(*nfs_pmap));
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index a92c4200..85b8ca5a 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -337,6 +337,20 @@ static int nfs_verify_lock_option(struct
mount_options *options)
return 1;
}
+static const char *nfs_resvport_opttbl[] = {
+ "noresvport",
+ "resvport",
+ NULL,
+};
+
+/*
+ * Returns true unless "noresvport" is set
+ */
+static int nfs_resvport_option(struct mount_options *options)
+{
+ return po_rightmost(options, nfs_resvport_opttbl) != 0;
+}
+
static int nfs_insert_sloppy_option(struct mount_options
*options)
{
if (linux_version_code() < MAKE_VERSION(2, 6, 27))
@@ -550,7 +564,7 @@ static int nfs_construct_new_options(struct
mount_options *options,
* FALSE is returned if some failure occurred.
*/
static int
-nfs_rewrite_pmap_mount_options(struct mount_options *options, int
checkv4)
+nfs_rewrite_pmap_mount_options(struct mount_options *options, int
checkv4, int resvp)
{
union nfs_sockaddr nfs_address;
struct sockaddr *nfs_saddr = &nfs_address.sa;
@@ -604,7 +618,8 @@ nfs_rewrite_pmap_mount_options(struct
mount_options *options, int checkv4)
* negotiate. Bail now if we can't contact it.
*/
if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap,
- nfs_saddr, nfs_salen, &nfs_pmap,
checkv4)) {
+ nfs_saddr, nfs_salen, &nfs_pmap,
+ checkv4, resvp)) {
errno = ESPIPE;
if (rpc_createerr.cf_stat ==
RPC_PROGNOTREGISTERED)
errno = EOPNOTSUPP;
@@ -670,6 +685,7 @@ static int nfs_do_mount_v3v2(struct
nfsmount_info *mi,
{
struct mount_options *options = po_dup(mi->options);
int result = 0;
+ int resvp;
if (!options) {
errno = ENOMEM;
@@ -704,11 +720,13 @@ static int nfs_do_mount_v3v2(struct
nfsmount_info *mi,
goto out_fail;
}
+ resvp = nfs_resvport_option(options);
+
if (verbose)
printf(_("%s: trying text-based options '%s'\n"),
progname, *mi->extra_opts);
- if (!nfs_rewrite_pmap_mount_options(options, checkv4))
+ if (!nfs_rewrite_pmap_mount_options(options, checkv4,
resvp))
goto out_fail;
result = nfs_sys_mount(mi, options);