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");