]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/network.c
mount.nfs: force rpcbind queries if options aren't specified
[nfs-utils.git] / utils / mount / network.c
index 3080378386e500d3f8f06d3d7f71306b15298f53..1e0526332be03ae33801bc084a69e81ef641ab00 100644 (file)
@@ -509,6 +509,21 @@ static void nfs_pp_debug(const struct sockaddr *sap, const socklen_t salen,
                        port);
 }
 
+static void nfs_pp_debug2(const char *str)
+{
+       if (!verbose)
+               return;
+
+       if (rpc_createerr.cf_error.re_status == RPC_CANTRECV ||
+           rpc_createerr.cf_error.re_status == RPC_CANTSEND)
+               nfs_error(_("%s: portmap query %s%s - %s"),
+                               progname, str, clnt_spcreateerror(""),
+                               strerror(rpc_createerr.cf_error.re_errno));
+       else
+               nfs_error(_("%s: portmap query %s%s"),
+                               progname, str, clnt_spcreateerror(""));
+}
+
 /*
  * Use the portmapper to discover whether or not the service we want is
  * available. The lists 'versions' and 'protos' define ordered sequences
@@ -540,6 +555,9 @@ static int nfs_probe_port(const struct sockaddr *sap, const socklen_t salen,
        p_vers = vers ? &vers : versions;
 
        for (;;) {
+               if (verbose)
+                       printf(_("%s: prog %lu, trying vers=%lu, prot=%u\n"),
+                               progname, prog, *p_vers, *p_prot);
                p_port = nfs_getport(saddr, salen, prog, *p_vers, *p_prot);
                if (p_port) {
                        if (!port || port == p_port) {
@@ -549,28 +567,31 @@ static int nfs_probe_port(const struct sockaddr *sap, const socklen_t salen,
                                if (nfs_rpc_ping(saddr, salen, prog,
                                                        *p_vers, *p_prot, NULL))
                                        goto out_ok;
-                       }
+                       } else
+                               rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
                }
                if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED &&
                    rpc_createerr.cf_stat != RPC_TIMEDOUT &&
                    rpc_createerr.cf_stat != RPC_CANTRECV &&
                    rpc_createerr.cf_stat != RPC_PROGVERSMISMATCH)
-                       goto out_bad;
+                       break;
 
                if (!prot) {
-                       if (*++p_prot)
+                       if (*++p_prot) {
+                               nfs_pp_debug2("retrying");
                                continue;
+                       }
                        p_prot = protos;
                }
                if (rpc_createerr.cf_stat == RPC_TIMEDOUT ||
                    rpc_createerr.cf_stat == RPC_CANTRECV)
-                       goto out_bad;
+                       break;
 
                if (vers || !*++p_vers)
                        break;
        }
 
-out_bad:
+       nfs_pp_debug2("failed");
        return 0;
 
 out_ok:
@@ -1209,13 +1230,16 @@ static rpcvers_t nfs_nfs_version(struct mount_options *options)
  * Returns the NFS transport protocol specified by the given mount options
  *
  * Returns the IPPROTO_ value specified by the given mount options, or
- * IPPROTO_UDP if all fails.
+ * zero if all fails.  The protocol value will be filled in by an
+ * rpcbind query in this case.
  */
 static unsigned short nfs_nfs_protocol(struct mount_options *options)
 {
        char *option;
 
        switch (po_rightmost(options, nfs_transport_opttbl)) {
+       case 0: /* udp */
+               return IPPROTO_UDP;
        case 1: /* tcp */
                return IPPROTO_TCP;
        case 2: /* proto */
@@ -1228,7 +1252,7 @@ static unsigned short nfs_nfs_protocol(struct mount_options *options)
                }
        }
 
-       return IPPROTO_UDP;
+       return 0;
 }
 
 /*
@@ -1269,7 +1293,8 @@ static rpcprog_t nfs_mount_program(struct mount_options *options)
 
 /*
  * Returns the RPC version number specified by the given mount options,
- * or the version "3" if all fails.
+ * or zero if all fails.  The version value will be filled in by an
+ * rpcbind query in this case.
  */
 static rpcvers_t nfs_mount_version(struct mount_options *options)
 {
@@ -1279,15 +1304,15 @@ static rpcvers_t nfs_mount_version(struct mount_options *options)
                if (tmp >= 1 && tmp <= 4)
                        return tmp;
 
-       return nfsvers_to_mnt(nfs_nfs_version(options));
+       return 0;
 }
 
 /*
  * Returns the transport protocol to use for the mount service
  *
  * Returns the IPPROTO_ value specified by the mountproto option, or
- * if that doesn't exist, the IPPROTO_ value specified for NFS
- * itself.
+ * copies the NFS protocol setting.  If the protocol value is zero,
+ * the value will be filled in by an rpcbind query.
  */
 static unsigned short nfs_mount_protocol(struct mount_options *options)
 {
@@ -1309,7 +1334,7 @@ static unsigned short nfs_mount_protocol(struct mount_options *options)
  * mount options, or zero if all fails.  Zero results in a portmap
  * query to discover the server's mountd service port.
  *
- * port=0 will guarantee an rpcbind request precedes the mount
+ * mountport=0 will guarantee an rpcbind request precedes the mount
  * RPC so the client can determine the server's port number.
  */
 static unsigned short nfs_mount_port(struct mount_options *options)