* Use the portmapper to discover whether or not the service we want is
* available. The lists 'versions' and 'protos' define ordered sequences
* of service versions and udp/tcp protocols to probe for.
+ * If 'ping' is set, set an RPC NULL request to make sure the service
+ * is there. Else just assume that it is.
*/
static int probe_port(clnt_addr_t *server, const unsigned long *versions,
- const unsigned int *protos)
+ const unsigned int *protos, int ping)
{
struct sockaddr_in *saddr = &server->saddr;
struct pmap *pmap = &server->pmap;
_("UDP") : _("TCP"),
p_port);
}
- if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
+ if (!ping ||
+ clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
goto out_ok;
}
}
return 1;
}
-static int probe_nfsport(clnt_addr_t *nfs_server)
+static int probe_nfsport(clnt_addr_t *nfs_server, int ping)
{
struct pmap *pmap = &nfs_server->pmap;
return 1;
if (nfs_mount_data_version >= 4)
- return probe_port(nfs_server, probe_nfs3_first, probe_tcp_first);
+ return probe_port(nfs_server, probe_nfs3_first, probe_tcp_first,
+ ping);
else
- return probe_port(nfs_server, probe_nfs2_only, probe_udp_only);
+ return probe_port(nfs_server, probe_nfs2_only, probe_udp_only,
+ ping);
}
-static int probe_mntport(clnt_addr_t *mnt_server)
+static int probe_mntport(clnt_addr_t *mnt_server, int ping)
{
struct pmap *pmap = &mnt_server->pmap;
return 1;
if (nfs_mount_data_version >= 4)
- return probe_port(mnt_server, probe_mnt3_first, probe_udp_first);
+ return probe_port(mnt_server, probe_mnt3_first, probe_udp_first,
+ ping);
else
- return probe_port(mnt_server, probe_mnt1_first, probe_udp_only);
+ return probe_port(mnt_server, probe_mnt1_first, probe_udp_only,
+ ping);
}
/**
*
* A side effect of calling this function is that rpccreateerr is set.
*/
-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 ping)
{
struct pmap *nfs_pmap = &nfs_server->pmap;
struct pmap *mnt_pmap = &mnt_server->pmap;
for (; *probe_vers; probe_vers++) {
nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
- if ((res = probe_nfsport(nfs_server) != 0)) {
+ if ((res = probe_nfsport(nfs_server, ping) != 0)) {
mnt_pmap->pm_vers = *probe_vers;
- if ((res = probe_mntport(mnt_server)) != 0)
+ if ((res = probe_mntport(mnt_server, ping)) != 0)
return 1;
memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
}
return 0;
version_fixed:
- if (!probe_nfsport(nfs_server))
+ if (!probe_nfsport(nfs_server, ping))
goto out_bad;
- return probe_mntport(mnt_server);
+ return probe_mntport(mnt_server, ping);
}
static int probe_statd(void)
enum clnt_stat res = 0;
int msock;
- if (!probe_mntport(mnt_server))
+ if (!probe_mntport(mnt_server, 0))
return 0;
clnt = mnt_openclnt(mnt_server, &msock);
if (!clnt)
* Returns a new group of mount options if successful; otherwise
* NULL is returned if some failure occurred.
*/
-static struct mount_options *nfs_rewrite_mount_options(char *str)
+static struct mount_options *nfs_rewrite_mount_options(char *str, int ping)
{
struct mount_options *options;
char *option, new_option[64];
po_remove_all(options, "tcp");
po_remove_all(options, "udp");
- if (!probe_bothports(&mnt_server, &nfs_server)) {
+ if (!probe_bothports(&mnt_server, &nfs_server, ping)) {
errno = ESPIPE;
goto err;
}
if (po_append(options, new_option) == PO_FAILED)
goto err;
- snprintf(new_option, sizeof(new_option) - 1,
- "mountport=%lu", mnt_server.pmap.pm_port);
- if (po_append(options, new_option) == PO_FAILED)
- goto err;
-
errno = 0;
return options;
* 'extra_opts' are updated to reflect the mount options that worked.
* If the retry fails, 'options' and 'extra_opts' are left unchanged.
*/
-static int nfs_retry_nfs23mount(struct nfsmount_info *mi)
+static int nfs_try_nfs23mount_probe(struct nfsmount_info *mi, int ping)
{
struct mount_options *retry_options;
char *retry_str = NULL;
char **extra_opts = mi->extra_opts;
- retry_options = nfs_rewrite_mount_options(*extra_opts);
+ retry_options = nfs_rewrite_mount_options(*extra_opts, ping);
if (!retry_options)
return 0;
if (mi->fake)
return 1;
- if (nfs_sys_mount(mi, "nfs", *extra_opts))
+ if (nfs_try_nfs23mount_probe(mi, 0))
return 1;
/*
if (errno != EOPNOTSUPP && errno != EPROTONOSUPPORT)
return 0;
- return nfs_retry_nfs23mount(mi);
+ /* Probe harder */
+ return nfs_try_nfs23mount_probe(mi, 1);
}
/*