Hi all,

Here are two patches:

1. Update rpc ping logic to try TCP and also try NFS V2 and V3.
   I hope I haven't broken anything. It should be transparent for
   map entries that are not multi-mount syntax. It will delay
   for a while if packets are droped instead of rejected from
   a packet filter but what else can we do. Oh and adjusting
   the timeout makes no difference cause the timeout is at a
   lower network layer.

2. Make nonstrict the default option for multi-mount map
   entries. Seems to work OK. It essentially ignores existing
   nonstrict option so as not to cause grief for those that
   already use it. The option is now strict instead. Check
   the man page entries and let me know if they are sane.
   ie. automount.8 and autofs.5.

If anyone has time to test these please let me know how it goes.

Ian
diff -Nur autofs-4.1.3.orig/include/automount.h autofs-4.1.3/include/automount.h
--- autofs-4.1.3.orig/include/automount.h       2004-05-16 12:07:10.000000000 +0800
+++ autofs-4.1.3/include/automount.h    2004-05-16 17:36:38.000000000 +0800
@@ -241,8 +241,16 @@
               const char *dir, const char *base, size_t blen);
 
 /* rpc helper subs */
-int rpc_ping(const char *host, long seconds, long micros);
-int rpc_time(const char *host, int seconds, int micros, double *result);
+#define RPC_PING_FAIL           0x0000
+#define RPC_PING_V2             NFS2_VERSION
+#define RPC_PING_V3             NFS3_VERSION
+#define RPC_PING_UDP            0x0100
+#define RPC_PING_TCP            0x0200
+
+unsigned int rpc_ping(const char *host, long seconds, long micros);
+int rpc_time(const char *host, 
+            unsigned int ping_vers, unsigned int ping_proto,
+            long seconds, long micros, double *result);
 
 /* log notification */
 extern int do_verbose;
diff -Nur autofs-4.1.3.orig/lib/rpc_subs.c autofs-4.1.3/lib/rpc_subs.c
--- autofs-4.1.3.orig/lib/rpc_subs.c    2004-05-16 12:07:10.000000000 +0800
+++ autofs-4.1.3/lib/rpc_subs.c 2004-05-16 17:36:38.000000000 +0800
@@ -1,15 +1,20 @@
 #include <rpc/rpc.h>
 #include <nfs/nfs.h>
 #include <linux/nfs2.h>
+#include <linux/nfs3.h>
 #include <rpc/xdr.h>
  
-int rpc_ping(const char *host, long seconds, long micros)
+#include "automount.h"
+
+static int rpc_ping_proto(const char *host,
+                         unsigned long nfs_version, const char *proto,
+                         long seconds, long micros)
 {
        CLIENT *client;
        struct timeval tout;
        enum clnt_stat stat;
 
-       client = clnt_create(host, NFS_PROGRAM, NFS2_VERSION, "udp");
+       client = clnt_create(host, NFS_PROGRAM, nfs_version, proto);
        if (client == NULL) {
                return 0;
        }
@@ -32,6 +37,49 @@
        return 1;
 }
 
+static unsigned int rpc_ping_v2(const char *host, long seconds, long micros)
+{
+       unsigned int status = RPC_PING_FAIL;
+
+       status = rpc_ping_proto(host, NFS2_VERSION, "udp", seconds, micros);
+       if (status)
+               return RPC_PING_V2 | RPC_PING_UDP;
+
+       status = rpc_ping_proto(host, NFS2_VERSION, "tcp", seconds, micros);
+       if (status)
+               return RPC_PING_V2 | RPC_PING_TCP;
+
+       return status;
+}
+
+static unsigned int rpc_ping_v3(const char *host, long seconds, long micros)
+{
+       unsigned int status = RPC_PING_FAIL;
+
+       status = rpc_ping_proto(host, NFS3_VERSION, "udp", seconds, micros);
+       if (status)
+               return RPC_PING_V3 | RPC_PING_UDP;
+
+       status = rpc_ping_proto(host, NFS3_VERSION, "tcp", seconds, micros);
+       if (status)
+               return RPC_PING_V3 | RPC_PING_TCP;
+
+       return status;
+}
+
+unsigned int rpc_ping(const char *host, long seconds, long micros)
+{
+       unsigned int status;
+
+       status = rpc_ping_v2(host, seconds, micros);
+       if (status)
+               return status;
+
+       status = rpc_ping_v3(host, seconds, micros);
+       
+       return status;
+}
+
 static double elapsed(struct timeval start, struct timeval end)
 {
        double t1, t2;
@@ -40,34 +88,21 @@
        return t2-t1;
 }
 
-int rpc_time(const char *host, int seconds, int micros, double *result)
+int rpc_time(const char *host,
+            unsigned int ping_vers, unsigned int ping_proto,
+            long seconds, long micros, double *result)
 {
-       CLIENT *client;
-       struct timeval tout;
-       enum clnt_stat stat;
+       int status;
+       double taken;
        struct timeval start, end;
        struct timezone tz;
-       double taken;
-
-       client = clnt_create(host, NFS_PROGRAM, NFS2_VERSION, "udp");
-       if (client == NULL) {
-               return 0;
-       }
-
-       tout.tv_sec = seconds;
-       tout.tv_usec = micros;
-
-       clnt_control(client, CLSET_TIMEOUT, (char *)&tout);
-       clnt_control(client, CLSET_RETRY_TIMEOUT, (char *)&tout);
+       char *proto = (ping_proto & RPC_PING_UDP) ? "udp" : "tcp";
 
        gettimeofday(&start, &tz);
-       stat = clnt_call(client, NFSPROC_NULL,
-                       (xdrproc_t)xdr_void, 0, (xdrproc_t)xdr_void, 0, tout);
+       status = rpc_ping_proto(host, ping_vers, proto, seconds, micros);
        gettimeofday(&end, &tz);
 
-       clnt_destroy(client);
-
-       if (stat != RPC_SUCCESS) {
+       if (!status) {
                return 0;
        }
 
@@ -77,6 +112,6 @@
                *result = taken;
        }
 
-       return 1;
+       return status;
 }
 
diff -Nur autofs-4.1.3.orig/modules/mount_nfs.c autofs-4.1.3/modules/mount_nfs.c
--- autofs-4.1.3.orig/modules/mount_nfs.c       2004-05-16 12:07:10.000000000 +0800
+++ autofs-4.1.3/modules/mount_nfs.c    2004-05-16 17:36:38.000000000 +0800
@@ -29,6 +29,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <netinet/in.h>
+#include <linux/nfs.h>
+#include <linux/nfs2.h>
 
 #define MODULE_MOUNT
 #include "automount.h"
@@ -139,6 +141,7 @@
 
        while (p && *p) {
                char *next;
+               unsigned int ping_stat = 0;
 
                p += strspn(p, " \t,");
                delim = strpbrk(p, "(, \t:");
@@ -148,7 +151,7 @@
                /* Find lowest weight whose server is alive */
                if (*delim == '(') {
                        char *weight = delim + 1;
-                       int alive;
+                       unsigned int alive;
 
                        *delim = '\0';
 
@@ -217,7 +220,7 @@
                 * If it's not local and it's a replicated server map entry
                 * is it alive
                 */
-               if (!local && is_replicated && !rpc_ping(p, sec, micros)) {
+               if (!local && is_replicated && !(ping_stat = rpc_ping(p, sec, 
micros))) {
                        p = next;
                        continue;
                }
@@ -228,18 +231,25 @@
                }
                /* compare RPC times if there are no weighted hosts */
                else if (winner_weight == INT_MAX) {
+                       int status;
                        double resp_time;
+                       unsigned int vers = NFS2_VERSION;
+                       unsigned int proto = RPC_PING_UDP;
 
+                       if (ping_stat) {
+                               vers = ping_stat & 0x00ff;
+                               proto = ping_stat & 0xff00;
+                       }
+
+                       status = rpc_time(winner, vers, proto, sec, micros, 
&resp_time);
                        /* did we time the first winner? */
                        if (winner_time == 0) {
-                               if (rpc_time(winner, sec, micros, &resp_time))
+                               if (status)
                                        winner_time = resp_time;
                                else
                                        winner_time = 6;
-                       }
-
-                       if (rpc_time(winner, sec, micros, &resp_time)) {
-                               if (resp_time < winner_time) {
+                       } else {
+                               if ((status) && (resp_time < winner_time)) {
                                        winner = p;
                                        winner_time = resp_time;
                                }
Files autofs-4.1.3.orig/man/autofs-4.1.3.tar.bz2 and 
autofs-4.1.3/man/autofs-4.1.3.tar.bz2 differ
diff -Nur autofs-4.1.3.orig/man/autofs.5 autofs-4.1.3/man/autofs.5
--- autofs-4.1.3.orig/man/autofs.5      2004-05-16 17:36:09.000000000 +0800
+++ autofs-4.1.3/man/autofs.5   2004-05-16 20:16:40.000000000 +0800
@@ -46,10 +46,10 @@
 used to specify a filesystem type if the filesystem is not of the default
 NFS type.  This option is processed by the automounter and not by the mount
 command.
-.I -nonstrict
-used to ignore file systems that can't be mounted. This is important if
+.I -strict
+is used to treat errors when mounting file systems as fatal. This is important when
 multiple file systems should be mounted (`multimounts'). If this option
-is not given, no file system is mounted at all if at least one file system
+is given, no file system is mounted at all if at least one file system
 can't be mounted.
 
 .SS location
diff -Nur autofs-4.1.3.orig/man/automount.8 autofs-4.1.3/man/automount.8
--- autofs-4.1.3.orig/man/automount.8   2004-05-16 17:36:09.000000000 +0800
+++ autofs-4.1.3/man/automount.8        2004-05-16 20:04:50.000000000 +0800
@@ -114,6 +114,12 @@
 .TP
 .I "\-Dvariable=value"
 Replace \fIvariable\fP with \fIvalue\fP in map substitutions.
+.TP
+.I "\-strict"
+Treat errors when mounting file systems as fatal. This is important when
+multiple file systems should be mounted (`multimounts'). If this option
+is given, no file system is mounted at all if at least one file system
+can't be mounted.
 .RE
 .SH NOTES
 If the \fBautomount\fP daemon catches signal USR1, it will unmount all
diff -Nur autofs-4.1.3.orig/modules/parse_sun.c autofs-4.1.3/modules/parse_sun.c
--- autofs-4.1.3.orig/modules/parse_sun.c       2004-05-16 17:36:09.000000000 +0800
+++ autofs-4.1.3/modules/parse_sun.c    2004-05-16 19:08:15.000000000 +0800
@@ -517,7 +517,7 @@
                     const char *loc, int loclen, const char *options)
 {
        char *fstype = "nfs";   /* Default filesystem type */
-       int nonstrict = 0;
+       int nonstrict = 1;
        int rv;
        char *mountpoint;
        char *what;
@@ -551,6 +551,8 @@
                                fstype = alloca(typelen + 1);
                                memcpy(fstype, cp + 7, typelen);
                                fstype[typelen] = '\0';
+                       } else if (strncmp("strict", cp, 6) == 0) {
+                               nonstrict = 0;
                        } else if (strncmp("nonstrict", cp, 9) == 0) {
                                nonstrict = 1;
                        } else {
_______________________________________________
autofs mailing list
[EMAIL PROTECTED]
http://linux.kernel.org/mailman/listinfo/autofs

Reply via email to