]>
Commit | Line | Data |
---|---|---|
3d551623 PG |
1 | diff --git a/CHANGELOG b/CHANGELOG |
2 | index c36017a..0e9dc51 100644 | |
3 | --- a/CHANGELOG | |
4 | +++ b/CHANGELOG | |
5 | @@ -20,6 +20,7 @@ | |
6 | - fix don't fail on empty master map. | |
7 | - if there's no "automount" entry in nsswitch.conf use "files" source. | |
8 | - add LDAP schema discovery if no schema is configured. | |
9 | +- add random selection as a master map entry option. | |
10 | ||
11 | 18/06/2007 autofs-5.0.2 | |
12 | ----------------------- | |
13 | diff --git a/daemon/automount.c b/daemon/automount.c | |
14 | index 7b79f02..4b6584a 100644 | |
15 | --- a/daemon/automount.c | |
16 | +++ b/daemon/automount.c | |
17 | @@ -49,9 +49,9 @@ const char *confdir = AUTOFS_CONF_DIR; /* Location of autofs config file */ | |
18 | ||
19 | const char *global_options; /* Global option, from command line */ | |
20 | ||
21 | -static char *pid_file = NULL; /* File in which to keep pid */ | |
22 | -unsigned int random_selection; /* use random policy when selecting | |
23 | - * which multi-mount host to mount */ | |
24 | +static char *pid_file = NULL; /* File in which to keep pid */ | |
25 | +unsigned int global_random_selection; /* use random policy when selecting | |
26 | + * which multi-mount host to mount */ | |
27 | static int start_pipefd[2]; | |
28 | static int st_stat = 0; | |
29 | static int *pst_stat = &st_stat; | |
30 | @@ -1490,7 +1490,7 @@ int main(int argc, char *argv[]) | |
31 | timeout = defaults_get_timeout(); | |
32 | ghost = defaults_get_browse_mode(); | |
33 | logging = defaults_get_logging(); | |
34 | - random_selection = 0; | |
35 | + global_random_selection = 0; | |
36 | global_options = NULL; | |
37 | have_global_options = 0; | |
38 | foreground = 0; | |
39 | @@ -1531,7 +1531,7 @@ int main(int argc, char *argv[]) | |
40 | exit(0); | |
41 | ||
42 | case 'r': | |
43 | - random_selection = 1; | |
44 | + global_random_selection = 1; | |
45 | break; | |
46 | ||
47 | case 'O': | |
48 | diff --git a/include/automount.h b/include/automount.h | |
49 | index d9e4ecd..d55ba5c 100644 | |
50 | --- a/include/automount.h | |
51 | +++ b/include/automount.h | |
52 | @@ -448,6 +448,8 @@ struct autofs_point { | |
53 | enum states state; /* Current state */ | |
54 | int state_pipe[2]; /* State change router pipe */ | |
55 | unsigned dir_created; /* Directory created for this mount? */ | |
56 | + unsigned random_selection; /* Use random policy when selecting a | |
57 | + * host from which to mount */ | |
58 | struct autofs_point *parent; /* Owner of mounts list for submount */ | |
59 | pthread_mutex_t mounts_mutex; /* Protect mount lists */ | |
60 | pthread_cond_t mounts_cond; /* Submounts condition variable */ | |
61 | diff --git a/include/replicated.h b/include/replicated.h | |
62 | index c77cda6..3afe9f7 100644 | |
63 | --- a/include/replicated.h | |
64 | +++ b/include/replicated.h | |
65 | @@ -63,7 +63,7 @@ struct host { | |
66 | void seed_random(void); | |
67 | void free_host_list(struct host **); | |
68 | int parse_location(struct host **, const char *); | |
69 | -int prune_host_list(struct host **, unsigned int, const char *); | |
70 | +int prune_host_list(struct host **, unsigned int, const char *, unsigned int); | |
71 | void dump_host_list(struct host *); | |
72 | ||
73 | #endif | |
74 | diff --git a/lib/master_parse.y b/lib/master_parse.y | |
75 | index ab2895d..70b48be 100644 | |
76 | --- a/lib/master_parse.y | |
77 | +++ b/lib/master_parse.y | |
78 | @@ -56,6 +56,8 @@ static char *type; | |
79 | static char *format; | |
80 | static long timeout; | |
81 | static unsigned ghost; | |
82 | +extern unsigned global_random_selection; | |
83 | +static unsigned random_selection; | |
84 | static char **tmp_argv; | |
85 | static int tmp_argc; | |
86 | static char **local_argv; | |
87 | @@ -93,7 +95,7 @@ static int master_fprintf(FILE *, char *, ...); | |
88 | ||
89 | %token COMMENT | |
90 | %token MAP | |
91 | -%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG | |
92 | +%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG OPT_RANDOM | |
93 | %token COLON COMMA NL DDASH | |
94 | %type <strtype> map | |
95 | %type <strtype> options | |
96 | @@ -174,6 +176,7 @@ line: | |
97 | | PATH COLON { master_notify($1); YYABORT; } | |
98 | | PATH OPTION { master_notify($2); YYABORT; } | |
99 | | PATH NILL { master_notify($2); YYABORT; } | |
100 | + | PATH OPT_RANDOM { master_notify($1); YYABORT; } | |
101 | | PATH OPT_DEBUG { master_notify($1); YYABORT; } | |
102 | | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } | |
103 | | PATH OPT_GHOST { master_notify($1); YYABORT; } | |
104 | @@ -543,6 +546,7 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } | |
105 | | OPT_GHOST { ghost = 1; } | |
106 | | OPT_VERBOSE { verbose = 1; } | |
107 | | OPT_DEBUG { debug = 1; } | |
108 | + | OPT_RANDOM { random_selection = 1; } | |
109 | ; | |
110 | ||
111 | mount_option: OPTION | |
112 | @@ -600,6 +604,7 @@ static void local_init_vars(void) | |
113 | debug = 0; | |
114 | timeout = -1; | |
115 | ghost = defaults_get_browse_mode(); | |
116 | + random_selection = global_random_selection; | |
117 | tmp_argv = NULL; | |
118 | tmp_argc = 0; | |
119 | local_argv = NULL; | |
120 | @@ -790,6 +795,7 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne | |
121 | } | |
122 | set_mnt_logging(ap); | |
123 | } | |
124 | + entry->ap->random_selection = random_selection; | |
125 | ||
126 | /* | |
127 | source = master_find_map_source(entry, type, format, | |
128 | diff --git a/lib/master_tok.l b/lib/master_tok.l | |
129 | index ff69a24..013a15a 100644 | |
130 | --- a/lib/master_tok.l | |
131 | +++ b/lib/master_tok.l | |
132 | @@ -324,6 +324,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) | |
133 | -g|--ghost|-?browse { return(OPT_GHOST); } | |
134 | -v|--verbose { return(OPT_VERBOSE); } | |
135 | -d|--debug { return(OPT_DEBUG); } | |
136 | + -r|--random-multimount-selection { return(OPT_RANDOM); } | |
137 | ||
138 | {OPTWS}","{OPTWS} { return(COMMA); } | |
139 | ||
140 | diff --git a/man/auto.master.5.in b/man/auto.master.5.in | |
141 | index 249c9a7..ab5ab1e 100644 | |
142 | --- a/man/auto.master.5.in | |
143 | +++ b/man/auto.master.5.in | |
144 | @@ -146,6 +146,12 @@ to prevent symlinking of local NFS mounts. Nowadays it can be used to | |
145 | prevent bind mounting of local NFS filesystems as well. If you need to | |
146 | prevent bind mounting for only specific entrys in a map then this | |
147 | can be done by adding the "port=" mount option to the given entries. | |
148 | +.TP | |
149 | +.I "\-r, \-\-random-multimount-selection" | |
150 | +Enables the use of ramdom selection when choosing a host from a | |
151 | +list of replicated servers. This option is applied to this mount | |
152 | +only, overriding the global setting that may be specified on the | |
153 | +command line. | |
154 | .SH GENERAL SYSTEM DEFAULTS CONFIGURATION | |
155 | .P | |
156 | The default value of several general settings may be changed in the | |
157 | diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c | |
158 | index e7a9a8a..e4480c5 100644 | |
159 | --- a/modules/mount_nfs.c | |
160 | +++ b/modules/mount_nfs.c | |
161 | @@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int | |
162 | warn(ap->logopt, MODPREFIX "no hosts available"); | |
163 | return 1; | |
164 | } | |
165 | - prune_host_list(&hosts, vers, nfsoptions); | |
166 | + prune_host_list(&hosts, vers, nfsoptions, ap->random_selection); | |
167 | ||
168 | if (!hosts) { | |
169 | warn(ap->logopt, MODPREFIX "no hosts available"); | |
170 | diff --git a/modules/replicated.c b/modules/replicated.c | |
171 | index 0764d4a..e15587c 100644 | |
172 | --- a/modules/replicated.c | |
173 | +++ b/modules/replicated.c | |
174 | @@ -74,8 +74,6 @@ | |
175 | #define max(x, y) (x >= y ? x : y) | |
176 | #define mmax(x, y, z) (max(x, y) == x ? max(x, z) : max(y, z)) | |
177 | ||
178 | -extern unsigned int random_selection; | |
179 | - | |
180 | void seed_random(void) | |
181 | { | |
182 | int fd; | |
183 | @@ -392,7 +390,7 @@ static unsigned short get_port_option(const char *options) | |
184 | static unsigned int get_nfs_info(struct host *host, | |
185 | struct conn_info *pm_info, struct conn_info *rpc_info, | |
186 | const char *proto, unsigned int version, | |
187 | - const char *options) | |
188 | + const char *options, unsigned int random_selection) | |
189 | { | |
190 | char *have_port_opt = options ? strstr(options, "port=") : NULL; | |
191 | struct pmap parms; | |
192 | @@ -535,7 +533,9 @@ done_ver: | |
193 | return supported; | |
194 | } | |
195 | ||
196 | -static int get_vers_and_cost(struct host *host, unsigned int version, const char *options) | |
197 | +static int get_vers_and_cost(struct host *host, | |
198 | + unsigned int version, const char *options, | |
199 | + unsigned int random_selection) | |
200 | { | |
201 | struct conn_info pm_info, rpc_info; | |
202 | time_t timeout = RPC_TIMEOUT; | |
203 | @@ -559,7 +559,9 @@ static int get_vers_and_cost(struct host *host, unsigned int version, const char | |
204 | vers &= version; | |
205 | ||
206 | if (version & UDP_REQUESTED) { | |
207 | - supported = get_nfs_info(host, &pm_info, &rpc_info, "udp", vers, options); | |
208 | + supported = get_nfs_info(host, | |
209 | + &pm_info, &rpc_info, "udp", vers, | |
210 | + options, random_selection); | |
211 | if (supported) { | |
212 | ret = 1; | |
213 | host->version |= (supported << 8); | |
214 | @@ -567,7 +569,9 @@ static int get_vers_and_cost(struct host *host, unsigned int version, const char | |
215 | } | |
216 | ||
217 | if (version & TCP_REQUESTED) { | |
218 | - supported = get_nfs_info(host, &pm_info, &rpc_info, "tcp", vers, options); | |
219 | + supported = get_nfs_info(host, | |
220 | + &pm_info, &rpc_info, "tcp", vers, | |
221 | + options, random_selection); | |
222 | if (supported) { | |
223 | ret = 1; | |
224 | host->version |= supported; | |
225 | @@ -577,7 +581,9 @@ static int get_vers_and_cost(struct host *host, unsigned int version, const char | |
226 | return ret; | |
227 | } | |
228 | ||
229 | -static int get_supported_ver_and_cost(struct host *host, unsigned int version, const char *options) | |
230 | +static int get_supported_ver_and_cost(struct host *host, | |
231 | + unsigned int version, const char *options, | |
232 | + unsigned int random_selection) | |
233 | { | |
234 | char *have_port_opt = options ? strstr(options, "port=") : NULL; | |
235 | struct conn_info pm_info, rpc_info; | |
236 | @@ -695,7 +701,9 @@ done: | |
237 | return 0; | |
238 | } | |
239 | ||
240 | -int prune_host_list(struct host **list, unsigned int vers, const char *options) | |
241 | +int prune_host_list(struct host **list, | |
242 | + unsigned int vers, const char *options, | |
243 | + unsigned int random_selection) | |
244 | { | |
245 | struct host *this, *last, *first; | |
246 | struct host *new = NULL; | |
247 | @@ -734,7 +742,8 @@ int prune_host_list(struct host **list, unsigned int vers, const char *options) | |
248 | break; | |
249 | ||
250 | if (this->name) { | |
251 | - status = get_vers_and_cost(this, vers, options); | |
252 | + status = get_vers_and_cost(this, vers, | |
253 | + options, random_selection); | |
254 | if (!status) { | |
255 | if (this == first) { | |
256 | first = next; | |
257 | @@ -824,7 +833,9 @@ int prune_host_list(struct host **list, unsigned int vers, const char *options) | |
258 | remove_host(list, this); | |
259 | add_host(&new, this); | |
260 | } else { | |
261 | - status = get_supported_ver_and_cost(this, selected_version, options); | |
262 | + status = get_supported_ver_and_cost(this, | |
263 | + selected_version, options, | |
264 | + random_selection); | |
265 | if (status) { | |
266 | this->version = selected_version; | |
267 | remove_host(list, this); |