rpms/autofs/FC-6 autofs-5.0.1-rc3-map-update-source-only.patch, NONE, 1.1 autofs.spec, 1.179, 1.180

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Thu May 31 06:07:50 UTC 2007


Author: ikent

Update of /cvs/dist/rpms/autofs/FC-6
In directory cvs.devel.redhat.com:/tmp/cvs-serv32307

Modified Files:
	autofs.spec 
Added Files:
	autofs-5.0.1-rc3-map-update-source-only.patch 
Log Message:
* Thu May 31 2007 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc3.30
- fix wildcard map handling and improve nsswitch source map re-reading.


autofs-5.0.1-rc3-map-update-source-only.patch:
 daemon/direct.c           |    4 -
 daemon/indirect.c         |    4 -
 daemon/lookup.c           |   93 +++++++++++++++------------
 daemon/state.c            |    2 
 include/automount.h       |    9 +-
 include/master.h          |    3 
 lib/cache.c               |   15 ++--
 lib/master.c              |  123 ++++++++++++++++++++++++++++--------
 lib/master_parse.y        |    2 
 modules/lookup_file.c     |  155 ++++++++++++++++++----------------------------
 modules/lookup_hesiod.c   |    2 
 modules/lookup_hosts.c    |    4 -
 modules/lookup_ldap.c     |  100 +++++++++++++++--------------
 modules/lookup_nisplus.c  |   95 +++++++++++++++-------------
 modules/lookup_program.c  |    2 
 modules/lookup_userhome.c |    2 
 modules/lookup_yp.c       |   79 ++++++++++++-----------
 modules/parse_sun.c       |    2 
 18 files changed, 382 insertions(+), 314 deletions(-)

--- NEW FILE autofs-5.0.1-rc3-map-update-source-only.patch ---
--- autofs-5.0.1/include/automount.h.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/include/automount.h	2007-05-31 13:48:14.000000000 +0800
@@ -141,6 +141,7 @@ struct mapent {
 	pthread_mutex_t multi_mutex;
 	struct list_head multi_list;
 	struct mapent_cache *mc;
+	struct map_source *source;
 	/* Need to know owner if we're a multi-mount */
 	struct mapent *multi;
 	/* Parent nesting point within multi-mount */
@@ -175,10 +176,10 @@ struct mapent *cache_lookup(struct mapen
 struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key);
 struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head);
 struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix);
-int cache_add(struct mapent_cache *mc, const char *key, const char *mapent, time_t age);
+int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
 int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
 int cache_set_parents(struct mapent *mm);
-int cache_update(struct mapent_cache *mc, const char *key, const char *mapent, time_t age);
+int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
 int cache_delete(struct mapent_cache *mc, const char *key);
 void cache_multi_lock(struct mapent *me);
 void cache_multi_unlock(struct mapent *me);
@@ -221,11 +222,11 @@ int rmdir_path(struct autofs_point *ap, 
 #define PARSE_MAX_BUF	KEY_MAX_LEN + MAPENT_MAX_LEN + 2
 
 int lookup_nss_read_master(struct master *master, time_t age);
-int lookup_nss_read_map(struct autofs_point *ap, time_t age);
+int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age);
 int lookup_enumerate(struct autofs_point *ap,
 	int (*fn)(struct autofs_point *,struct mapent *, int), time_t now);
 int lookup_ghost(struct autofs_point *ap);
-int lookup_nss_mount(struct autofs_point *ap, const char *name, int name_len);
+int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len);
 void lookup_close_lookup(struct autofs_point *ap);
 int lookup_prune_cache(struct autofs_point *ap, time_t age);
 struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type);
--- autofs-5.0.1/include/master.h.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/include/master.h	2007-05-31 13:48:14.000000000 +0800
@@ -85,7 +85,8 @@ void master_free_map_source(struct map_s
 struct map_source *
 master_find_source_instance(struct map_source *, const char *, const char *, int, const char **);
 struct map_source *
-master_add_source_instance(struct map_source *, const char *, const char *, time_t);
+master_add_source_instance(struct map_source *, const char *, const char *, time_t, int, const char **);
+void send_map_update_request(struct autofs_point *);
 void master_source_writelock(struct master_mapent *);
 void master_source_readlock(struct master_mapent *);
 void master_source_unlock(struct master_mapent *);
--- autofs-5.0.1/modules/parse_sun.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/parse_sun.c	2007-05-31 13:48:14.000000000 +0800
@@ -1141,7 +1141,7 @@ int parse_mount(struct autofs_point *ap,
 			 * Not in the cache, perhaps it's a program map
 			 * or one that doesn't support enumeration
 			 */
-			ret = cache_add(mc, name, mapent, time(NULL));
+			ret = cache_add(mc, source, name, mapent, time(NULL));
 			if (ret == CHE_FAIL) {
 				cache_unlock(mc);
 				free(options);
--- autofs-5.0.1/modules/lookup_nisplus.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_nisplus.c	2007-05-31 13:48:14.000000000 +0800
@@ -234,7 +234,7 @@ int lookup_read_map(struct autofs_point 
 		mapent = ENTRY_VAL(this, 1);
 
 		cache_writelock(mc);
-		cache_update(mc, s_key, mapent, age);
+		cache_update(mc, source, s_key, mapent, age);
 		cache_unlock(mc);
 
 		free(s_key);
@@ -296,7 +296,7 @@ static int lookup_one(struct autofs_poin
 	this = NIS_RES_OBJECT(result);
 	mapent = ENTRY_VAL(this, 1);
 	cache_writelock(mc);
-	ret = cache_update(mc, key, mapent, age);
+	ret = cache_update(mc, source, key, mapent, age);
 	cache_unlock(mc);
 
 	nis_freeresult(result);
@@ -348,7 +348,7 @@ static int lookup_wild(struct autofs_poi
 	this = NIS_RES_OBJECT(result);
 	mapent = ENTRY_VAL(this, 1);
 	cache_writelock(mc);
-	ret = cache_update(mc, "*", mapent, age);
+	ret = cache_update(mc, source, "*", mapent, age);
 	cache_unlock(mc);
 
 	nis_freeresult(result);
@@ -366,7 +366,6 @@ static int check_map_indirect(struct aut
 	struct mapent *me, *exists;
 	time_t now = time(NULL);
 	time_t t_last_read;
-	int need_map = 0;
 	int ret = 0;
 
 	source = ap->entry->current;
@@ -375,12 +374,6 @@ static int check_map_indirect(struct aut
 
 	mc = source->mc;
 
-	cache_readlock(mc);
-	exists = cache_lookup_distinct(mc, key);
-	if (exists && exists->mc != mc)
-		exists = NULL;
-	cache_unlock(mc);
-
 	master_source_current_wait(ap->entry);
 	ap->entry->current = source;
 
@@ -396,51 +389,62 @@ static int check_map_indirect(struct aut
 		return NSS_STATUS_UNAVAIL;
 	}
 
-	cache_readlock(mc);
+	pthread_cleanup_push(cache_lock_cleanup, mc);
+	cache_writelock(mc);
+	t_last_read = ap->exp_runfreq + 1;
 	me = cache_lookup_first(mc);
-	t_last_read = me ? now - me->age : ap->exp_runfreq + 1;
-	cache_unlock(mc);
-
-	if (t_last_read > ap->exp_runfreq)
-		if ((ret & CHE_UPDATED) ||
-		    (exists && (ret & CHE_MISSING)))
-			need_map = 1;
+	while (me) {
+		if (me->source == source) {
+			t_last_read = now - me->age;
+			break;
+		}
+		me = cache_lookup_next(mc, me);
+	}
+	exists = cache_lookup_distinct(mc, key);
+	/* Not found in the map but found in the cache */
+	if (exists && exists->source == source && ret & CHE_MISSING) {
+		if (exists->mapent) {
+			free(exists->mapent);
+			exists->mapent = NULL;
+			source->stale = 1;
+			exists->status = 0;
+		}
+	}
+	pthread_cleanup_pop(1);
+	
+	if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED)
+		source->stale = 1;
 
 	if (ret == CHE_MISSING) {
 		int wild = CHE_MISSING;
+		struct mapent *we;
 
 		master_source_current_wait(ap->entry);
 		ap->entry->current = source;
 
 		wild = lookup_wild(ap, ctxt);
-		if (wild == CHE_UPDATED || CHE_OK)
-			return NSS_STATUS_SUCCESS;
-
+		/*
+		 * Check for map change and update as needed for
+		 * following cache lookup.
+		*/
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_writelock(mc);
-		if (wild == CHE_MISSING)
-			cache_delete(mc, "*");
-
-		if (cache_delete(mc, key) && wild & (CHE_MISSING | CHE_FAIL))
-			rmdir_path(ap, key, ap->dev);
+		we = cache_lookup_distinct(mc, "*");
+		if (we) {
+			/* Wildcard entry existed and is now gone */
+			if (we->source == source && wild & CHE_MISSING) {
+				cache_delete(mc, "*");
+				source->stale = 1;
+			}
+		} else {
+			/* Wildcard not in map but now is */
+			if (wild & (CHE_OK || CHE_UPDATED))
+				source->stale = 1;
+		}
 		pthread_cleanup_pop(1);
-	}
-
-	/* Have parent update its map */
-	if (ap->ghost && need_map) {
-		int status;
 
-		source->stale = 1;
-
-		status = pthread_mutex_lock(&ap->state_mutex);
-		if (status)
-			fatal(status);
-
-		nextstate(ap->state_pipe[1], ST_READMAP);
-
-		status = pthread_mutex_unlock(&ap->state_mutex);
-		if (status)
-			fatal(status);
+		if (wild & (CHE_UPDATED || CHE_OK))
+			return NSS_STATUS_SUCCESS;
 	}
 
 	if (ret == CHE_MISSING)
@@ -514,7 +518,10 @@ int lookup_mount(struct autofs_point *ap
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	if (me && me->mapent && *me->mapent) {
+	/* Stale mapent => check for wildcard */
+	if (me && !me->mapent)
+		me = cache_lookup_distinct(mc, "*");
+	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
 		strcpy(mapent, me->mapent);
@@ -535,7 +542,7 @@ int lookup_mount(struct autofs_point *ap
 			cache_writelock(mc);
 			me = cache_lookup_distinct(mc, key);
 			if (!me)
-				rv = cache_update(mc, key, NULL, now);
+				rv = cache_update(mc, source, key, NULL, now);
 			if (rv != CHE_FAIL) {
 				me = cache_lookup_distinct(mc, key);
 				me->status = time(NULL) + NEGATIVE_TIMEOUT;
--- autofs-5.0.1/modules/lookup_file.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_file.c	2007-05-31 13:48:14.000000000 +0800
@@ -551,45 +551,20 @@ static int check_self_include(const char
 	return 0;
 }
 
-static struct autofs_point *
+static struct map_source *
 prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned int inc)
 {
-	struct master *master;
-	struct master_mapent *entry;
 	struct map_source *current;
 	struct map_source *source;
-	struct autofs_point *iap;
 	char *type, *map, *fmt;
 	const char *argv[2];
-	int ret, argc;
-	unsigned int timeout = ap->exp_timeout;
-	unsigned int logopt = ap->logopt;
-	unsigned int ghost = ap->ghost;
+	int argc;
 	char *buf, *tmp;
 
 	current = ap->entry->current;
 	ap->entry->current = NULL;
 	master_source_current_signal(ap->entry);
 
-	master = ap->entry->master;
-
-	entry = master_new_mapent(master, ap->path, ap->entry->age);
-	if (!entry) {
-		error(ap->logopt, MODPREFIX "malloc failed for entry");
-		return NULL;
-	}
-
-	ret = master_add_autofs_point(entry, timeout, logopt, ghost, 0);
-	if (!ret) {
-		master_free_mapent(entry);
-		error(ap->logopt,
-		      MODPREFIX "failed to add autofs_point to entry");
-		return NULL;
-	}
-	iap = entry->ap;
-	iap->kpipefd = ap->kpipefd;
-	set_mnt_logging(iap);
-
 	/*
 	 * TODO:
 	 * Initially just consider the passed in key to be a simple map
@@ -602,7 +577,6 @@ prepare_plus_include(struct autofs_point
 	/* skip plus */
 	buf = strdup(key + 1);
 	if (!buf) {
-		master_free_mapent(entry);
 		error(ap->logopt, MODPREFIX "failed to strdup key");
 		return NULL;
 	}
@@ -633,21 +607,23 @@ prepare_plus_include(struct autofs_point
 	argv[0] = map;
 	argv[1] = NULL;
 
-	source = master_add_map_source(entry, type, fmt, age, argc, argv);
+	source = master_find_source_instance(current, type, fmt, argc, argv);
 	if (!source) {
-		master_free_mapent(entry);
-		free(buf);
-		error(ap->logopt, "failed to creat map_source");
-		return NULL;
+		source = master_add_source_instance(current, type, fmt, age, argc, argv);
+		if (!source) {
+			free(buf);
+			error(ap->logopt, "failed to add included map instance");
+			return NULL;
+		}
 	}
-	source->mc = current->mc;
+
 	source->depth = current->depth + 1;
 	if (inc)
 		source->recurse = 1;
 
 	free(buf);
 
-	return iap;
+	return source;
 }
 
 int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
@@ -719,7 +695,7 @@ int lookup_read_map(struct autofs_point 
 		 * included map.
 		 */
 		if (*key == '+') {
-			struct autofs_point *iap;
+			struct map_source *inc_source;
 			unsigned int inc;
 			int status;
 
@@ -730,21 +706,18 @@ int lookup_read_map(struct autofs_point 
 			master_source_current_wait(ap->entry);
 			ap->entry->current = source;
 
-			iap = prepare_plus_include(ap, age, key, inc);
-			if (!iap) {
+			inc_source = prepare_plus_include(ap, age, key, inc);
+			if (!inc_source) {
 				debug(ap->logopt,
 				      "failed to select included map %s", key);
 				continue;
 			}
 
 			/* Gim'ee some o' that 16k stack baby !! */
-			status = lookup_nss_read_map(iap, age);
+			status = lookup_nss_read_map(ap, inc_source, age);
 			if (!status)
 				warn(ap->logopt,
 				     "failed to read included map %s", key);
-
-			master_free_mapent_sources(iap->entry, 0);
-			master_free_mapent(iap->entry);
 		} else {
 			char *s_key; 
 
@@ -753,7 +726,7 @@ int lookup_read_map(struct autofs_point 
 				continue;
 
 			cache_writelock(mc);
-			cache_update(mc, s_key, mapent, age);
+			cache_update(mc, source, s_key, mapent, age);
 			cache_unlock(mc);
 
 			free(s_key);
@@ -819,7 +792,7 @@ static int lookup_one(struct autofs_poin
 			 * included map.
 			 */
 			if (*mkey == '+') {
-				struct autofs_point *iap;
+				struct map_source *inc_source;
 				unsigned int inc;
 				int status;
 
@@ -831,8 +804,8 @@ static int lookup_one(struct autofs_poin
 				master_source_current_wait(ap->entry);
 				ap->entry->current = source;
 
-				iap = prepare_plus_include(ap, age, mkey, inc);
-				if (!iap) {
+				inc_source = prepare_plus_include(ap, age, mkey, inc);
+				if (!inc_source) {
 					debug(ap->logopt,
 					      MODPREFIX
 					      "failed to select included map %s",
@@ -841,11 +814,7 @@ static int lookup_one(struct autofs_poin
 				}
 
 				/* Gim'ee some o' that 16k stack baby !! */
-				status = lookup_nss_mount(iap, key, key_len);
-
-				master_free_mapent_sources(iap->entry, 0);
-				master_free_mapent(iap->entry);
-
+				status = lookup_nss_mount(ap, inc_source, key, key_len);
 				if (status) {
 					fclose(f);
 					return CHE_COMPLETED;
@@ -872,7 +841,7 @@ static int lookup_one(struct autofs_poin
 				free(s_key);
 
 				cache_writelock(mc);
-				ret = cache_update(mc, key, mapent, age);
+				ret = cache_update(mc, source, key, mapent, age);
 				cache_unlock(mc);
 
 				fclose(f);
@@ -932,7 +901,7 @@ static int lookup_wild(struct autofs_poi
 				continue;
 
 			cache_writelock(mc);
-			ret = cache_update(mc, "*", mapent, age);
+			ret = cache_update(mc, source, "*", mapent, age);
 			cache_unlock(mc);
 
 			fclose(f);
@@ -956,7 +925,6 @@ static int check_map_indirect(struct aut
 	struct map_source *source;
 	struct mapent_cache *mc;
 	struct mapent *exists;
-	int need_map = 0;
 	int ret = CHE_OK;
 
 	source = ap->entry->current;
@@ -965,12 +933,6 @@ static int check_map_indirect(struct aut
 
 	mc = source->mc;
 
-	cache_readlock(mc);
-	exists = cache_lookup_distinct(mc, key);
-	if (exists && exists->mc != mc)
-		exists = NULL;
-	cache_unlock(mc);
-
 	master_source_current_wait(ap->entry);
 	ap->entry->current = source;
 
@@ -981,49 +943,53 @@ static int check_map_indirect(struct aut
 	if (ret == CHE_FAIL)
 		return NSS_STATUS_NOTFOUND;
 
-	if ((ret & CHE_UPDATED) ||
-	    (exists && (ret & CHE_MISSING)))
-		need_map = 1;
+	if (ret & CHE_UPDATED)
+		source->stale = 1;
+
+	pthread_cleanup_push(cache_lock_cleanup, mc);
+	cache_writelock(mc);
+	exists = cache_lookup_distinct(mc, key);
+	/* Not found in the map but found in the cache */
+	if (exists && exists->source == source && ret & CHE_MISSING) {
+		if (exists->mapent) {
+			free(exists->mapent);
+			exists->mapent = NULL;
+			exists->status = 0;
+			source->stale = 1;
+		}
+	}
+	pthread_cleanup_pop(1);
 
 	if (ret == CHE_MISSING) {
+		struct mapent *we;
 		int wild = CHE_MISSING;
 
 		master_source_current_wait(ap->entry);
 		ap->entry->current = source;
 
 		wild = lookup_wild(ap, ctxt);
-		if (wild == CHE_COMPLETED || CHE_UPDATED || CHE_OK)
-			return NSS_STATUS_SUCCESS;
-/*
-		if (wild == CHE_FAIL)
-			return NSS_STATUS_NOTFOUND;
-*/
+		/*
+		 * Check for map change and update as needed for
+		 * following cache lookup.
+		 */
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_writelock(mc);
-		if (wild == CHE_MISSING)
-			cache_delete(mc, "*");
-
-		if (cache_delete(mc, key) && wild & (CHE_MISSING | CHE_FAIL))
-			rmdir_path(ap, key, ap->dev);
+		we = cache_lookup_distinct(mc, "*");
+		if (we) {
+			/* Wildcard entry existed and is now gone */
+			if (we->source == source && (wild & CHE_MISSING)) {
+				cache_delete(mc, "*");
+				source->stale = 1;
+			}
+		} else {
+			/* Wildcard not in map but now is */
+			if (wild & (CHE_OK || CHE_UPDATED))
+				source->stale = 1;
+		}
 		pthread_cleanup_pop(1);
-	}
 
-	/* Have parent update its map ? */
-	/* TODO: update specific map */
-	if (ap->ghost && need_map) {
-		int status;
-
-		source->stale = 1;
-
-		status = pthread_mutex_lock(&ap->state_mutex);
-		if (status)
-			fatal(status);
-
-		nextstate(ap->state_pipe[1], ST_READMAP);
-
-		status = pthread_mutex_unlock(&ap->state_mutex);
-		if (status)
-			fatal(status);
+		if (wild & (CHE_OK || CHE_UPDATED))
+			return NSS_STATUS_SUCCESS;
 	}
 
 	if (ret == CHE_MISSING)
@@ -1113,7 +1079,10 @@ int lookup_mount(struct autofs_point *ap
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	if (me && me->mapent && *me->mapent) {
+	/* Stale mapent => check for wildcard */
+	if (me && !me->mapent)
+		me = cache_lookup_distinct(mc, "*");
+	if (me && (me->source == source || *me->key == '/')) {
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
@@ -1136,7 +1105,7 @@ int lookup_mount(struct autofs_point *ap
 			cache_writelock(mc);
 			me = cache_lookup_distinct(mc, key);
 			if (!me)
-				rv = cache_update(mc, key, NULL, now);
+				rv = cache_update(mc, source, key, NULL, now);
 			if (rv != CHE_FAIL) {
 				me = cache_lookup_distinct(mc, key);
 				me->status = now + NEGATIVE_TIMEOUT;
--- autofs-5.0.1/modules/lookup_program.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_program.c	2007-05-31 13:48:14.000000000 +0800
@@ -339,7 +339,7 @@ int lookup_mount(struct autofs_point *ap
 	}
 
 	cache_writelock(mc);
-	ret = cache_update(mc, name, mapent, time(NULL));
+	ret = cache_update(mc, source, name, mapent, time(NULL));
 	cache_unlock(mc);
 	if (ret == CHE_FAIL)
 		return NSS_STATUS_UNAVAIL;
--- autofs-5.0.1/modules/lookup_userhome.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_userhome.c	2007-05-31 13:48:14.000000000 +0800
@@ -78,7 +78,7 @@ int lookup_mount(struct autofs_point *ap
 	}
 
 	cache_writelock(mc);
-	ret = cache_update(mc, name, NULL, time(NULL));
+	ret = cache_update(mc, source, name, NULL, time(NULL));
 	cache_unlock(mc);
 
 	if (ret == CHE_FAIL) {
--- autofs-5.0.1/modules/lookup_hosts.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_hosts.c	2007-05-31 13:48:14.000000000 +0800
@@ -97,7 +97,7 @@ int lookup_read_map(struct autofs_point 
 	while ((host = gethostent()) != NULL) {
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_writelock(mc);
-		cache_update(mc, host->h_name, NULL, age);
+		cache_update(mc, source, host->h_name, NULL, age);
 		cache_unlock(mc);
 		pthread_cleanup_pop(0);
 	}
@@ -250,7 +250,7 @@ done:
 	debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent);
 
 	cache_writelock(mc);
-	cache_update(mc, name, mapent, now);
+	cache_update(mc, source, name, mapent, now);
 	cache_unlock(mc);
 
 	debug(LOGOPT_ANY, "source wait");
--- autofs-5.0.1/modules/lookup_hesiod.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_hesiod.c	2007-05-31 13:48:14.000000000 +0800
@@ -154,7 +154,7 @@ int lookup_mount(struct autofs_point *ap
 	}
 
 	cache_writelock(mc);
-	rv = cache_update(mc, name, best_record, time(NULL));
+	rv = cache_update(mc, source, name, best_record, time(NULL));
 	cache_unlock(mc);
 	if (rv == CHE_FAIL)
 		return NSS_STATUS_UNAVAIL;
--- autofs-5.0.1/modules/lookup_ldap.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_ldap.c	2007-05-31 13:48:14.000000000 +0800
@@ -1251,7 +1251,7 @@ static int read_one_map(struct autofs_po
 			goto next;
 
 		cache_writelock(mc);
-		cache_update(mc, s_key, mapent, age);
+		cache_update(mc, source, s_key, mapent, age);
 		cache_unlock(mc);
 
 		free(s_key);
@@ -1313,6 +1313,7 @@ static int lookup_one(struct autofs_poin
 	char *attrs[3];
 	int scope = LDAP_SCOPE_SUBTREE;
 	LDAP *ldap;
+	struct mapent *we;
 	unsigned int wild = 0;
 	int ret = CHE_MISSING;
 
@@ -1466,7 +1467,7 @@ static int lookup_one(struct autofs_poin
 				goto next;
 			wild = 1;
 			cache_writelock(mc);
-			cache_update(mc, "*", mapent, age);
+			cache_update(mc, source, "*", mapent, age);
 			cache_unlock(mc);
 			goto next;
 		}
@@ -1476,7 +1477,7 @@ static int lookup_one(struct autofs_poin
 			goto next;
 
 		cache_writelock(mc);
-		ret = cache_update(mc, s_key, mapent, age);
+		ret = cache_update(mc, source, s_key, mapent, age);
 		cache_unlock(mc);
 
 		free(s_key);
@@ -1493,10 +1494,34 @@ next:
 	ldap_msgfree(result);
 	unbind_ldap_connection(ldap, ctxt);
 
+	/* Failed to find wild entry, update cache if needed */
+	pthread_cleanup_push(cache_lock_cleanup, mc);
 	cache_writelock(mc);
-	if (!wild && cache_lookup(mc, "*"))
-		cache_delete(mc, "*");
-	cache_unlock(mc);
+	we = cache_lookup_distinct(mc, "*");
+	if (we) {
+		/* Wildcard entry existed and is now gone */
+		if (we->source == source && !wild) {
+			cache_delete(mc, "*");
+			source->stale = 1;
+		}
+	} else {
+		/* Wildcard not in map but now is */
+		if (wild)
+			source->stale = 1;
+	}
+	/* Not found in the map but found in the cache */
+	if (ret == CHE_MISSING) {
+		struct mapent *exists = cache_lookup_distinct(mc, qKey);
+		if (exists && exists->source == source) {
+			if (exists->mapent) {
+				free(exists->mapent);
+				exists->mapent = NULL;
+				source->stale = 1;
+				exists->status = 0;
+			}
+		}
+	}
+	pthread_cleanup_pop(1);
 
 	return ret;
 }
@@ -1507,10 +1532,10 @@ static int check_map_indirect(struct aut
 {
 	struct map_source *source;
 	struct mapent_cache *mc;
-	struct mapent *me, *exists;
+	struct mapent *me;
 	time_t now = time(NULL);
 	time_t t_last_read;
-	int ret, cur_state, need_map = 0;
+	int ret, cur_state;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
@@ -1518,12 +1543,6 @@ static int check_map_indirect(struct aut
 
 	mc = source->mc;
 
-	cache_readlock(mc);
-	exists = cache_lookup_distinct(mc, key);
-	if (exists && exists->mc != mc)
-		exists = NULL;
-	cache_unlock(mc);
-
 	master_source_current_wait(ap->entry);
 	ap->entry->current = source;
 
@@ -1535,44 +1554,28 @@ static int check_map_indirect(struct aut
 	}
 	pthread_setcancelstate(cur_state, NULL);
 
+	/*
+	 * Check for map change and update as needed for
+	 * following cache lookup.
+	 */
 	cache_readlock(mc);
+	t_last_read = ap->exp_runfreq + 1;
 	me = cache_lookup_first(mc);
-	t_last_read = me ? now - me->age : ap->exp_runfreq + 1;
-	cache_unlock(mc);
-
-	if (t_last_read > ap->exp_runfreq) {
-		if ((ret & CHE_UPDATED) ||
-		    (exists && (ret & CHE_MISSING)))
-			need_map = 1;
-	}
-
-	if (ret == CHE_MISSING && exists) {
-		pthread_cleanup_push(cache_lock_cleanup, mc);
-		cache_writelock(mc);
-		if (cache_delete(mc, key))
-			rmdir_path(ap, key, ap->dev);
-		pthread_cleanup_pop(1);
+	while (me) {
+		if (me->source == source) {
+			t_last_read = now - me->age;
+			break;
+		}
+		me = cache_lookup_next(mc, me);
 	}
+	cache_unlock(mc);
 
-	/* Have parent update its map */
-	if (ap->ghost && need_map) {
-		int status;
-
+	if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED)
 		source->stale = 1;
 
-		status = pthread_mutex_lock(&ap->state_mutex);
-		if (status)
-			fatal(status);
-
-		nextstate(ap->state_pipe[1], ST_READMAP);
-
-		status = pthread_mutex_unlock(&ap->state_mutex);
-		if (status)
-			fatal(status);
-	}
-
 	cache_readlock(mc);
-	if (ret == CHE_MISSING && !cache_lookup(mc, "*")) {
+	me = cache_lookup_distinct(mc, "*");
+	if (ret == CHE_MISSING && (!me || me->source != source)) {
 		cache_unlock(mc);
 		return NSS_STATUS_NOTFOUND;
 	}
@@ -1648,7 +1651,10 @@ int lookup_mount(struct autofs_point *ap
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	if (me && me->mapent && *me->mapent) {
+	/* Stale mapent => check for wildcard */
+	if (me && !me->mapent)
+		me = cache_lookup_distinct(mc, "*");
+	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
 		strcpy(mapent, me->mapent);
@@ -1670,7 +1676,7 @@ int lookup_mount(struct autofs_point *ap
 			cache_writelock(mc);
 			me = cache_lookup_distinct(mc, key);
 			if (!me)
-				rv = cache_update(mc, key, NULL, now);
+				rv = cache_update(mc, source, key, NULL, now);
 			if (rv != CHE_FAIL) {
 				me = cache_lookup_distinct(mc, key);
 				me->status = now + NEGATIVE_TIMEOUT;
--- autofs-5.0.1/modules/lookup_yp.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/modules/lookup_yp.c	2007-05-31 13:48:14.000000000 +0800
@@ -272,7 +272,7 @@ int yp_all_callback(int status, char *yp
 	*(mapent + vallen) = '\0';
 
 	cache_writelock(mc);
-	ret = cache_update(mc, key, mapent, age);
+	ret = cache_update(mc, source, key, mapent, age);
 	cache_unlock(mc);
 
 	free(key);
@@ -389,7 +389,7 @@ static int lookup_one(struct autofs_poin
 	}
 
 	cache_writelock(mc);
-	ret = cache_update(mc, key, mapent, age);
+	ret = cache_update(mc, source, key, mapent, age);
 	cache_unlock(mc);
 	free(mapent);
 
@@ -441,7 +441,7 @@ static int lookup_wild(struct autofs_poi
 	}
 
 	cache_writelock(mc);
-	ret = cache_update(mc, "*", mapent, age);
+	ret = cache_update(mc, source, "*", mapent, age);
 	cache_unlock(mc);
 	free(mapent);
 
@@ -456,7 +456,6 @@ static int check_map_indirect(struct aut
 	struct mapent_cache *mc;
 	struct mapent *exists;
 	unsigned int map_order;
-	int need_map = 0;
 	int ret = 0;
 
 	source = ap->entry->current;
@@ -465,12 +464,6 @@ static int check_map_indirect(struct aut
 
 	mc = source->mc;
 
-	cache_readlock(mc);
-	exists = cache_lookup_distinct(mc, key);
-	if (exists && exists->mc != mc)
-		exists = NULL;
-	cache_unlock(mc);
-
 	master_source_current_wait(ap->entry);
 	ap->entry->current = source;
 
@@ -490,44 +483,53 @@ static int check_map_indirect(struct aut
 	map_order = get_map_order(ctxt->domainname, ctxt->mapname);
 	if (map_order > ctxt->order) {
 		ctxt->order = map_order;
-		need_map = 1;
+		source->stale = 1;
+	}
+
+	pthread_cleanup_push(cache_lock_cleanup, mc);
+	cache_writelock(mc);
+	exists = cache_lookup_distinct(mc, key);
+	/* Not found in the map but found in the cache */
+	if (exists && exists->source == source && ret & CHE_MISSING) {
+		if (exists->mapent) {
+			free(exists->mapent);
+			exists->mapent = NULL;
+			source->stale = 1;
+			exists->status = 0;
+		}
 	}
+	pthread_cleanup_pop(1);
 
 	if (ret == CHE_MISSING) {
+		struct mapent *we;
 		int wild = CHE_MISSING;
 
 		master_source_current_wait(ap->entry);
 		ap->entry->current = source;
 
 		wild = lookup_wild(ap, ctxt);
-		if (wild == CHE_UPDATED || CHE_OK)
-			return NSS_STATUS_SUCCESS;
-
+		/*
+		 * Check for map change and update as needed for
+		 * following cache lookup.
+		 */
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_writelock(mc);
-		if (wild == CHE_MISSING)
-			cache_delete(mc, "*");
-
-		if (cache_delete(mc, key) && wild & (CHE_MISSING | CHE_FAIL))
-			rmdir_path(ap, key, ap->dev);
+		we = cache_lookup_distinct(mc, "*");
+		if (we) {
+			/* Wildcard entry existed and is now gone */
+			if (we->source == source && (wild & CHE_MISSING)) {
+				cache_delete(mc, "*");
+				source->stale = 1;
+			}
+		} else {
+			/* Wildcard not in map but now is */
+			if (wild & (CHE_OK || CHE_UPDATED))
+				source->stale = 1;
+		}
 		pthread_cleanup_pop(1);
-	}
-
-	/* Have parent update its map if needed */
-	if (ap->ghost && need_map) {
-		int status;
 
-		source->stale = 1;
-
-		status = pthread_mutex_lock(&ap->state_mutex);
-		if (status)
-			fatal(status);
-
-		nextstate(ap->state_pipe[1], ST_READMAP);
-
-		status = pthread_mutex_unlock(&ap->state_mutex);
-		if (status)
-			fatal(status);
+		if (wild & (CHE_OK || CHE_UPDATED))
+			return NSS_STATUS_SUCCESS;
 	}
 
 	if (ret == CHE_MISSING)
@@ -602,7 +604,10 @@ int lookup_mount(struct autofs_point *ap
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	if (me && me->mapent && *me->mapent) {
+	/* Stale mapent => check for wildcard */
+	if (me && !me->mapent)
+		me = cache_lookup_distinct(mc, "*");
+	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
 		strcpy(mapent, me->mapent);
@@ -623,7 +628,7 @@ int lookup_mount(struct autofs_point *ap
 			cache_writelock(mc);
 			me = cache_lookup_distinct(mc, key);
 			if (!me)
-				rv = cache_update(mc, key, NULL, now);
+				rv = cache_update(mc, source, key, NULL, now);
 			if (rv != CHE_FAIL) {
 				me = cache_lookup_distinct(mc, key);
 				me->status = now + NEGATIVE_TIMEOUT;
--- autofs-5.0.1/daemon/direct.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/daemon/direct.c	2007-05-31 13:48:14.000000000 +0800
@@ -526,7 +526,7 @@ int mount_autofs_direct(struct autofs_po
 		return -1;
 
 	/* TODO: check map type */
-	if (lookup_nss_read_map(ap, now))
+	if (lookup_nss_read_map(ap, NULL, now))
 		lookup_prune_cache(ap, now);
 	else {
 		error(ap->logopt, "failed to read direct map");
@@ -1413,7 +1413,7 @@ static void *do_mount_direct(void *arg)
 	}
 
 cont:
-	status = lookup_nss_mount(ap, mt->name, strlen(mt->name));
+	status = lookup_nss_mount(ap, NULL, mt->name, strlen(mt->name));
 	/*
 	 * Direct mounts are always a single mount. If it fails there's
 	 * nothing to undo so just complain
--- autofs-5.0.1/daemon/indirect.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/daemon/indirect.c	2007-05-31 13:48:14.000000000 +0800
@@ -261,7 +261,7 @@ int mount_autofs_indirect(struct autofs_
 		return -1;
 
 	/* TODO: read map, determine map type is OK */
-	if (lookup_nss_read_map(ap, now))
+	if (lookup_nss_read_map(ap, NULL, now))
 		lookup_prune_cache(ap, now);
 	else {
 		error(ap->logopt, "failed to read map for %s", ap->path);
@@ -884,7 +884,7 @@ static void *do_mount_indirect(void *arg
 		free(tsv);
 	}
 cont:
-	status = lookup_nss_mount(ap, mt->name, mt->len);
+	status = lookup_nss_mount(ap, NULL, mt->name, mt->len);
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 	if (status) {
 		send_ready(ap->ioctlfd, mt->wait_queue_token);
--- autofs-5.0.1/daemon/state.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/daemon/state.c	2007-05-31 13:48:14.000000000 +0800
@@ -378,7 +378,7 @@ static void *do_readmap(void *arg)
 
 	pthread_cleanup_push(do_readmap_cleanup, ra);
 
-	status = lookup_nss_read_map(ap, now);
+	status = lookup_nss_read_map(ap, NULL, now);
 	if (!status)
 		pthread_exit(NULL);
 
--- autofs-5.0.1/daemon/lookup.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/daemon/lookup.c	2007-05-31 13:48:14.000000000 +0800
@@ -261,11 +261,16 @@ static int do_read_map(struct autofs_poi
 	if (!ap->ghost && ap->type != LKP_DIRECT)
 		return NSS_STATUS_SUCCESS;
 
+	if (!map->stale)
+		return NSS_STATUS_SUCCESS;
+
 	master_source_current_wait(ap->entry);
 	ap->entry->current = map;
 
 	status = lookup->lookup_read_map(ap, age, lookup->context);
 
+	map->stale = 0;
+
 	/*
 	 * For maps that don't support enumeration return success
 	 * and do whatever we must to have autofs function with an
@@ -302,7 +307,9 @@ static int read_file_source_instance(str
 
 	instance = master_find_source_instance(map, type, format, 0, NULL);
 	if (!instance) {
-		instance = master_add_source_instance(map, type, format, age);
+		int argc = map->argc;
+		const char **argv = map->argv;
+		instance = master_add_source_instance(map, type, format, age, argc, argv);
 		if (!instance)
 			return NSS_STATUS_UNAVAIL;
 		instance->recurse = map->recurse;
@@ -321,7 +328,9 @@ static int read_source_instance(struct a
 
 	instance = master_find_source_instance(map, type, format, 0, NULL);
 	if (!instance) {
-		instance = master_add_source_instance(map, type, format, age);
+		int argc = map->argc;
+		const char **argv = map->argv;
+		instance = master_add_source_instance(map, type, format, age, argc, argv);
 		if (!instance)
 			return NSS_STATUS_UNAVAIL;
 		instance->recurse = map->recurse;
@@ -343,7 +352,6 @@ static enum nsswitch_status read_map_sou
 		struct autofs_point *ap, struct map_source *map, time_t age)
 {
 	enum nsswitch_status result;
-	struct map_source *instance;
 	struct map_source tmap;
 	char *path;
 
@@ -363,15 +371,6 @@ static enum nsswitch_status read_map_sou
 		return NSS_STATUS_NOTFOUND;
 	}
 
-	instance = master_find_source_instance(map,
-				"file", map->format, map->argc, map->argv);
-	if (!instance)
-		instance = master_find_source_instance(map,
-				"program", map->format, map->argc, map->argv);
-
-	if (instance)
-		return read_file_source_instance(ap, map, age);
-
 	this->source[4] = '\0';
 	tmap.type = this->source;
 	tmap.format = map->format;
@@ -412,10 +411,12 @@ static enum nsswitch_status read_map_sou
 	result = read_file_source_instance(ap, &tmap, age);
 	pthread_cleanup_pop(1);
 
+	map->instance = tmap.instance;
+
 	return result;
 }
 
-int lookup_nss_read_map(struct autofs_point *ap, time_t age)
+int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age)
 {
 	struct master_mapent *entry = ap->entry;
 	struct list_head nsslist;
@@ -432,7 +433,10 @@ int lookup_nss_read_map(struct autofs_po
 	 */
 	pthread_cleanup_push(master_source_lock_cleanup, entry);
 	master_source_readlock(entry);
-	map = entry->maps;
+	if (source)
+		map = source;
+	else
+		map = entry->maps;
 	while (map) {
 		/* Is map source up to date or no longer valid */
 		if (!map->stale || entry->age > map->age) {
@@ -647,7 +651,9 @@ static int lookup_name_file_source_insta
 
 	instance = master_find_source_instance(map, type, format, 0, NULL);
 	if (!instance) {
-		instance = master_add_source_instance(map, type, format, age);
+		int argc = map->argc;
+		const char **argv = map->argv;
+		instance = master_add_source_instance(map, type, format, age, argc, argv);
 		if (!instance)
 			return NSS_STATUS_NOTFOUND;
 		instance->recurse = map->recurse;
@@ -667,7 +673,9 @@ static int lookup_name_source_instance(s
 
 	instance = master_find_source_instance(map, type, format, 0, NULL);
 	if (!instance) {
-		instance = master_add_source_instance(map, type, format, age);
+		int argc = map->argc;
+		const char **argv = map->argv;
+		instance = master_add_source_instance(map, type, format, age, argc, argv);
 		if (!instance)
 			return NSS_STATUS_NOTFOUND;
 		instance->recurse = map->recurse;
@@ -682,7 +690,6 @@ static enum nsswitch_status lookup_map_n
 			const char *name, int name_len)
 {
 	enum nsswitch_status result;
-	struct map_source *instance;
 	struct map_source tmap;
 	char *path;
 
@@ -702,13 +709,6 @@ static enum nsswitch_status lookup_map_n
 		return NSS_STATUS_NOTFOUND;
 	}
 
-	instance = master_find_source_instance(map, "file", map->format, 0, NULL);
-	if (!instance)
-		instance = master_find_source_instance(map, "program", map->format, 0, NULL);
-
-	if (instance)
-		return lookup_name_file_source_instance(ap, map, name, name_len);
-
 	this->source[4] = '\0';
 	tmap.type = this->source;
 	tmap.format = map->format;
@@ -746,13 +746,15 @@ static enum nsswitch_status lookup_map_n
 
 	result = lookup_name_file_source_instance(ap, &tmap, name, name_len);
 
+	map->instance = tmap.instance;
+
 	/* path is freed in free_argv */
 	free_argv(tmap.argc, tmap.argv);
 
 	return result;
 }
 
-int lookup_nss_mount(struct autofs_point *ap, const char *name, int name_len)
+int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len)
 {
 	struct master_mapent *entry = ap->entry;
 	struct list_head nsslist;
@@ -769,7 +771,10 @@ int lookup_nss_mount(struct autofs_point
 	 */
 	pthread_cleanup_push(master_source_lock_cleanup, entry);
 	master_source_readlock(entry);
-	map = entry->maps;
+	if (source)
+		map = source;
+	else
+		map = entry->maps;
 	while (map) {
 		/*
 		 * Only consider map sources that have been read since 
@@ -850,11 +855,28 @@ int lookup_nss_mount(struct autofs_point
 
 		map = map->next;
 	}
+	send_map_update_request(ap);
 	pthread_cleanup_pop(1);
 
 	return !result;
 }
 
+static void lookup_close_lookup_instances(struct map_source *map)
+{
+	struct map_source *instance;
+
+	instance = map->instance;
+	while (instance) {
+		lookup_close_lookup_instances(instance);
+		instance = instance->next;
+	}
+
+	if (map->lookup) {
+		close_lookup(map->lookup);
+		map->lookup = NULL;
+	}
+}
+
 void lookup_close_lookup(struct autofs_point *ap)
 {
 	struct map_source *map;
@@ -864,21 +886,7 @@ void lookup_close_lookup(struct autofs_p
 		return;
 
 	while (map) {
-		struct map_source *instance;
-
-		instance = map->instance;
-		while (instance) {
-			if (instance->lookup) {
-				close_lookup(instance->lookup);
-				instance->lookup = NULL;
-			}
-			instance = instance->next;
-		}
-
-		if (map->lookup) {
-			close_lookup(map->lookup);
-			map->lookup = NULL;
-		}
+		lookup_close_lookup_instances(map);
 		map = map->next;
 	}
 	return;
@@ -919,6 +927,7 @@ int lookup_prune_cache(struct autofs_poi
 
 	map = entry->maps;
 	while (map) {
+		/* Is the map stale */
 		if (!map->stale) {
 			map = map->next;
 			continue;
@@ -950,7 +959,7 @@ int lookup_prune_cache(struct autofs_poi
 
 			if (is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
 				debug(ap->logopt,
-				      "prune posponed, %s is mounted", path);
+				      "prune check posponed, %s mounted", path);
 				free(key);
 				free(path);
 				continue;
--- autofs-5.0.1/lib/master.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/lib/master.c	2007-05-31 13:48:14.000000000 +0800
@@ -292,10 +292,8 @@ struct map_source *master_find_map_sourc
 	return source;
 }
 
-void master_free_map_source(struct map_source *source, unsigned int free_cache)
+static void __master_free_map_source(struct map_source *source, unsigned int free_cache)
 {
-	int status;
-
 	if (source->type)
 		free(source->type);
 	if (source->format)
@@ -318,20 +316,12 @@ void master_free_map_source(struct map_s
 	if (source->instance) {
 		struct map_source *instance, *next;
 
-		status = pthread_mutex_lock(&instance_mutex);
-		if (status)
-			fatal(status);
-
 		instance = source->instance;
 		while (instance) {
 			next = instance->next;
-			master_free_map_source(instance, 0);
+			__master_free_map_source(instance, 0);
 			instance = next;
 		}
-
-		status = pthread_mutex_unlock(&instance_mutex);
-		if (status)
-			fatal(status);
 	}
 
 	free(source);
@@ -339,6 +329,21 @@ void master_free_map_source(struct map_s
 	return;
 }
 
+void master_free_map_source(struct map_source *source, unsigned int free_cache)
+{
+	int status;
+
+	status = pthread_mutex_lock(&instance_mutex);
+	if (status)
+		fatal(status);
+
+	__master_free_map_source(source, free_cache);
+
+	status = pthread_mutex_unlock(&instance_mutex);
+	if (status)
+		fatal(status);
+}
+
 struct map_source *master_find_source_instance(struct map_source *source, const char *type, const char *format, int argc, const char **argv)
 {
 	struct map_source *map;
@@ -378,19 +383,15 @@ next:
 }
 
 struct map_source *
-master_add_source_instance(struct map_source *source, const char *type, const char *format, time_t age)
+master_add_source_instance(struct map_source *source, const char *type, const char *format, time_t age, int argc, const char **argv)
 {
 	struct map_source *instance;
 	struct map_source *new;
 	char *ntype, *nformat;
-	const char **tmpargv, *name;
+	const char **tmpargv;
 	int status;
 
-	if (!type)
-		return NULL;
-
-	instance = master_find_source_instance(source,
-			type, format, source->argc, source->argv);
+	instance = master_find_source_instance(source, type, format, argc, argv);
 	if (instance)
 		return instance;
 
@@ -399,12 +400,14 @@ master_add_source_instance(struct map_so
 		return NULL;
 	memset(new, 0, sizeof(struct map_source));
 
-	ntype = strdup(type);
-	if (!ntype) {
-		master_free_map_source(new, 0);
-		return NULL;
+	if (type) {
+		ntype = strdup(type);
+		if (!ntype) {
+			master_free_map_source(new, 0);
+			return NULL;
+		}
+		new->type = ntype;
 	}
-	new->type = ntype;
 
 	if (format) {
 		nformat = strdup(format);
@@ -418,17 +421,16 @@ master_add_source_instance(struct map_so
 	new->age = age;
 	new->master_line = 0;
 	new->mc = source->mc;
+	new->stale = 1;
 
-	tmpargv = copy_argv(source->argc, source->argv);
+	tmpargv = copy_argv(argc, argv);
 	if (!tmpargv) {
 		master_free_map_source(new, 0);
 		return NULL;
 	}
-	new->argc = source->argc;
+	new->argc = argc;
 	new->argv = tmpargv;
 
-	name = new->argv[0];
-
 	status = pthread_mutex_lock(&instance_mutex);
 	if (status)
 		fatal(status);
@@ -451,6 +453,71 @@ master_add_source_instance(struct map_so
 	return new;
 }
 
+static void check_stale_instances(struct map_source *source)
+{
+	struct map_source *map;
+
+	if (!source)
+		return;
+
+	map = source->instance;
+	while (map) {
+		if (map->stale) {
+			source->stale = 1;
+			break;
+		}
+		check_stale_instances(map->instance);
+		map = map->next;
+	}
+
+	return;
+}
+
+void send_map_update_request(struct autofs_point *ap)
+{
+	struct map_source *map;
+	int status, need_update = 0;
+
+	if (!ap->ghost)
+		return;
+
+	status = pthread_mutex_lock(&instance_mutex);
+	if (status)
+		fatal(status);
+
+	map = ap->entry->maps;
+	while (map) {
+		check_stale_instances(map);
+		map = map->next;
+	}
+
+	map = ap->entry->maps;
+	while (map) {
+		if (map->stale) {
+			need_update = 1;
+			break;
+		}
+		map = map->next;
+	}
+
+	status = pthread_mutex_unlock(&instance_mutex);
+	if (status)
+		fatal(status);
+
+	if (!need_update)
+		return;
+
+	status = pthread_mutex_lock(&ap->state_mutex);
+	if (status)
+		fatal(status);
+	nextstate(ap->state_pipe[1], ST_READMAP);
+	status = pthread_mutex_unlock(&ap->state_mutex);
+	if (status)
+		fatal(status);
+
+	return;
+}
+
 void master_source_writelock(struct master_mapent *entry)
 {
 	int status;
--- autofs-5.0.1/lib/master_parse.y.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/lib/master_parse.y	2007-05-31 13:48:14.000000000 +0800
@@ -533,7 +533,7 @@ int master_parse_entry(const char *buffe
 	/* Add null map entries to the null map cache */
 	if (type && !strcmp(type, "null")) {
 		cache_writelock(nc);
-		cache_update(nc, path, NULL, lineno);
+		cache_update(nc, NULL, path, NULL, lineno);
 		cache_unlock(nc);
 		local_free_vars();
 		return 1;
--- autofs-5.0.1/lib/cache.c.map-update-source-only	2007-05-31 13:47:59.000000000 +0800
+++ autofs-5.0.1/lib/cache.c	2007-05-31 13:48:14.000000000 +0800
@@ -509,7 +509,7 @@ struct mapent *cache_partial_match(struc
 }
 
 /* cache must be write locked by caller */
-int cache_add(struct mapent_cache *mc, const char *key, const char *mapent, time_t age)
+int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age)
 {
 	struct mapent *me, *existing = NULL;
 	char *pkey, *pent;
@@ -541,6 +541,7 @@ int cache_add(struct mapent_cache *mc, c
 	me->age = age;
 	me->status = 0;
 	me->mc = mc;
+	me->source = ms;
 	INIT_LIST_HEAD(&me->ino_index);
 	INIT_LIST_HEAD(&me->multi_list);
 	me->multi = NULL;
@@ -618,7 +619,7 @@ int cache_add_offset(struct mapent_cache
 	if (me && me != owner)
 		return CHE_DUPLICATE;
 
-	ret = cache_add(mc, key, mapent, age);
+	ret = cache_add(mc, owner->source, key, mapent, age);
 	if (ret == CHE_FAIL) {
 		warn(LOGOPT_ANY, "failed to add key %s to cache", key);
 		return CHE_FAIL;
@@ -686,7 +687,7 @@ int cache_set_parents(struct mapent *mm)
 }
 
 /* cache must be write locked by caller */
-int cache_update(struct mapent_cache *mc, const char *key, const char *mapent, time_t age)
+int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age)
 {
 	struct mapent *me = NULL;
 	char *pent;
@@ -694,7 +695,7 @@ int cache_update(struct mapent_cache *mc
 
 	me = cache_lookup(mc, key);
 	if (!me || (*me->key == '*' && *key != '*')) {
-		ret = cache_add(mc, key, mapent, age);
+		ret = cache_add(mc, ms, key, mapent, age);
 		if (!ret) {
 			debug(LOGOPT_NONE, "failed for %s", key);
 			return CHE_FAIL;
@@ -705,9 +706,11 @@ int cache_update(struct mapent_cache *mc
 		if (me->age == age)
 			return CHE_OK;
 
-		if (!mapent)
+		if (!mapent) {
+			if (me->mapent)
+				free(me->mapent);
 			me->mapent = NULL;
-		else if (!me->mapent || strcmp(me->mapent, mapent) != 0) {
+		} else if (!me->mapent || strcmp(me->mapent, mapent) != 0) {
 			pent = malloc(strlen(mapent) + 1);
 			if (pent == NULL)
 				return CHE_FAIL;


Index: autofs.spec
===================================================================
RCS file: /cvs/dist/rpms/autofs/FC-6/autofs.spec,v
retrieving revision 1.179
retrieving revision 1.180
diff -u -r1.179 -r1.180
--- autofs.spec	17 Apr 2007 13:04:10 -0000	1.179
+++ autofs.spec	31 May 2007 06:07:48 -0000	1.180
@@ -4,7 +4,7 @@
 Summary: A tool for automatically mounting and unmounting filesystems
 Name: autofs
 %define version 5.0.1
-%define release 0.rc3.29
+%define release 0.rc3.30
 Version: %{version}
 Release: %{release}
 Epoch: 1
@@ -34,6 +34,7 @@
 Patch21: autofs-5.0.1-localfs-label-check.patch
 Patch22: autofs-5.0.1-disable-exports-check.patch
 Patch23: autofs-5.0.1-cmd-global-options-fix.patch
+Patch24: autofs-5.0.1-rc3-map-update-source-only.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
 Conflicts: kernel < 2.6.17
@@ -99,6 +100,7 @@
 %patch21 -p1
 %patch22 -p1
 %patch23 -p1
+%patch24 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -155,6 +157,9 @@
 %{_libdir}/autofs/*
 
 %changelog
+* Thu May 31 2007 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc3.30
+- fix wildcard map handling and improve nsswitch source map re-reading.
+
 * Tue Apr 17 2007 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc3.29
 - upstream fix for filesystem is local check.
 - disable exports access control check (bz 203277).




More information about the fedora-cvs-commits mailing list