--- autofs-5.0.1/include/replicated.h.random-selection 2007-05-04 13:49:54.000000000 +0800 +++ autofs-5.0.1/include/replicated.h 2007-05-04 13:50:12.000000000 +0800 @@ -60,6 +60,7 @@ struct host *next; }; +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 *); --- autofs-5.0.1/modules/replicated.c.random-selection 2007-05-04 13:49:54.000000000 +0800 +++ autofs-5.0.1/modules/replicated.c 2007-05-04 13:50:12.000000000 +0800 @@ -74,6 +74,29 @@ #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; + unsigned int seed; + + fd = open("/dev/random", O_RDONLY); + if (fd < 0) { + srandom(time(NULL)); + return; + } + + if (read(fd, &seed, sizeof(seed)) != -1) + srandom(seed); + else + srandom(time(NULL)); + + close(fd); + + return; +} + static unsigned int get_proximity(const char *host_addr, int addr_len) { struct sockaddr_in *msk_addr, *if_addr; @@ -403,7 +426,11 @@ status = rpc_ping_proto(rpc_info); gettimeofday(&end, &tz); if (status) { - taken += elapsed(start, end); + if (random_selection) + /* Random value between 0 and 1 */ + taken += ((float) random())/((float) RAND_MAX+1); + else + taken += elapsed(start, end);; count++; supported = NFS4_SUPPORTED; } @@ -440,7 +467,11 @@ status = rpc_ping_proto(rpc_info); gettimeofday(&end, &tz); if (status) { - taken += elapsed(start, end); + if (random_selection) + /* Random value between 0 and 1 */ + taken += ((float) random())/((float) RAND_MAX+1); + else + taken += elapsed(start, end);; count++; supported |= NFS3_SUPPORTED; } @@ -470,7 +501,11 @@ status = rpc_ping_proto(rpc_info); gettimeofday(&end, &tz); if (status) { - taken += elapsed(start, end); + if (random_selection) + /* Random value between 0 and 1 */ + taken += ((float) random())/((float) RAND_MAX+1); + else + taken += elapsed(start, end);; count++; supported |= NFS2_SUPPORTED; } @@ -610,8 +645,13 @@ gettimeofday(&start, &tz); status = rpc_ping_proto(&rpc_info); gettimeofday(&end, &tz); - if (status) - taken = elapsed(start, end); + if (status) { + if (random_selection) + /* Random value between 0 and 1 */ + taken = ((float) random())/((float) RAND_MAX+1); + else + taken = elapsed(start, end); + } } done: if (rpc_info.proto->p_proto == IPPROTO_UDP) { --- autofs-5.0.1/modules/mount_nfs.c.random-selection 2007-05-04 13:49:54.000000000 +0800 +++ autofs-5.0.1/modules/mount_nfs.c 2007-05-04 13:50:12.000000000 +0800 @@ -51,6 +51,8 @@ } else init_ctr++; + seed_random(); + return !mount_bind; } --- autofs-5.0.1/daemon/automount.c.random-selection 2007-05-04 13:49:54.000000000 +0800 +++ autofs-5.0.1/daemon/automount.c 2007-05-04 13:50:12.000000000 +0800 @@ -47,6 +47,8 @@ const char *confdir = AUTOFS_CONF_DIR; /* Location of autofs config file */ 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 int start_pipefd[2]; static int st_stat = 0; static int *pst_stat = &st_stat; @@ -1342,6 +1344,8 @@ " -d --debug log debuging info\n" " -D --define define global macro variable\n" /*" -f --foreground do not fork into background\n" */ + " -r --random-replicated-selection" + " use ramdom replicated server selection\n" " -V --version print version, build config and exit\n" , program); } @@ -1440,6 +1444,7 @@ {"debug", 0, 0, 'd'}, {"define", 1, 0, 'D'}, {"foreground", 0, 0, 'f'}, + {"random-selection", 0, 0, 'r'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; @@ -1454,10 +1459,11 @@ timeout = defaults_get_timeout(); ghost = defaults_get_browse_mode(); logging = defaults_get_logging(); + random_selection = 0; foreground = 0; opterr = 0; - while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fV", long_options, NULL)) != EOF) { + while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVr", long_options, NULL)) != EOF) { switch (opt) { case 'h': usage(); @@ -1491,6 +1497,10 @@ show_build_info(); exit(0); + case 'r': + random_selection = 1; + break; + case '?': case ':': printf("%s: Ambiguous or unknown options\n", program); --- autofs-5.0.1/man/automount.8.in.random-selection 2007-05-04 13:49:54.000000000 +0800 +++ autofs-5.0.1/man/automount.8.in 2007-05-04 13:50:12.000000000 +0800 @@ -49,6 +49,10 @@ are over-ridden macro definitions of the same name specified in mount entries. .TP +.I "\-r, \-\-random-replicated-selection" +Enables the use of ramdom selection when choosing a host from a +list of replicated servers. +.TP .I "\-V, \-\-version" Display the version number, then exit. .SH ARGUMENTS