If an NFS server is only listening on TCP for portmap (as apparently
authorNeil Brown <neilb@suse.de>
Wed, 16 Jul 2008 17:15:46 +0000 (13:15 -0400)
committerSteve Dickson <steved@dickson.boston.devel.redhat.com>
Wed, 16 Jul 2008 17:15:46 +0000 (13:15 -0400)
MS-Windows-Server2003R2SP2 does), mount doesn't cope.  There is retry
logic in case the initial choice of version/etc doesn't work, but it
doesn't cope with mountd needing tcp.
So:
  Fix probe_port so that a TIMEDOUT error doesn't simply abort
    but probes with other protocols (e.g. tcp).
  Fix rewrite_mount_options to extract the mountproto option before
    doing a probe, then set mountproto  (and mount prot) based
    on the result.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Steve Dickson <steved@redhat.com>
utils/mount/network.c
utils/mount/stropts.c

index 7d3d09a..75354a7 100644 (file)
@@ -532,11 +532,10 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions,
                                 }
                                if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
                                        goto out_ok;
-                               if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
-                                       goto out_bad;
                        }
                }
                if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED &&
+                   rpc_createerr.cf_stat != RPC_TIMEDOUT &&
                    rpc_createerr.cf_stat != RPC_PROGVERSMISMATCH)
                        goto out_bad;
 
@@ -545,6 +544,9 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions,
                                continue;
                        p_prot = protos;
                }
+               if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
+                       goto out_bad;
+
                if (vers || !*++p_vers)
                        break;
        }
index e4a4408..09fca86 100644 (file)
@@ -353,6 +353,17 @@ static struct mount_options *nfs_rewrite_mount_options(char *str)
        option = po_get(options, "mountvers");
        if (option)
                mnt_server.pmap.pm_vers = atoi(option);
+       option = po_get(options, "mountproto");
+       if (option) {
+               if (strcmp(option, "tcp") == 0) {
+                       mnt_server.pmap.pm_prot = IPPROTO_TCP;
+                       po_remove_all(options, "mountproto");
+               }
+               if (strcmp(option, "udp") == 0) {
+                       mnt_server.pmap.pm_prot = IPPROTO_UDP;
+                       po_remove_all(options, "mountproto");
+               }
+       }
 
        option = po_get(options, "port");
        if (option) {
@@ -421,6 +432,20 @@ static struct mount_options *nfs_rewrite_mount_options(char *str)
 
        }
 
+       if (mnt_server.pmap.pm_prot == IPPROTO_TCP)
+               snprintf(new_option, sizeof(new_option) - 1,
+                        "mountproto=tcp");
+       else
+               snprintf(new_option, sizeof(new_option) - 1,
+                        "mountproto=udp");
+       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;