1
#!/bin/sh /usr/share/dpatch/dpatch-run
2
## 060_non_replicated_ping.dpatch
8
diff -Naur .B/modules/mount_nfs.c .A/modules/mount_nfs.c
9
--- .B/modules/mount_nfs.c 2005-04-05 12:42:42.000000000 +0000
10
+++ .A/modules/mount_nfs.c 2007-01-07 21:36:35.000000000 +0000
12
#include <netinet/in.h>
13
#include <linux/nfs.h>
14
#include <linux/nfs2.h>
18
#include "automount.h"
19
@@ -105,28 +106,117 @@
25
+ * If the entry doesn't contain a ',' or doesn't contain more than
26
+ * one ':' then @what is not a replicated server entry.
28
+static int inline is_replicated_entry(char *what)
30
+ return strchr(what, ',') ||
31
+ (strchr(what, ':') != strrchr(what, ':'));
35
+ * Check to see if the 'host:path' or 'host' is on the local machine
36
+ * Returns < 0 if there is a host lookup problem, otherwise returns 0
37
+ * if it's not a local mount, and returns > 0 if it is a local mount.
39
+int is_local_mount(const char *hostpath)
48
+ debug(MODPREFIX "is_local_mount: %s", hostpath);
49
+ delim = strpbrk(hostpath,":");
52
+ hostnamelen = delim - hostpath;
54
+ hostnamelen = strlen(hostpath);
56
+ hostname = malloc(hostnamelen+1);
57
+ strncpy(hostname, hostpath, hostnamelen);
58
+ hostname[hostnamelen] = '\0';
59
+ he = gethostbyname(hostname);
61
+ error(MODPREFIX "host %s: lookup failure", hostname);
65
+ for (haddr = he->h_addr_list; *haddr; haddr++) {
66
+ local = is_local_addr(hostname, *haddr, he->h_length);
70
+ debug(MODPREFIX "host %s: is localhost",
79
* Given a mount string, return (in the same string) the
80
- * best mount to use based on weight/locality/rpctime
81
+ * best mount to use based on locality/weight/rpctime.
83
+ * If longtimeout is set to 0 then we only do 100 ms pings to hosts. In
84
+ * the event that this fails, we call ourself recursively with the
85
+ * longtimeout option set to 1. In this case we ping for up to 10s and
86
+ * skip logic for detecting if a localhost has been passed. (if a local
87
+ * host had been passed, we would have returned that mount as the best
88
+ * mount. The skipping of local maps in this case is an optimization).
90
* - return -1 and what = '\0' on error,
91
* 1 and what = local mount path if local bind,
92
* else 0 and what = remote mount path
94
-int get_best_mount(char *what, const char *original, int longtimeout, int skiplocal)
95
+int get_best_mount(char *what, const char *original, int longtimeout)
99
int winner_weight = INT_MAX, local = 0;
100
double winner_time = 0;
102
+ char *delim, *pstrip;
103
int sec = (longtimeout) ? 10 : 0;
104
int micros = (longtimeout) ? 0 : 100000;
105
+ int skiplocal = longtimeout; /* clearly local is not available */
113
+ * If only one mountpoint has been passed in, we don't need to
114
+ * do anything except strip whitespace from the end of the string.
116
+ if (!is_replicated_entry(p)) {
117
+ for (pstrip = p+strlen(p) - 1; pstrip >= p; pstrip--)
118
+ if (isspace(*pstrip))
121
+ /* Check if the host is the localhost */
122
+ if (is_local_mount(p) > 0) {
123
+ debug(MODPREFIX "host %s: is localhost", p);
125
+ /* Strip off hostname and ':' */
126
+ delim = strchr(p,':');
127
+ while (delim && *delim != '\0') {
139
unsigned int ping_stat = 0;
140
@@ -171,37 +261,17 @@
141
/* p points to a server, "next is our next parse point */
143
/* Check if it's localhost */
144
- struct hostent *he;
147
- he = gethostbyname(p);
149
- error(MODPREFIX "host %s: lookup failure", p);
154
- /* Check each host in round robin list */
155
- for (haddr = he->h_addr_list; *haddr; haddr++) {
156
- local = is_local_addr(p, *haddr, he->h_length);
167
+ local = is_local_mount(p);
181
/* ping each (or the) entry to see if it's alive. */
183
/* First unweighted or only host is alive so set winner */
187
/* No more to check, return it */
192
if (!local && winner_weight == INT_MAX) {
193
/* We had more than one contender and none responded in time */
194
- if (winner_time != 0 && winner_time > 500) {
195
+ if (winner_time == 0 || winner_time > 500) {
196
/* We've already tried a longer timeout */
198
/* Reset string and try again */
199
@@ -267,16 +338,14 @@
200
"retrying with longer timeout",
203
- return get_best_mount(what, original, 1, 1);
204
+ return get_best_mount(what, original, 1);
209
- /* No winner found so bail */
214
+ /* No winner found so return first */
219
* We now have our winner, copy it to the front of the string,
221
/* No colon, take this as a bind (local) entry */
223
} else if (!nosymlink) {
224
- local = get_best_mount(whatstr, what, 0, 0);
225
+ local = get_best_mount(whatstr, what, 0);
227
warn(MODPREFIX "no host elected");