[autofs] * Thu Mar 03 2011 Ian Kent <ikent at redhat.com> - 1:5.0.5-36 - use weight only for server selection. -

Ian Kent iankent at fedoraproject.org
Thu Mar 3 02:59:43 UTC 2011


commit e767d529b84002887fefc786e402f2912c9214fa
Author: Ian Kent <raven at themaw.net>
Date:   Thu Mar 3 10:58:56 2011 +0800

    * Thu Mar 03 2011 Ian Kent <ikent at redhat.com> - 1:5.0.5-36
    - use weight only for server selection.
    - fix isspace() wild card substition.
    - auto adjust ldap page size.
    - fix prune cache valid check.
    - fix mountd vers retry.
    - fix expire race.
    - add lsb force-reload and try-restart.

 ....0.5-add-lsb-force-reload-and-try-restart.patch |   50 ++
 autofs-5.0.5-auto-adjust-ldap-page-size.patch      |  113 ++++
 autofs-5.0.5-fix-expire-race.patch                 |   40 ++
 ...fs-5.0.5-fix-isspace-wild-card-substition.patch |   78 +++
 autofs-5.0.5-fix-mountd-vers-retry.patch           |   81 +++
 autofs-5.0.5-fix-prune-cache-valid-check.patch     |   42 ++
 ....0.5-use-weight-only-for-server-selection.patch |  568 ++++++++++++++++++++
 autofs.spec                                        |   25 +-
 8 files changed, 996 insertions(+), 1 deletions(-)
---
diff --git a/autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch b/autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch
new file mode 100644
index 0000000..f5015f9
--- /dev/null
+++ b/autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch
@@ -0,0 +1,50 @@
+autofs-5.0.5 - add lsb force-reload and try-restart
+
+From: Ian Kent <raven at themaw.net>
+
+LSB specifies two additional init script options, force-reload and
+try-restart. The force-reload option is supposed to do what restart
+does and does that. The try-restart option is essentially condrestart
+and is another option for that action. This change is made only to
+RedHat init script.
+---
+
+ redhat/autofs.init.in |   10 +++-------
+ 1 files changed, 3 insertions(+), 7 deletions(-)
+
+
+diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in
+index 05ab145..4a915ec 100644
+--- a/redhat/autofs.init.in
++++ b/redhat/autofs.init.in
+@@ -173,7 +173,7 @@ case "$1" in
+ 	status)
+ 		status -p /var/run/autofs.pid -l autofs $prog
+ 		;;
+-	restart)
++	restart|force-reload)
+ 		restart
+ 		;;
+ 	forcerestart)
+@@ -183,19 +183,15 @@ case "$1" in
+ 	reload)
+ 		reload
+ 		;;
+-	condrestart)
++	condrestart|try-restart)
+ 		if [ -f /var/lock/subsys/autofs ]; then
+ 			restart
+ 		fi
+ 		;;
+ 	usage)
+-		echo $"Usage: $0 {start|forcestart|stop|status|restart|forcerestart|reload|condrestart}"
++		echo $"Usage: $0 {start|forcestart|stop|status|restart|force-reload|forcerestart|reload|condrestart|try-restart}"
+ 		exit 0
+ 		;;
+-	try-restart|force-reload)
+-		echo "$1 service action not supported"
+-		exit 3
+-		;;
+ 	*)
+ 		echo "unknown, invalid or excess argument(s)"
+ 		exit 2
diff --git a/autofs-5.0.5-auto-adjust-ldap-page-size.patch b/autofs-5.0.5-auto-adjust-ldap-page-size.patch
new file mode 100644
index 0000000..fd4ee9b
--- /dev/null
+++ b/autofs-5.0.5-auto-adjust-ldap-page-size.patch
@@ -0,0 +1,113 @@
+autofs-5.0.5 - auto adjust ldap page size
+
+From: Ian Kent <raven at themaw.net>
+
+When doing a paged LDAP request, if an LDAP server is configured with
+request size limits less than the size autofs requests the query fails
+with an LDAP_ADMINLIMIT_EXCEEDED. To fix this, when the error is returned
+halve the request size and try again until we get down to a ridiculously
+small size.
+---
+
+ CHANGELOG             |    1 +
+ modules/lookup_ldap.c |   32 ++++++++++++++++++++++++--------
+ 2 files changed, 25 insertions(+), 8 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -56,6 +56,7 @@
+ - add option to dump configured automount maps.
+ - use weight only for server selection.
+ - fix isspace() wild card substition.
++- auto adjust ldap page size.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/modules/lookup_ldap.c
++++ autofs-5.0.5/modules/lookup_ldap.c
+@@ -55,6 +55,7 @@ struct ldap_search_params {
+ 	LDAP *ldap;
+ 	char *query, **attrs;
+ 	struct berval *cookie;
++	ber_int_t pageSize;
+ 	int morePages;
+ 	ber_int_t totalCount;
+ 	LDAPMessage *result;
+@@ -1946,7 +1947,6 @@ static int do_paged_query(struct ldap_se
+ 	struct autofs_point *ap = sp->ap;
+ 	LDAPControl *pageControl=NULL, *controls[2] = { NULL, NULL };
+ 	LDAPControl **returnedControls = NULL;
+-	static ber_int_t pageSize = 1000;
+ 	static char pagingCriticality = 'T';
+ 	int rv, scope = LDAP_SCOPE_SUBTREE;
+ 
+@@ -1959,7 +1959,8 @@ static int do_paged_query(struct ldap_se
+  		 * Check for Size Limit exceeded and force run through loop
+ 		 * and requery using page control.
+  		 */
+-		if (rv == LDAP_SIZELIMIT_EXCEEDED)
++		if (rv == LDAP_SIZELIMIT_EXCEEDED ||
++		    rv == LDAP_ADMINLIMIT_EXCEEDED)
+ 			sp->morePages = TRUE;
+ 		else {
+ 			debug(ap->logopt,
+@@ -1974,7 +1975,7 @@ do_paged:
+ 	/* we need to use page controls so requery LDAP */
+ 	debug(ap->logopt, MODPREFIX "geting page of results");
+ 
+-	rv = ldap_create_page_control(sp->ldap, pageSize, sp->cookie,
++	rv = ldap_create_page_control(sp->ldap, sp->pageSize, sp->cookie,
+ 				      pagingCriticality, &pageControl);
+ 	if (rv != LDAP_SUCCESS) {
+ 		warn(ap->logopt, MODPREFIX "failed to create page control");
+@@ -1989,10 +1990,11 @@ do_paged:
+ 			       ctxt->qdn, scope, sp->query, sp->attrs,
+ 			       0, controls, NULL, NULL, 0, &sp->result);
+ 	if ((rv != LDAP_SUCCESS) && (rv != LDAP_PARTIAL_RESULTS)) {
+-		debug(ap->logopt,
+-		      MODPREFIX "query failed for %s: %s",
+-		      sp->query, ldap_err2string(rv));
+ 		ldap_control_free(pageControl);
++		if (rv != LDAP_ADMINLIMIT_EXCEEDED)
++			debug(ap->logopt,
++			      MODPREFIX "query failed for %s: %s",
++			      sp->query, ldap_err2string(rv));
+ 		return rv;
+ 	}
+ 
+@@ -2347,18 +2349,32 @@ static int read_one_map(struct autofs_po
+ 	      MODPREFIX "searching for \"%s\" under \"%s\"", sp.query, ctxt->qdn);
+ 
+ 	sp.cookie = NULL;
++	sp.pageSize = 1000;
+ 	sp.morePages = FALSE;
+ 	sp.totalCount = 0;
+ 	sp.result = NULL;
+ 
+ 	do {
+ 		rv = do_paged_query(&sp, ctxt);
+-		if (rv == LDAP_SIZELIMIT_EXCEEDED)
+-		{
++		if (rv == LDAP_SIZELIMIT_EXCEEDED) {
+ 			debug(ap->logopt, MODPREFIX "result size exceed");
+ 			if (sp.result)
+ 				ldap_msgfree(sp.result);
++			continue;
++		}
+ 
++		if (rv == LDAP_ADMINLIMIT_EXCEEDED) {
++			if (sp.result)
++				ldap_msgfree(sp.result);
++			sp.pageSize = sp.pageSize / 2;
++			if (sp.pageSize < 5) {
++				debug(ap->logopt, MODPREFIX
++				      "administrative result size too small");
++				unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
++				*result_ldap = rv;
++				free(sp.query);
++				return NSS_STATUS_UNAVAIL;
++			}
+ 			continue;
+ 		}
+ 
diff --git a/autofs-5.0.5-fix-expire-race.patch b/autofs-5.0.5-fix-expire-race.patch
new file mode 100644
index 0000000..a6d9f75
--- /dev/null
+++ b/autofs-5.0.5-fix-expire-race.patch
@@ -0,0 +1,40 @@
+autofs-5.0.3 - fix expire race
+
+From: Ian Kent <raven at themaw.net>
+
+For multi-mounts, if a mount request comes in and does not complete
+before a concurrent expire autofs will not recognize that the tree
+has become busy which can lead to a partial expire leaving the
+multi-mount non-functional.
+---
+
+ CHANGELOG    |    1 +
+ lib/mounts.c |    5 ++++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -59,6 +59,7 @@
+ - auto adjust ldap page size.
+ - fix prune cache valid check.
+ - fix mountd vers retry.
++- fix expire race.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/lib/mounts.c
++++ autofs-5.0.5/lib/mounts.c
+@@ -1525,8 +1525,11 @@ int umount_multi_triggers(struct autofs_
+ 		oe_base = oe->key + strlen(root);
+ 		left += umount_multi_triggers(ap, oe, root, oe_base);
+ 
+-		if (oe->ioctlfd != -1)
++		if (oe->ioctlfd != -1 ||
++		    is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
+ 			left++;
++			break;
++		}
+ 	}
+ 
+ 	if (left)
diff --git a/autofs-5.0.5-fix-isspace-wild-card-substition.patch b/autofs-5.0.5-fix-isspace-wild-card-substition.patch
new file mode 100644
index 0000000..ead44ff
--- /dev/null
+++ b/autofs-5.0.5-fix-isspace-wild-card-substition.patch
@@ -0,0 +1,78 @@
+autofs-5.0.5 - fix isspace() wild card substition
+
+From: Ian Kent <raven at themaw.net>
+
+If there are characters that match isspace() (such as \t, \n, etc.) in a
+passed map entry key and there is no space in the key these characters
+won't be properly preserved, leading to failed or incorrect mounts.
+
+This is caused by an incorrect attempt at optimization, using a check
+to see if a space is present in the passed key and only then processing
+each character of the key individually, escaping any isspace() characters.
+---
+
+ CHANGELOG           |    1 +
+ modules/parse_sun.c |   40 +++++++++++++++++-----------------------
+ 2 files changed, 18 insertions(+), 23 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -55,6 +55,7 @@
+ - fix add simple bind auth.
+ - add option to dump configured automount maps.
+ - use weight only for server selection.
++- fix isspace() wild card substition.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/modules/parse_sun.c
++++ autofs-5.0.5/modules/parse_sun.c
+@@ -161,30 +161,24 @@ int expandsunent(const char *src, char *
+ 		case '&':
+ 			l = strlen(key);
+ 			/*
+-			 * In order to ensure that any spaces in the key
+-			 * re preserved, we need to escape them here.
++			 * In order to ensure that any isspace() characters
++			 * in the key are preserved, we need to escape them
++			 * here.
+ 			 */
+-			if (strchr(key, ' ')) {
+-				const char *keyp = key;
+-				while (*keyp) {
+-					if (isspace(*keyp)) {
+-						if (dst) {
+-							*dst++ = '\\';
+-							*dst++ = *keyp++;
+-						} else
+-							keyp++;
+-						l++;
+-					} else {
+-						if (dst)
+-							*dst++ = *keyp++;
+-						else
+-							keyp++;
+-					}
+-				}
+-			} else {
+-				if (dst) {
+-					strcpy(dst, key);
+-					dst += l;
++			const char *keyp = key;
++			while (*keyp) {
++				if (isspace(*keyp)) {
++					if (dst) {
++						*dst++ = '\\';
++						*dst++ = *keyp++;
++					} else
++						keyp++;
++					l++;
++				} else {
++					if (dst)
++						*dst++ = *keyp++;
++					else
++						keyp++;
+ 				}
+ 			}
+ 			len += l;
diff --git a/autofs-5.0.5-fix-mountd-vers-retry.patch b/autofs-5.0.5-fix-mountd-vers-retry.patch
new file mode 100644
index 0000000..7e4bf3a
--- /dev/null
+++ b/autofs-5.0.5-fix-mountd-vers-retry.patch
@@ -0,0 +1,81 @@
+autofs-5.0.5 - fix mountd vers retry
+
+From: Ian Kent <raven at themaw.net>
+
+The autofs RPC function used to get the exports list from a host to
+be used by the hosts internal map did not try all potentially available
+mountd versions. This leads to a failure to get the export list when
+certain mountd protocol versions are disabled.
+---
+
+ CHANGELOG      |    1 +
+ lib/rpc_subs.c |   26 +++++++++++++++++++++-----
+ 2 files changed, 22 insertions(+), 5 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -58,6 +58,7 @@
+ - fix isspace() wild card substition.
+ - auto adjust ldap page size.
+ - fix prune cache valid check.
++- fix mountd vers retry.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/lib/rpc_subs.c
++++ autofs-5.0.5/lib/rpc_subs.c
+@@ -53,6 +53,12 @@
+ /* Get numeric value of the n bits starting at position p */
+ #define getbits(x, p, n)      ((x >> (p + 1 - n)) & ~(~0 << n))
+ 
++static const rpcvers_t mount_vers[] = {
++        MOUNTVERS_NFSV3,
++        MOUNTVERS_POSIX,
++        MOUNTVERS,
++};
++
+ static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *);
+ inline void dump_core(void);
+ 
+@@ -846,6 +852,7 @@ static int rpc_get_exports_proto(struct 
+ 	enum clnt_stat status;
+ 	int proto = info->proto->p_proto;
+ 	unsigned int option = info->close_option;
++	int vers_entry;
+ 
+ 	if (info->proto->p_proto == IPPROTO_UDP) {
+ 		info->send_sz = UDPMSGSIZE;
+@@ -862,10 +869,19 @@ static int rpc_get_exports_proto(struct 
+ 
+ 	client->cl_auth = authunix_create_default();
+ 
+-	status = clnt_call(client, MOUNTPROC_EXPORT,
+-			 (xdrproc_t) xdr_void, NULL,
+-			 (xdrproc_t) xdr_exports, (caddr_t) exp,
+-			 info->timeout);
++	vers_entry = 0;
++	while (1) {
++		status = clnt_call(client, MOUNTPROC_EXPORT,
++				 (xdrproc_t) xdr_void, NULL,
++				 (xdrproc_t) xdr_exports, (caddr_t) exp,
++				 info->timeout);
++		if (status != RPC_PROGVERSMISMATCH)
++			break;
++		if (++vers_entry > 2)
++			break;
++		CLNT_CONTROL(client, CLSET_VERS,
++			    (void *) &mount_vers[vers_entry]);
++	}
+ 
+ 	/* Only play with the close options if we think it completed OK */
+ 	if (proto == IPPROTO_TCP && status == RPC_SUCCESS) {
+@@ -934,7 +950,7 @@ exports rpc_get_exports(const char *host
+ 	info.addr = NULL;
+ 	info.addr_len = 0;
+ 	info.program = MOUNTPROG;
+-	info.version = MOUNTVERS;
++	info.version = mount_vers[0];
+ 	info.send_sz = 0;
+ 	info.recv_sz = 0;
+ 	info.timeout.tv_sec = seconds;
diff --git a/autofs-5.0.5-fix-prune-cache-valid-check.patch b/autofs-5.0.5-fix-prune-cache-valid-check.patch
new file mode 100644
index 0000000..f639578
--- /dev/null
+++ b/autofs-5.0.5-fix-prune-cache-valid-check.patch
@@ -0,0 +1,42 @@
+autofs-5.0.5 - fix prune cache valid check
+
+From: Ian Kent <raven at themaw.net>
+
+During a map reload, when pruning the cache we look for a valid map entry
+in another map. In lookup_prune_one_cache() There is a missing check for
+the entry being in the current map which causes the directory cleanup code
+from doing its job.
+---
+
+ CHANGELOG       |    1 +
+ daemon/lookup.c |    8 ++++++++
+ 2 files changed, 9 insertions(+)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -57,6 +57,7 @@
+ - use weight only for server selection.
+ - fix isspace() wild card substition.
+ - auto adjust ldap page size.
++- fix prune cache valid check.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/daemon/lookup.c
++++ autofs-5.0.5/daemon/lookup.c
+@@ -1060,6 +1060,14 @@ void lookup_prune_one_cache(struct autof
+ 		 * cache entry.
+ 		 */
+ 		valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT);
++		if (valid && valid->mc == mc) {
++			 /*
++			  * We've found a map entry that has been removed from
++			  * the current cache so it isn't really valid.
++			  */
++			cache_unlock(valid->mc);
++			valid = NULL;
++		}
+ 		if (!valid &&
+ 		    is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
+ 			debug(ap->logopt,
diff --git a/autofs-5.0.5-use-weight-only-for-server-selection.patch b/autofs-5.0.5-use-weight-only-for-server-selection.patch
new file mode 100644
index 0000000..d56ff90
--- /dev/null
+++ b/autofs-5.0.5-use-weight-only-for-server-selection.patch
@@ -0,0 +1,568 @@
+autofs-5.0.5 - use weight only for server selection
+
+From: Ian Kent <raven at themaw.net>
+
+When using weighted server names in map entries the server response
+time is also taken into consideration when selecting a server for
+the target of the mount. In some cases people need to be able to
+rely on selection strictly by weight. We add pseudo option
+"--use-weight-only" that can be used in with master map entries
+or with individual map entries to provide for this. For individual
+map entries the option "no-use-weight-only" can also be used to
+override the master map option.
+---
+
+ CHANGELOG            |    1 
+ daemon/automount.c   |    8 ++---
+ include/automount.h  |    3 ++
+ include/replicated.h |    3 +-
+ lib/master_parse.y   |   12 ++++++--
+ lib/master_tok.l     |    1 
+ man/auto.master.5.in |    6 ++++
+ man/autofs.5         |    7 ++++
+ modules/mount_nfs.c  |   15 ++++++----
+ modules/parse_sun.c  |   36 +++++++++++++++++++++---
+ modules/replicated.c |   76 ++++++++++++++++++++++++++++++---------------------
+ 11 files changed, 120 insertions(+), 48 deletions(-)
+
+
+--- autofs-5.0.5.orig/CHANGELOG
++++ autofs-5.0.5/CHANGELOG
+@@ -54,6 +54,7 @@
+ - add external bind method.
+ - fix add simple bind auth.
+ - add option to dump configured automount maps.
++- use weight only for server selection.
+ 
+ 03/09/2009 autofs-5.0.5
+ -----------------------
+--- autofs-5.0.5.orig/daemon/automount.c
++++ autofs-5.0.5/daemon/automount.c
+@@ -57,8 +57,8 @@ const char *fifodir = AUTOFS_FIFO_DIR "/
+ const char *global_options;		/* Global option, from command line */
+ 
+ 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 */
++unsigned int global_selection_options;
++
+ long global_negative_timeout = -1;
+ int do_force_unlink = 0;		/* Forceably unlink mount tree at startup */
+ 
+@@ -1855,7 +1855,7 @@ int main(int argc, char *argv[])
+ 	timeout = defaults_get_timeout();
+ 	ghost = defaults_get_browse_mode();
+ 	logging = defaults_get_logging();
+-	global_random_selection = 0;
++	global_selection_options = 0;
+ 	global_options = NULL;
+ 	have_global_options = 0;
+ 	foreground = 0;
+@@ -1898,7 +1898,7 @@ int main(int argc, char *argv[])
+ 			exit(0);
+ 
+ 		case 'r':
+-			global_random_selection = 1;
++			global_selection_options |= MOUNT_FLAG_RANDOM_SELECT;
+ 			break;
+ 
+ 		case 'n':
+--- autofs-5.0.5.orig/include/automount.h
++++ autofs-5.0.5/include/automount.h
+@@ -443,6 +443,9 @@ struct kernel_mod_version {
+ /* Mount being re-mounted */
+ #define MOUNT_FLAG_REMOUNT		0x0008
+ 
++/* Use server weight only for selection */
++#define MOUNT_FLAG_USE_WEIGHT_ONLY	0x0010
++
+ struct autofs_point {
+ 	pthread_t thid;
+ 	char *path;			/* Mount point name */
+--- autofs-5.0.5.orig/include/replicated.h
++++ autofs-5.0.5/include/replicated.h
+@@ -56,6 +56,7 @@ struct host {
+ 	size_t addr_len;
+ 	char *path;
+ 	unsigned int version;
++	unsigned int options;
+ 	unsigned int proximity;
+ 	unsigned int weight;
+ 	unsigned long cost;
+@@ -65,7 +66,7 @@ struct host {
+ void seed_random(void);
+ void free_host_list(struct host **);
+ int parse_location(unsigned, struct host **, const char *, unsigned int);
+-int prune_host_list(unsigned, struct host **, unsigned int, const char *, unsigned int);
++int prune_host_list(unsigned, struct host **, unsigned int, const char *);
+ void dump_host_list(struct host *);
+ 
+ #endif
+--- autofs-5.0.5.orig/lib/master_parse.y
++++ autofs-5.0.5/lib/master_parse.y
+@@ -58,8 +58,9 @@ static char *format;
+ static long timeout;
+ static long negative_timeout;
+ static unsigned ghost;
+-extern unsigned global_random_selection;
++extern unsigned global_selection_options;
+ static unsigned random_selection;
++static unsigned use_weight;
+ static char **tmp_argv;
+ static int tmp_argc;
+ static char **local_argv;
+@@ -98,7 +99,7 @@ static int master_fprintf(FILE *, char *
+ %token COMMENT
+ %token MAP
+ %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOGHOST OPT_GHOST OPT_VERBOSE
+-%token OPT_DEBUG OPT_RANDOM
++%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT
+ %token COLON COMMA NL DDASH
+ %type <strtype> map
+ %type <strtype> options
+@@ -181,6 +182,7 @@ line:
+ 	| PATH OPTION { master_notify($2); YYABORT; }
+ 	| PATH NILL { master_notify($2); YYABORT; }
+ 	| PATH OPT_RANDOM { master_notify($1); YYABORT; }
++	| PATH OPT_USE_WEIGHT { 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; }
+@@ -558,6 +560,7 @@ daemon_option: OPT_TIMEOUT NUMBER { time
+ 	| OPT_VERBOSE	{ verbose = 1; }
+ 	| OPT_DEBUG	{ debug = 1; }
+ 	| OPT_RANDOM	{ random_selection = 1; }
++	| OPT_USE_WEIGHT { use_weight = 1; }
+ 	;
+ 
+ mount_option: OPTION
+@@ -622,7 +625,8 @@ static void local_init_vars(void)
+ 	timeout = -1;
+ 	negative_timeout = 0;
+ 	ghost = defaults_get_browse_mode();
+-	random_selection = global_random_selection;
++	random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT;
++	use_weight = 0;
+ 	tmp_argv = NULL;
+ 	tmp_argc = 0;
+ 	local_argv = NULL;
+@@ -808,6 +812,8 @@ int master_parse_entry(const char *buffe
+ 	}
+ 	if (random_selection)
+ 		entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
++	if (use_weight)
++		entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY;
+ 	if (negative_timeout)
+ 		entry->ap->negative_timeout = negative_timeout;
+ 
+--- autofs-5.0.5.orig/lib/master_tok.l
++++ autofs-5.0.5/lib/master_tok.l
+@@ -363,6 +363,7 @@ OPTNTOUT	(-n{OPTWS}|-n{OPTWS}={OPTWS}|--
+ 	-g|--ghost|-?browse	{ return(OPT_GHOST); }
+ 	-v|--verbose		{ return(OPT_VERBOSE); }
+ 	-d|--debug		{ return(OPT_DEBUG); }
++	-w|--use-weight-only	{ return(OPT_USE_WEIGHT); }
+ 	-r|--random-multimount-selection { return(OPT_RANDOM); }
+ 
+ 	{OPTWS}","{OPTWS}	{ return(COMMA); }
+--- autofs-5.0.5.orig/man/auto.master.5.in
++++ autofs-5.0.5/man/auto.master.5.in
+@@ -153,6 +153,12 @@ list of replicated servers. This option 
+ only, overriding the global setting that may be specified on the
+ command line.
+ .TP
++.I "\-w, \-\-use-weight-only"
++Use only specified weights for server selection where more than one
++server is specified in the map entry. If no server weights are given
++then each available server will be tried in the order listed, within
++proximity.
++.TP
+ .I "\-n, \-\-negative\-timeout <seconds>"
+ Set the timeout for caching failed key lookups. This option can be
+ used to override the global default given either on the command line
+--- autofs-5.0.5.orig/man/autofs.5
++++ autofs-5.0.5/man/autofs.5
+@@ -49,6 +49,13 @@ is used to treat errors when mounting fi
+ multiple file systems should be mounted (`multi-mounts'). If this option
+ is given, no file system is mounted at all if at least one file system
+ can't be mounted.
++.I -use-weight-only
++is used to make the weight the sole factor in selecting a server when multiple
++servers are present in a map entry.
++and
++.I -no-use-weight-only
++can be used to negate the option if it is present in the master map entry
++for the map but is not wanted for the given mount.
+ 
+ .SS location
+ The location specifies from where the file system is to be mounted.  In the
+--- autofs-5.0.5.orig/modules/mount_nfs.c
++++ autofs-5.0.5/modules/mount_nfs.c
+@@ -63,7 +63,8 @@ int mount_mount(struct autofs_point *ap,
+ 	struct host *this, *hosts = NULL;
+ 	unsigned int mount_default_proto, vers;
+ 	char *nfsoptions = NULL;
+-	unsigned int random_selection = ap->flags & MOUNT_FLAG_RANDOM_SELECT;
++	unsigned int flags = ap->flags &
++			(MOUNT_FLAG_RANDOM_SELECT | MOUNT_FLAG_USE_WEIGHT_ONLY);
+ 	int len, status, err, existed = 1;
+ 	int nosymlink = 0;
+ 	int ro = 0;            /* Set if mount bind should be read-only */
+@@ -112,9 +113,13 @@ int mount_mount(struct autofs_point *ap,
+ 			while (*comma == ' ' || *comma == '\t')
+ 				end--;
+ 
+-			if (strncmp("nosymlink", cp, end - cp + 1) == 0)
++			if (strncmp("nosymlink", cp, end - cp + 1) == 0) {
+ 				nosymlink = 1;
+-			else {
++			} else if (strncmp("no-use-weight-only", cp, end - cp + 1) == 0) {
++				flags &= ~MOUNT_FLAG_USE_WEIGHT_ONLY;
++			} else if (strncmp("use-weight-only", cp, end - cp + 1) == 0) {
++				flags |= MOUNT_FLAG_USE_WEIGHT_ONLY;
++			} else {
+ 				/* Check for options that also make sense
+ 				   with bind mounts */
+ 				if (strncmp("ro", cp, end - cp + 1) == 0)
+@@ -137,11 +142,11 @@ int mount_mount(struct autofs_point *ap,
+ 	else if (mount_default_proto == 4)
+ 		vers = vers | NFS4_VERS_MASK;
+ 
+-	if (!parse_location(ap->logopt, &hosts, what, random_selection)) {
++	if (!parse_location(ap->logopt, &hosts, what, flags)) {
+ 		info(ap->logopt, MODPREFIX "no hosts available");
+ 		return 1;
+ 	}
+-	prune_host_list(ap->logopt, &hosts, vers, nfsoptions, random_selection);
++	prune_host_list(ap->logopt, &hosts, vers, nfsoptions);
+ 
+ 	if (!hosts) {
+ 		info(ap->logopt, MODPREFIX "no hosts available");
+--- autofs-5.0.5.orig/modules/parse_sun.c
++++ autofs-5.0.5/modules/parse_sun.c
+@@ -529,6 +529,7 @@ static int sun_mount(struct autofs_point
+ {
+ 	char *fstype = "nfs";	/* Default filesystem type */
+ 	int nonstrict = 1;
++	int use_weight_only = ap->flags & MOUNT_FLAG_USE_WEIGHT_ONLY;
+ 	int rv, cur_state;
+ 	char *mountpoint;
+ 	char *what;
+@@ -575,6 +576,10 @@ static int sun_mount(struct autofs_point
+ 					memcpy(np, cp, comma - cp + 1);
+ 					np += comma - cp + 1;
+ 				}
++			} else if (strncmp("no-use-weight-only", cp, 18) == 0) {
++				use_weight_only = -1;
++			} else if (strncmp("use-weight-only", cp, 15) == 0) {
++				use_weight_only = MOUNT_FLAG_USE_WEIGHT_ONLY;
+ 			} else if (strncmp("bg", cp, 2) == 0 ||
+ 				   strncmp("nofg", cp, 4) == 0) {
+ 				continue;
+@@ -593,11 +598,10 @@ static int sun_mount(struct autofs_point
+ 		options = noptions;
+ 	}
+ 
+-
+ 	if (!strcmp(fstype, "autofs") && ctxt->macros) {
+ 		char *noptions = NULL;
+ 
+-		if (!options) {
++		if (!options || *options == '\0') {
+ 			noptions = alloca(strlen(ctxt->macros) + 1);
+ 			*noptions = '\0';
+ 		} else {
+@@ -610,7 +614,7 @@ static int sun_mount(struct autofs_point
+ 			}
+ 		}
+ 
+-		if (noptions) {
++		if (noptions && *noptions != '\0') {
+ 			strcat(noptions, ctxt->macros);
+ 			options = noptions;
+ 		} else {
+@@ -624,7 +628,7 @@ static int sun_mount(struct autofs_point
+ 
+ 	type = ap->entry->maps->type;
+ 	if (type && !strcmp(type, "hosts")) {
+-		if (options) {
++		if (options && *options != '\0') {
+ 			int len = strlen(options);
+ 			int suid = strstr(options, "suid") ? 0 : 7;
+ 			int dev = strstr(options, "dev") ? 0 : 6;
+@@ -669,6 +673,30 @@ static int sun_mount(struct autofs_point
+ 		memcpy(what, loc, loclen);
+ 		what[loclen] = '\0';
+ 
++		/* Add back "[no-]use-weight-only" for NFS mounts only */
++		if (use_weight_only) {
++			char *tmp;
++			int len;
++
++			if (options && *options != '\0') {
++				len = strlen(options) + 19;
++				tmp = alloca(len);
++				strcpy(tmp, options);
++				strcat(tmp, ",");
++				if (use_weight_only == MOUNT_FLAG_USE_WEIGHT_ONLY)
++					strcat(tmp, "use-weight-only");
++				else
++					strcat(tmp, "no-use-weight-only");
++			} else {
++				tmp = alloca(19);
++				if (use_weight_only == MOUNT_FLAG_USE_WEIGHT_ONLY)
++					strcpy(tmp, "use-weight-only");
++				else
++					strcpy(tmp, "no-use-weight-only");
++			}
++			options = tmp;
++		}
++
+ 		debug(ap->logopt, MODPREFIX
+ 		      "mounting root %s, mountpoint %s, "
+ 		      "what %s, fstype %s, options %s",
+--- autofs-5.0.5.orig/modules/replicated.c
++++ autofs-5.0.5/modules/replicated.c
+@@ -351,7 +351,8 @@ static unsigned int get_proximity(struct
+ 
+ static struct host *new_host(const char *name,
+ 			     struct sockaddr *addr, size_t addr_len,
+-			     unsigned int proximity, unsigned int weight)
++			     unsigned int proximity, unsigned int weight,
++			     unsigned int options)
+ {
+ 	struct host *new;
+ 	struct sockaddr *tmp2;
+@@ -385,6 +386,7 @@ static struct host *new_host(const char 
+ 	new->addr = tmp2;
+ 	new->proximity = proximity;
+ 	new->weight = weight;
++	new->options = options;
+ 
+ 	return new;
+ }
+@@ -519,9 +521,11 @@ static unsigned short get_port_option(co
+ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
+ 			 struct conn_info *pm_info, struct conn_info *rpc_info,
+ 			 const char *proto, unsigned int version,
+-			 const char *options, unsigned int random_selection)
++			 const char *options)
+ {
+ 	char *have_port_opt = options ? strstr(options, "port=") : NULL;
++	unsigned int random_selection = host->options & MOUNT_FLAG_RANDOM_SELECT;
++	unsigned int use_weight_only = host->options & MOUNT_FLAG_USE_WEIGHT_ONLY;
+ 	struct pmap parms;
+ 	struct timeval start, end;
+ 	struct timezone tz;
+@@ -675,7 +679,10 @@ done_ver:
+ 		 * Average response time to 7 significant places as
+ 		 * integral type.
+ 		 */
+-		host->cost = (unsigned long) ((taken * 1000000) / count);
++		if (use_weight_only)
++			host->cost = 1;
++		else
++			host->cost = (unsigned long) ((taken * 1000000) / count);
+ 
+ 		/* Allow for user bias */
+ 		if (host->weight)
+@@ -689,8 +696,7 @@ done_ver:
+ }
+ 
+ static int get_vers_and_cost(unsigned logopt, struct host *host,
+-			     unsigned int version, const char *options,
+-			     unsigned int random_selection)
++			     unsigned int version, const char *options)
+ {
+ 	struct conn_info pm_info, rpc_info;
+ 	time_t timeout = RPC_TIMEOUT;
+@@ -717,8 +723,7 @@ static int get_vers_and_cost(unsigned lo
+ 
+ 	if (version & UDP_REQUESTED) {
+ 		supported = get_nfs_info(logopt, host,
+-					&pm_info, &rpc_info, "udp", vers,
+-					options, random_selection);
++				   &pm_info, &rpc_info, "udp", vers, options);
+ 		if (supported) {
+ 			ret = 1;
+ 			host->version |= (supported << 8);
+@@ -727,8 +732,7 @@ static int get_vers_and_cost(unsigned lo
+ 
+ 	if (version & TCP_REQUESTED) {
+ 		supported = get_nfs_info(logopt, host,
+-					 &pm_info, &rpc_info, "tcp", vers,
+-					 options, random_selection);
++				   &pm_info, &rpc_info, "tcp", vers, options);
+ 		if (supported) {
+ 			ret = 1;
+ 			host->version |= supported;
+@@ -739,10 +743,11 @@ static int get_vers_and_cost(unsigned lo
+ }
+ 
+ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
+-				      unsigned int version, const char *options,
+-				      unsigned int random_selection)
++				      unsigned int version, const char *options)
+ {
+ 	char *have_port_opt = options ? strstr(options, "port=") : NULL;
++	unsigned int random_selection = host->options & MOUNT_FLAG_RANDOM_SELECT;
++	unsigned int use_weight_only = host->options & MOUNT_FLAG_USE_WEIGHT_ONLY;
+ 	struct conn_info pm_info, rpc_info;
+ 	struct pmap parms;
+ 	const char *proto;
+@@ -855,7 +860,10 @@ done:
+ 
+ 	if (status) {
+ 		/* Response time to 7 significant places as integral type. */
+-		host->cost = (unsigned long) (taken * 1000000);
++		if (use_weight_only)
++			host->cost = 1;
++		else
++			host->cost = (unsigned long) (taken * 1000000);
+ 
+ 		/* Allow for user bias */
+ 		if (host->weight)
+@@ -870,8 +878,7 @@ done:
+ }
+ 
+ int prune_host_list(unsigned logopt, struct host **list,
+-		    unsigned int vers, const char *options,
+-		    unsigned int random_selection)
++		    unsigned int vers, const char *options)
+ {
+ 	struct host *this, *last, *first;
+ 	struct host *new = NULL;
+@@ -892,6 +899,7 @@ int prune_host_list(unsigned logopt, str
+ 	this = first;
+ 	while (this && this->proximity == PROXIMITY_LOCAL)
+ 		this = this->next;
++	first = this;
+ 
+ 	/*
+ 	 * Check for either a list containing only proximity local hosts
+@@ -903,8 +911,6 @@ int prune_host_list(unsigned logopt, str
+ 		return 1;
+ 
+ 	proximity = this->proximity;
+-	first = this;
+-	this = first;
+ 	while (this) {
+ 		struct host *next = this->next;
+ 
+@@ -912,8 +918,7 @@ int prune_host_list(unsigned logopt, str
+ 			break;
+ 
+ 		if (this->name) {
+-			status = get_vers_and_cost(logopt, this, vers,
+-						   options, random_selection);
++			status = get_vers_and_cost(logopt, this, vers, options);
+ 			if (!status) {
+ 				if (this == first) {
+ 					first = next;
+@@ -1022,8 +1027,7 @@ int prune_host_list(unsigned logopt, str
+ 			add_host(&new, this);
+ 		} else {
+ 			status = get_supported_ver_and_cost(logopt, this,
+-						selected_version, options,
+-						random_selection);
++						selected_version, options);
+ 			if (status) {
+ 				this->version = selected_version;
+ 				remove_host(list, this);
+@@ -1041,8 +1045,7 @@ int prune_host_list(unsigned logopt, str
+ 
+ static int add_new_host(struct host **list,
+ 			const char *host, unsigned int weight,
+-			struct addrinfo *host_addr,
+-			unsigned int random_selection)
++			struct addrinfo *host_addr, unsigned int options)
+ {
+ 	struct host *new;
+ 	unsigned int prx;
+@@ -1054,10 +1057,21 @@ static int add_new_host(struct host **li
+ 	 * We can't use PROXIMITY_LOCAL or we won't perform an RPC ping
+ 	 * to remove hosts that may be down.
+ 	 */
+-	if (random_selection)
++	if (options & MOUNT_FLAG_RANDOM_SELECT)
+ 		prx = PROXIMITY_SUBNET;
+-	else
++	else {
+ 		prx = get_proximity(host_addr->ai_addr);
++		/*
++		 * If we want the weight to be the determining factor
++		 * when selecting a host then all hosts must have the
++		 * same proximity. However, if this is the local machine
++		 * it should always be used since it is certainly available.
++		 */
++		if (prx != PROXIMITY_LOCAL &&
++		   (options & MOUNT_FLAG_USE_WEIGHT_ONLY))
++			prx = PROXIMITY_SUBNET;
++	}
++
+ 	/*
+ 	 * If we tried to add an IPv6 address and we don't have IPv6
+ 	 * support return success in the hope of getting an IPv4
+@@ -1069,7 +1083,7 @@ static int add_new_host(struct host **li
+ 		return 0;
+ 
+ 	addr_len = sizeof(struct sockaddr);
+-	new = new_host(host, host_addr->ai_addr, addr_len, prx, weight);
++	new = new_host(host, host_addr->ai_addr, addr_len, prx, weight, options);
+ 	if (!new)
+ 		return 0;
+ 
+@@ -1082,7 +1096,7 @@ static int add_new_host(struct host **li
+ }
+ 
+ static int add_host_addrs(struct host **list, const char *host,
+-			  unsigned int weight, unsigned int random_selection)
++			  unsigned int weight, unsigned int options)
+ {
+ 	struct addrinfo hints, *ni, *this;
+ 	int ret;
+@@ -1098,7 +1112,7 @@ static int add_host_addrs(struct host **
+ 
+ 	this = ni;
+ 	while (this) {
+-		ret = add_new_host(list, host, weight, this, random_selection);
++		ret = add_new_host(list, host, weight, this, options);
+ 		if (!ret)
+ 			break;
+ 		this = this->ai_next;
+@@ -1121,7 +1135,7 @@ try_name:
+ 
+ 	this = ni;
+ 	while (this) {
+-		ret = add_new_host(list, host, weight, this, random_selection);
++		ret = add_new_host(list, host, weight, this, options);
+ 		if (!ret)
+ 			break;
+ 		this = this->ai_next;
+@@ -1209,7 +1223,7 @@ static char *seek_delim(const char *s)
+ }
+ 
+ int parse_location(unsigned logopt, struct host **hosts,
+-		   const char *list, unsigned int random_selection)
++		   const char *list, unsigned int options)
+ {
+ 	char *str, *p, *delim;
+ 	unsigned int empty = 1;
+@@ -1264,7 +1278,7 @@ int parse_location(unsigned logopt, stru
+ 				}
+ 
+ 				if (p != delim) {
+-					if (!add_host_addrs(hosts, p, weight, random_selection)) {
++					if (!add_host_addrs(hosts, p, weight, options)) {
+ 						if (empty) {
+ 							p = next;
+ 							continue;
+@@ -1286,7 +1300,7 @@ int parse_location(unsigned logopt, stru
+ 				*delim = '\0';
+ 				next = delim + 1;
+ 
+-				if (!add_host_addrs(hosts, p, weight, random_selection)) {
++				if (!add_host_addrs(hosts, p, weight, options)) {
+ 					p = next;
+ 					continue;
+ 				}
diff --git a/autofs.spec b/autofs.spec
index 7c8d791..9fc9a65 100644
--- a/autofs.spec
+++ b/autofs.spec
@@ -4,7 +4,7 @@
 Summary: A tool for automatically mounting and unmounting filesystems
 Name: autofs
 Version: 5.0.5
-Release: 35%{?dist}
+Release: 36%{?dist}
 Epoch: 1
 License: GPLv2+
 Group: System Environment/Daemons
@@ -68,6 +68,13 @@ Patch56: autofs-5.0.5-add-external-bind-method.patch
 Patch57: autofs-5.0.5-fix-add-simple-bind-auth.patch
 Patch58: autofs-5.0.5-add-dump-maps-option.patch
 Patch59: autofs-5.0.5-fix-submount-shutdown-wait.patch
+Patch60: autofs-5.0.5-use-weight-only-for-server-selection.patch
+Patch61: autofs-5.0.5-fix-isspace-wild-card-substition.patch
+Patch62: autofs-5.0.5-auto-adjust-ldap-page-size.patch
+Patch63: autofs-5.0.5-fix-prune-cache-valid-check.patch
+Patch64: autofs-5.0.5-fix-mountd-vers-retry.patch
+Patch65: autofs-5.0.5-fix-expire-race.patch
+Patch66: autofs-5.0.5-add-lsb-force-reload-and-try-restart.patch
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel
 Conflicts: cyrus-sasl-lib < 2.1.23-9
@@ -169,6 +176,13 @@ echo %{version}-%{release} > .version
 %patch57 -p1
 %patch58 -p1
 %patch59 -p1
+%patch60 -p1
+%patch61 -p1
+%patch62 -p1
+%patch63 -p1
+%patch64 -p1
+%patch65 -p1
+%patch66 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -221,6 +235,15 @@ fi
 %{_libdir}/autofs/
 
 %changelog
+* Thu Mar 03 2011 Ian Kent <ikent at redhat.com> - 1:5.0.5-36
+- use weight only for server selection.
+- fix isspace() wild card substition.
+- auto adjust ldap page size.
+- fix prune cache valid check.
+- fix mountd vers retry.
+- fix expire race.
+- add lsb force-reload and try-restart.
+
 * Mon Feb 07 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1:5.0.5-35
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
 


More information about the scm-commits mailing list