1
autofs-5.0.5 - use weight only for server selection
3
From: Ian Kent <raven@themaw.net>
5
When using weighted server names in map entries the server response
6
time is also taken into consideration when selecting a server for
7
the target of the mount. In some cases people need to be able to
8
rely on selection strictly by weight. We add pseudo option
9
"--use-weight-only" that can be used in with master map entries
10
or with individual map entries to provide for this. For individual
11
map entries the option "no-use-weight-only" can also be used to
12
override the master map option.
16
daemon/automount.c | 8 +++--
17
include/automount.h | 3 ++
18
include/replicated.h | 3 +-
19
lib/master_parse.y | 12 ++++++--
20
lib/master_tok.l | 1 +
21
man/auto.master.5.in | 6 ++++
22
man/autofs.5 | 7 +++++
23
modules/mount_nfs.c | 15 +++++++---
24
modules/parse_sun.c | 36 +++++++++++++++++++++---
25
modules/replicated.c | 76 ++++++++++++++++++++++++++++++--------------------
26
11 files changed, 120 insertions(+), 48 deletions(-)
29
diff --git a/CHANGELOG b/CHANGELOG
30
index 11054da..c98204d 100644
34
- add external bind method.
35
- fix add simple bind auth.
36
- add option to dump configured automount maps.
37
+- use weight only for server selection.
39
03/09/2009 autofs-5.0.5
40
-----------------------
41
diff --git a/daemon/automount.c b/daemon/automount.c
42
index 1b1007d..6b4e0d0 100644
43
--- a/daemon/automount.c
44
+++ b/daemon/automount.c
45
@@ -57,8 +57,8 @@ const char *fifodir = AUTOFS_FIFO_DIR "/autofs.fifo";
46
const char *global_options; /* Global option, from command line */
48
static char *pid_file = NULL; /* File in which to keep pid */
49
-unsigned int global_random_selection; /* use random policy when selecting
50
- * which multi-mount host to mount */
51
+unsigned int global_selection_options;
53
long global_negative_timeout = -1;
54
int do_force_unlink = 0; /* Forceably unlink mount tree at startup */
56
@@ -1855,7 +1855,7 @@ int main(int argc, char *argv[])
57
timeout = defaults_get_timeout();
58
ghost = defaults_get_browse_mode();
59
logging = defaults_get_logging();
60
- global_random_selection = 0;
61
+ global_selection_options = 0;
62
global_options = NULL;
63
have_global_options = 0;
65
@@ -1898,7 +1898,7 @@ int main(int argc, char *argv[])
69
- global_random_selection = 1;
70
+ global_selection_options |= MOUNT_FLAG_RANDOM_SELECT;
74
diff --git a/include/automount.h b/include/automount.h
75
index 7d4efcc..5002747 100644
76
--- a/include/automount.h
77
+++ b/include/automount.h
78
@@ -443,6 +443,9 @@ struct kernel_mod_version {
79
/* Mount being re-mounted */
80
#define MOUNT_FLAG_REMOUNT 0x0008
82
+/* Use server weight only for selection */
83
+#define MOUNT_FLAG_USE_WEIGHT_ONLY 0x0010
87
char *path; /* Mount point name */
88
diff --git a/include/replicated.h b/include/replicated.h
89
index 519689d..6eb56e0 100644
90
--- a/include/replicated.h
91
+++ b/include/replicated.h
92
@@ -56,6 +56,7 @@ struct host {
96
+ unsigned int options;
97
unsigned int proximity;
100
@@ -65,7 +66,7 @@ struct host {
101
void seed_random(void);
102
void free_host_list(struct host **);
103
int parse_location(unsigned, struct host **, const char *, unsigned int);
104
-int prune_host_list(unsigned, struct host **, unsigned int, const char *, unsigned int);
105
+int prune_host_list(unsigned, struct host **, unsigned int, const char *);
106
void dump_host_list(struct host *);
109
diff --git a/lib/master_parse.y b/lib/master_parse.y
110
index b82129f..845cbed 100644
111
--- a/lib/master_parse.y
112
+++ b/lib/master_parse.y
113
@@ -58,8 +58,9 @@ static char *format;
115
static long negative_timeout;
116
static unsigned ghost;
117
-extern unsigned global_random_selection;
118
+extern unsigned global_selection_options;
119
static unsigned random_selection;
120
+static unsigned use_weight;
121
static char **tmp_argv;
123
static char **local_argv;
124
@@ -98,7 +99,7 @@ static int master_fprintf(FILE *, char *, ...);
127
%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE
128
-%token OPT_DEBUG OPT_RANDOM
129
+%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT
130
%token COLON COMMA NL DDASH
132
%type <strtype> options
133
@@ -181,6 +182,7 @@ line:
134
| PATH OPTION { master_notify($2); YYABORT; }
135
| PATH NILL { master_notify($2); YYABORT; }
136
| PATH OPT_RANDOM { master_notify($1); YYABORT; }
137
+ | PATH OPT_USE_WEIGHT { master_notify($1); YYABORT; }
138
| PATH OPT_DEBUG { master_notify($1); YYABORT; }
139
| PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
140
| PATH OPT_GHOST { master_notify($1); YYABORT; }
141
@@ -558,6 +560,7 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
142
| OPT_VERBOSE { verbose = 1; }
143
| OPT_DEBUG { debug = 1; }
144
| OPT_RANDOM { random_selection = 1; }
145
+ | OPT_USE_WEIGHT { use_weight = 1; }
149
@@ -622,7 +625,8 @@ static void local_init_vars(void)
151
negative_timeout = 0;
152
ghost = defaults_get_browse_mode();
153
- random_selection = global_random_selection;
154
+ random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT;
159
@@ -808,6 +812,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
161
if (random_selection)
162
entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
164
+ entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY;
165
if (negative_timeout)
166
entry->ap->negative_timeout = negative_timeout;
168
diff --git a/lib/master_tok.l b/lib/master_tok.l
169
index d05d1fb..c7fbe37 100644
170
--- a/lib/master_tok.l
171
+++ b/lib/master_tok.l
172
@@ -363,6 +363,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo
173
-g|--ghost|-?browse { return(OPT_GHOST); }
174
-v|--verbose { return(OPT_VERBOSE); }
175
-d|--debug { return(OPT_DEBUG); }
176
+ -w|--use-weight-only { return(OPT_USE_WEIGHT); }
177
-r|--random-multimount-selection { return(OPT_RANDOM); }
179
{OPTWS}","{OPTWS} { return(COMMA); }
180
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
181
index 453ff98..380b706 100644
182
--- a/man/auto.master.5.in
183
+++ b/man/auto.master.5.in
184
@@ -153,6 +153,12 @@ list of replicated servers. This option is applied to this mount
185
only, overriding the global setting that may be specified on the
188
+.I "\-w, \-\-use-weight-only"
189
+Use only specified weights for server selection where more than one
190
+server is specified in the map entry. If no server weights are given
191
+then each available server will be tried in the order listed, within
194
.I "\-n, \-\-negative\-timeout <seconds>"
195
Set the timeout for caching failed key lookups. This option can be
196
used to override the global default given either on the command line
197
diff --git a/man/autofs.5 b/man/autofs.5
198
index c5614e1..2161116 100644
201
@@ -49,6 +49,13 @@ is used to treat errors when mounting file systems as fatal. This is important w
202
multiple file systems should be mounted (`multi-mounts'). If this option
203
is given, no file system is mounted at all if at least one file system
206
+is used to make the weight the sole factor in selecting a server when multiple
207
+servers are present in a map entry.
209
+.I -no-use-weight-only
210
+can be used to negate the option if it is present in the master map entry
211
+for the map but is not wanted for the given mount.
214
The location specifies from where the file system is to be mounted. In the
215
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
216
index 9110eba..817b9c6 100644
217
--- a/modules/mount_nfs.c
218
+++ b/modules/mount_nfs.c
219
@@ -63,7 +63,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
220
struct host *this, *hosts = NULL;
221
unsigned int mount_default_proto, vers;
222
char *nfsoptions = NULL;
223
- unsigned int random_selection = ap->flags & MOUNT_FLAG_RANDOM_SELECT;
224
+ unsigned int flags = ap->flags &
225
+ (MOUNT_FLAG_RANDOM_SELECT | MOUNT_FLAG_USE_WEIGHT_ONLY);
226
int len, status, err, existed = 1;
228
int ro = 0; /* Set if mount bind should be read-only */
229
@@ -112,9 +113,13 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
230
while (*comma == ' ' || *comma == '\t')
233
- if (strncmp("nosymlink", cp, end - cp + 1) == 0)
234
+ if (strncmp("nosymlink", cp, end - cp + 1) == 0) {
237
+ } else if (strncmp("no-use-weight-only", cp, end - cp + 1) == 0) {
238
+ flags &= ~MOUNT_FLAG_USE_WEIGHT_ONLY;
239
+ } else if (strncmp("use-weight-only", cp, end - cp + 1) == 0) {
240
+ flags |= MOUNT_FLAG_USE_WEIGHT_ONLY;
242
/* Check for options that also make sense
244
if (strncmp("ro", cp, end - cp + 1) == 0)
245
@@ -137,11 +142,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
246
else if (mount_default_proto == 4)
247
vers = vers | NFS4_VERS_MASK;
249
- if (!parse_location(ap->logopt, &hosts, what, random_selection)) {
250
+ if (!parse_location(ap->logopt, &hosts, what, flags)) {
251
info(ap->logopt, MODPREFIX "no hosts available");
254
- prune_host_list(ap->logopt, &hosts, vers, nfsoptions, random_selection);
255
+ prune_host_list(ap->logopt, &hosts, vers, nfsoptions);
258
info(ap->logopt, MODPREFIX "no hosts available");
259
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
260
index 1f91ad1..4bddcc9 100644
261
--- a/modules/parse_sun.c
262
+++ b/modules/parse_sun.c
263
@@ -529,6 +529,7 @@ static int sun_mount(struct autofs_point *ap, const char *root,
265
char *fstype = "nfs"; /* Default filesystem type */
267
+ int use_weight_only = ap->flags & MOUNT_FLAG_USE_WEIGHT_ONLY;
271
@@ -575,6 +576,10 @@ static int sun_mount(struct autofs_point *ap, const char *root,
272
memcpy(np, cp, comma - cp + 1);
273
np += comma - cp + 1;
275
+ } else if (strncmp("no-use-weight-only", cp, 18) == 0) {
276
+ use_weight_only = -1;
277
+ } else if (strncmp("use-weight-only", cp, 15) == 0) {
278
+ use_weight_only = MOUNT_FLAG_USE_WEIGHT_ONLY;
279
} else if (strncmp("bg", cp, 2) == 0 ||
280
strncmp("nofg", cp, 4) == 0) {
282
@@ -593,11 +598,10 @@ static int sun_mount(struct autofs_point *ap, const char *root,
287
if (!strcmp(fstype, "autofs") && ctxt->macros) {
288
char *noptions = NULL;
291
+ if (!options || *options == '\0') {
292
noptions = alloca(strlen(ctxt->macros) + 1);
295
@@ -610,7 +614,7 @@ static int sun_mount(struct autofs_point *ap, const char *root,
300
+ if (noptions && *noptions != '\0') {
301
strcat(noptions, ctxt->macros);
304
@@ -624,7 +628,7 @@ static int sun_mount(struct autofs_point *ap, const char *root,
306
type = ap->entry->maps->type;
307
if (type && !strcmp(type, "hosts")) {
309
+ if (options && *options != '\0') {
310
int len = strlen(options);
311
int suid = strstr(options, "suid") ? 0 : 7;
312
int dev = strstr(options, "dev") ? 0 : 6;
313
@@ -669,6 +673,30 @@ static int sun_mount(struct autofs_point *ap, const char *root,
314
memcpy(what, loc, loclen);
317
+ /* Add back "[no-]use-weight-only" for NFS mounts only */
318
+ if (use_weight_only) {
322
+ if (options && *options != '\0') {
323
+ len = strlen(options) + 19;
325
+ strcpy(tmp, options);
327
+ if (use_weight_only == MOUNT_FLAG_USE_WEIGHT_ONLY)
328
+ strcat(tmp, "use-weight-only");
330
+ strcat(tmp, "no-use-weight-only");
333
+ if (use_weight_only == MOUNT_FLAG_USE_WEIGHT_ONLY)
334
+ strcpy(tmp, "use-weight-only");
336
+ strcpy(tmp, "no-use-weight-only");
341
debug(ap->logopt, MODPREFIX
342
"mounting root %s, mountpoint %s, "
343
"what %s, fstype %s, options %s",
344
diff --git a/modules/replicated.c b/modules/replicated.c
345
index 9eefb19..975c254 100644
346
--- a/modules/replicated.c
347
+++ b/modules/replicated.c
348
@@ -351,7 +351,8 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
350
static struct host *new_host(const char *name,
351
struct sockaddr *addr, size_t addr_len,
352
- unsigned int proximity, unsigned int weight)
353
+ unsigned int proximity, unsigned int weight,
354
+ unsigned int options)
357
struct sockaddr *tmp2;
358
@@ -385,6 +386,7 @@ static struct host *new_host(const char *name,
360
new->proximity = proximity;
361
new->weight = weight;
362
+ new->options = options;
366
@@ -519,9 +521,11 @@ static unsigned short get_port_option(const char *options)
367
static unsigned int get_nfs_info(unsigned logopt, struct host *host,
368
struct conn_info *pm_info, struct conn_info *rpc_info,
369
const char *proto, unsigned int version,
370
- const char *options, unsigned int random_selection)
371
+ const char *options)
373
char *have_port_opt = options ? strstr(options, "port=") : NULL;
374
+ unsigned int random_selection = host->options & MOUNT_FLAG_RANDOM_SELECT;
375
+ unsigned int use_weight_only = host->options & MOUNT_FLAG_USE_WEIGHT_ONLY;
377
struct timeval start, end;
379
@@ -675,7 +679,10 @@ done_ver:
380
* Average response time to 7 significant places as
383
- host->cost = (unsigned long) ((taken * 1000000) / count);
384
+ if (use_weight_only)
387
+ host->cost = (unsigned long) ((taken * 1000000) / count);
389
/* Allow for user bias */
391
@@ -689,8 +696,7 @@ done_ver:
394
static int get_vers_and_cost(unsigned logopt, struct host *host,
395
- unsigned int version, const char *options,
396
- unsigned int random_selection)
397
+ unsigned int version, const char *options)
399
struct conn_info pm_info, rpc_info;
400
time_t timeout = RPC_TIMEOUT;
401
@@ -717,8 +723,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
403
if (version & UDP_REQUESTED) {
404
supported = get_nfs_info(logopt, host,
405
- &pm_info, &rpc_info, "udp", vers,
406
- options, random_selection);
407
+ &pm_info, &rpc_info, "udp", vers, options);
410
host->version |= (supported << 8);
411
@@ -727,8 +732,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
413
if (version & TCP_REQUESTED) {
414
supported = get_nfs_info(logopt, host,
415
- &pm_info, &rpc_info, "tcp", vers,
416
- options, random_selection);
417
+ &pm_info, &rpc_info, "tcp", vers, options);
420
host->version |= supported;
421
@@ -739,10 +743,11 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
424
static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
425
- unsigned int version, const char *options,
426
- unsigned int random_selection)
427
+ unsigned int version, const char *options)
429
char *have_port_opt = options ? strstr(options, "port=") : NULL;
430
+ unsigned int random_selection = host->options & MOUNT_FLAG_RANDOM_SELECT;
431
+ unsigned int use_weight_only = host->options & MOUNT_FLAG_USE_WEIGHT_ONLY;
432
struct conn_info pm_info, rpc_info;
435
@@ -855,7 +860,10 @@ done:
438
/* Response time to 7 significant places as integral type. */
439
- host->cost = (unsigned long) (taken * 1000000);
440
+ if (use_weight_only)
443
+ host->cost = (unsigned long) (taken * 1000000);
445
/* Allow for user bias */
447
@@ -870,8 +878,7 @@ done:
450
int prune_host_list(unsigned logopt, struct host **list,
451
- unsigned int vers, const char *options,
452
- unsigned int random_selection)
453
+ unsigned int vers, const char *options)
455
struct host *this, *last, *first;
456
struct host *new = NULL;
457
@@ -892,6 +899,7 @@ int prune_host_list(unsigned logopt, struct host **list,
459
while (this && this->proximity == PROXIMITY_LOCAL)
464
* Check for either a list containing only proximity local hosts
465
@@ -903,8 +911,6 @@ int prune_host_list(unsigned logopt, struct host **list,
468
proximity = this->proximity;
472
struct host *next = this->next;
474
@@ -912,8 +918,7 @@ int prune_host_list(unsigned logopt, struct host **list,
478
- status = get_vers_and_cost(logopt, this, vers,
479
- options, random_selection);
480
+ status = get_vers_and_cost(logopt, this, vers, options);
484
@@ -1022,8 +1027,7 @@ int prune_host_list(unsigned logopt, struct host **list,
485
add_host(&new, this);
487
status = get_supported_ver_and_cost(logopt, this,
488
- selected_version, options,
490
+ selected_version, options);
492
this->version = selected_version;
493
remove_host(list, this);
494
@@ -1041,8 +1045,7 @@ int prune_host_list(unsigned logopt, struct host **list,
496
static int add_new_host(struct host **list,
497
const char *host, unsigned int weight,
498
- struct addrinfo *host_addr,
499
- unsigned int random_selection)
500
+ struct addrinfo *host_addr, unsigned int options)
504
@@ -1054,10 +1057,21 @@ static int add_new_host(struct host **list,
505
* We can't use PROXIMITY_LOCAL or we won't perform an RPC ping
506
* to remove hosts that may be down.
508
- if (random_selection)
509
+ if (options & MOUNT_FLAG_RANDOM_SELECT)
510
prx = PROXIMITY_SUBNET;
513
prx = get_proximity(host_addr->ai_addr);
515
+ * If we want the weight to be the determining factor
516
+ * when selecting a host then all hosts must have the
517
+ * same proximity. However, if this is the local machine
518
+ * it should always be used since it is certainly available.
520
+ if (prx != PROXIMITY_LOCAL &&
521
+ (options & MOUNT_FLAG_USE_WEIGHT_ONLY))
522
+ prx = PROXIMITY_SUBNET;
526
* If we tried to add an IPv6 address and we don't have IPv6
527
* support return success in the hope of getting an IPv4
528
@@ -1069,7 +1083,7 @@ static int add_new_host(struct host **list,
531
addr_len = sizeof(struct sockaddr);
532
- new = new_host(host, host_addr->ai_addr, addr_len, prx, weight);
533
+ new = new_host(host, host_addr->ai_addr, addr_len, prx, weight, options);
537
@@ -1082,7 +1096,7 @@ static int add_new_host(struct host **list,
540
static int add_host_addrs(struct host **list, const char *host,
541
- unsigned int weight, unsigned int random_selection)
542
+ unsigned int weight, unsigned int options)
544
struct addrinfo hints, *ni, *this;
546
@@ -1098,7 +1112,7 @@ static int add_host_addrs(struct host **list, const char *host,
550
- ret = add_new_host(list, host, weight, this, random_selection);
551
+ ret = add_new_host(list, host, weight, this, options);
554
this = this->ai_next;
555
@@ -1121,7 +1135,7 @@ try_name:
559
- ret = add_new_host(list, host, weight, this, random_selection);
560
+ ret = add_new_host(list, host, weight, this, options);
563
this = this->ai_next;
564
@@ -1209,7 +1223,7 @@ static char *seek_delim(const char *s)
567
int parse_location(unsigned logopt, struct host **hosts,
568
- const char *list, unsigned int random_selection)
569
+ const char *list, unsigned int options)
571
char *str, *p, *delim;
572
unsigned int empty = 1;
573
@@ -1264,7 +1278,7 @@ int parse_location(unsigned logopt, struct host **hosts,
577
- if (!add_host_addrs(hosts, p, weight, random_selection)) {
578
+ if (!add_host_addrs(hosts, p, weight, options)) {
582
@@ -1286,7 +1300,7 @@ int parse_location(unsigned logopt, struct host **hosts,
586
- if (!add_host_addrs(hosts, p, weight, random_selection)) {
587
+ if (!add_host_addrs(hosts, p, weight, options)) {