diff -up autofs-5.0.2/include/replicated.h.random-selection-fix autofs-5.0.2/include/replicated.h --- autofs-5.0.2/include/replicated.h.random-selection-fix 2007-06-18 15:18:08.000000000 +0800 +++ autofs-5.0.2/include/replicated.h 2007-11-20 14:55:28.000000000 +0900 @@ -63,7 +63,7 @@ struct host { void seed_random(void); void free_host_list(struct host **); int parse_location(struct host **, const char *); -int prune_host_list(struct host **, unsigned int, const char *); +int prune_host_list(struct host **, unsigned int, const char *, unsigned int); void dump_host_list(struct host *); #endif diff -up autofs-5.0.2/include/automount.h.random-selection-fix autofs-5.0.2/include/automount.h --- autofs-5.0.2/include/automount.h.random-selection-fix 2007-11-20 14:55:28.000000000 +0900 +++ autofs-5.0.2/include/automount.h 2007-11-20 14:55:28.000000000 +0900 @@ -448,6 +448,8 @@ struct autofs_point { enum states state; /* Current state */ int state_pipe[2]; /* State change router pipe */ unsigned dir_created; /* Directory created for this mount? */ + unsigned random_selection; /* Use random policy when selecting a + * host from which to mount */ struct autofs_point *parent; /* Owner of mounts list for submount */ pthread_mutex_t mounts_mutex; /* Protect mount lists */ pthread_cond_t mounts_cond; /* Submounts condition variable */ diff -up autofs-5.0.2/modules/mount_nfs.c.random-selection-fix autofs-5.0.2/modules/mount_nfs.c --- autofs-5.0.2/modules/mount_nfs.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900 +++ autofs-5.0.2/modules/mount_nfs.c 2007-11-20 14:55:28.000000000 +0900 @@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap, warn(ap->logopt, MODPREFIX "no hosts available"); return 1; } - prune_host_list(&hosts, vers, nfsoptions); + prune_host_list(&hosts, vers, nfsoptions, ap->random_selection); if (!hosts) { warn(ap->logopt, MODPREFIX "no hosts available"); diff -up autofs-5.0.2/modules/replicated.c.random-selection-fix autofs-5.0.2/modules/replicated.c --- autofs-5.0.2/modules/replicated.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900 +++ autofs-5.0.2/modules/replicated.c 2007-11-20 14:55:28.000000000 +0900 @@ -74,8 +74,6 @@ #define max(x, y) (x >= y ? x : y) #define mmax(x, y, z) (max(x, y) == x ? max(x, z) : max(y, z)) -extern unsigned int random_selection; - void seed_random(void) { int fd; @@ -392,7 +390,7 @@ static unsigned short get_port_option(co static unsigned int get_nfs_info(struct host *host, struct conn_info *pm_info, struct conn_info *rpc_info, const char *proto, unsigned int version, - const char *options) + const char *options, unsigned int random_selection) { char *have_port_opt = options ? strstr(options, "port=") : NULL; struct pmap parms; @@ -535,7 +533,9 @@ done_ver: return supported; } -static int get_vers_and_cost(struct host *host, unsigned int version, const char *options) +static int get_vers_and_cost(struct host *host, + unsigned int version, const char *options, + unsigned int random_selection) { struct conn_info pm_info, rpc_info; time_t timeout = RPC_TIMEOUT; @@ -559,7 +559,9 @@ static int get_vers_and_cost(struct host vers &= version; if (version & UDP_REQUESTED) { - supported = get_nfs_info(host, &pm_info, &rpc_info, "udp", vers, options); + supported = get_nfs_info(host, + &pm_info, &rpc_info, "udp", vers, + options, random_selection); if (supported) { ret = 1; host->version |= (supported << 8); @@ -567,7 +569,9 @@ static int get_vers_and_cost(struct host } if (version & TCP_REQUESTED) { - supported = get_nfs_info(host, &pm_info, &rpc_info, "tcp", vers, options); + supported = get_nfs_info(host, + &pm_info, &rpc_info, "tcp", vers, + options, random_selection); if (supported) { ret = 1; host->version |= supported; @@ -577,7 +581,9 @@ static int get_vers_and_cost(struct host return ret; } -static int get_supported_ver_and_cost(struct host *host, unsigned int version, const char *options) +static int get_supported_ver_and_cost(struct host *host, + unsigned int version, const char *options, + unsigned int random_selection) { char *have_port_opt = options ? strstr(options, "port=") : NULL; struct conn_info pm_info, rpc_info; @@ -695,7 +701,9 @@ done: return 0; } -int prune_host_list(struct host **list, unsigned int vers, const char *options) +int prune_host_list(struct host **list, + unsigned int vers, const char *options, + unsigned int random_selection) { struct host *this, *last, *first; struct host *new = NULL; @@ -734,7 +742,8 @@ int prune_host_list(struct host **list, break; if (this->name) { - status = get_vers_and_cost(this, vers, options); + status = get_vers_and_cost(this, vers, + options, random_selection); if (!status) { if (this == first) { first = next; @@ -824,7 +833,9 @@ int prune_host_list(struct host **list, remove_host(list, this); add_host(&new, this); } else { - status = get_supported_ver_and_cost(this, selected_version, options); + status = get_supported_ver_and_cost(this, + selected_version, options, + random_selection); if (status) { this->version = selected_version; remove_host(list, this); diff -up autofs-5.0.2/daemon/automount.c.random-selection-fix autofs-5.0.2/daemon/automount.c --- autofs-5.0.2/daemon/automount.c.random-selection-fix 2007-11-20 14:55:28.000000000 +0900 +++ autofs-5.0.2/daemon/automount.c 2007-11-20 14:55:28.000000000 +0900 @@ -52,9 +52,9 @@ const char *confdir = AUTOFS_CONF_DIR; / const char *global_options; /* Global option, from command line */ -static char *pid_file = NULL; /* File in which to keep pid */ -unsigned int random_selection; /* use random policy when selecting - * which multi-mount host to mount */ +static char *pid_file = NULL; /* File in which to keep pid */ +unsigned int global_random_selection; /* use random policy when selecting + * which multi-mount host to mount */ static int start_pipefd[2]; static int st_stat = 0; static int *pst_stat = &st_stat; @@ -1469,7 +1469,7 @@ int main(int argc, char *argv[]) timeout = defaults_get_timeout(); ghost = defaults_get_browse_mode(); logging = defaults_get_logging(); - random_selection = 0; + global_random_selection = 0; global_options = NULL; have_global_options = 0; foreground = 0; @@ -1510,7 +1510,7 @@ int main(int argc, char *argv[]) exit(0); case 'r': - random_selection = 1; + global_random_selection = 1; break; case 'O': diff -up autofs-5.0.2/lib/master_tok.l.random-selection-fix autofs-5.0.2/lib/master_tok.l --- autofs-5.0.2/lib/master_tok.l.random-selection-fix 2007-11-20 14:55:28.000000000 +0900 +++ autofs-5.0.2/lib/master_tok.l 2007-11-20 14:55:28.000000000 +0900 @@ -324,6 +324,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|-- -g|--ghost|-?browse { return(OPT_GHOST); } -v|--verbose { return(OPT_VERBOSE); } -d|--debug { return(OPT_DEBUG); } + -r|--random-multimount-selection { return(OPT_RANDOM); } {OPTWS}","{OPTWS} { return(COMMA); } diff -up autofs-5.0.2/lib/master_parse.y.random-selection-fix autofs-5.0.2/lib/master_parse.y --- autofs-5.0.2/lib/master_parse.y.random-selection-fix 2007-11-20 14:55:28.000000000 +0900 +++ autofs-5.0.2/lib/master_parse.y 2007-11-20 14:55:28.000000000 +0900 @@ -56,6 +56,8 @@ static char *type; static char *format; static long timeout; static unsigned ghost; +extern unsigned global_random_selection; +static unsigned random_selection; static char **tmp_argv; static int tmp_argc; static char **local_argv; @@ -93,7 +95,7 @@ static int master_fprintf(FILE *, char * %token COMMENT %token MAP -%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG +%token OPT_TIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE OPT_DEBUG OPT_RANDOM %token COLON COMMA NL DDASH %type map %type options @@ -174,6 +176,7 @@ line: | PATH COLON { master_notify($1); YYABORT; } | PATH OPTION { master_notify($2); YYABORT; } | PATH NILL { master_notify($2); YYABORT; } + | PATH OPT_RANDOM { master_notify($1); YYABORT; } | PATH OPT_DEBUG { master_notify($1); YYABORT; } | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } | PATH OPT_GHOST { master_notify($1); YYABORT; } @@ -543,6 +546,7 @@ daemon_option: OPT_TIMEOUT NUMBER { time | OPT_GHOST { ghost = 1; } | OPT_VERBOSE { verbose = 1; } | OPT_DEBUG { debug = 1; } + | OPT_RANDOM { random_selection = 1; } ; mount_option: OPTION @@ -600,6 +604,7 @@ static void local_init_vars(void) debug = 0; timeout = -1; ghost = defaults_get_browse_mode(); + random_selection = global_random_selection; tmp_argv = NULL; tmp_argc = 0; local_argv = NULL; @@ -790,6 +795,7 @@ int master_parse_entry(const char *buffe } set_mnt_logging(ap); } + entry->ap->random_selection = random_selection; /* source = master_find_map_source(entry, type, format, diff -up autofs-5.0.2/man/auto.master.5.in.random-selection-fix autofs-5.0.2/man/auto.master.5.in --- autofs-5.0.2/man/auto.master.5.in.random-selection-fix 2007-11-20 14:55:28.000000000 +0900 +++ autofs-5.0.2/man/auto.master.5.in 2007-11-20 14:55:28.000000000 +0900 @@ -146,6 +146,12 @@ to prevent symlinking of local NFS mount prevent bind mounting of local NFS filesystems as well. If you need to prevent bind mounting for only specific entrys in a map then this can be done by adding the "port=" mount option to the given entries. +.TP +.I "\-r, \-\-random-multimount-selection" +Enables the use of ramdom selection when choosing a host from a +list of replicated servers. This option is applied to this mount +only, overriding the global setting that may be specified on the +command line. .SH GENERAL SYSTEM DEFAULTS CONFIGURATION .P The default value of several general settings may be changed in the