rpms/autofs/devel autofs-5.0.0_beta4-map-update.patch, NONE, 1.1 autofs-5.0.0_beta4-program-map-offset-handling.patch, NONE, 1.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Mon Jun 12 07:16:21 UTC 2006


Author: ikent

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

Added Files:
	autofs-5.0.0_beta4-map-update.patch 
	autofs-5.0.0_beta4-program-map-offset-handling.patch 
Log Message:
- didn't add patches.


autofs-5.0.0_beta4-map-update.patch:
 CHANGELOG               |    1 +
 daemon/automount.c      |   44 ++++++++++++++++++++++++++++++++++++++++++--
 daemon/direct.c         |   20 +++++++++++++++++++-
 daemon/lookup.c         |   40 +++++++++++++++++++++++++++++++---------
 daemon/state.c          |    3 ++-
 include/automount.h     |    6 +++++-
 lib/master.c            |   48 +++++++++++++++++++++++++++++++++---------------
 lib/master_parse.y      |   19 ++++++++++++-------
 lib/mounts.c            |   16 +++++++++++++++-
 modules/lookup_file.c   |    2 +-
 modules/mount_autofs.c  |    2 +-
 modules/mount_bind.c    |    2 +-
 modules/mount_ext2.c    |    2 +-
 modules/mount_generic.c |    2 +-
 modules/mount_nfs.c     |    2 +-
 15 files changed, 166 insertions(+), 43 deletions(-)

--- NEW FILE autofs-5.0.0_beta4-map-update.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index f2557bb..a584f4e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,6 +23,7 @@
 - fix memory leak in walk_tree.
 - fix memory leak in rpc_portmap_getport and rpc_ping_proto.
 - fix memory leak in initialisation of lookup modules.
+- fix handling of master map entry update.
 
 2/6/2006 autofs-5.0.0_beta4
 ---------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 827541f..147be1c 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -345,7 +345,7 @@ static int umount_ent(struct autofs_poin
 		 * so that we do not try to call rmdir_path on the
 		 * directory.
 		 */
-		if (!rv && is_mounted(_PATH_MOUNTED, path)) {
+		if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
 			crit(ap->logopt,
 			     "the umount binary reported that %s was "
 			     "unmounted, but there is still something "
@@ -502,6 +502,44 @@ static void check_rm_dirs(struct autofs_
 		rm_unwanted(path, 0, ap->dev);
 }
 
+/* Try to purge cache entries kept around due to existing mounts */
+static void update_map_cache(struct autofs_point *ap, const char *path)
+{
+	struct map_source *map;
+	struct mapent_cache *mc;
+	const char *key;
+
+	if (ap->type == LKP_INDIRECT)
+		key = strrchr(path, '/') + 1;
+	else
+		key = path;
+
+	pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
+	master_source_readlock(ap->entry);
+	map = ap->entry->first;
+	while (map) {
+		struct mapent *me = NULL;
+
+		/* Skip current, in-use cache */
+		if (ap->entry->age <= map->age) {
+			map = map->next;
+			continue;
+		}
+
+		mc = map->mc;
+		cache_writelock(mc);
+		me = cache_lookup_distinct(mc, key);
+		if (me)
+			cache_delete(mc, key);
+		cache_unlock(mc);
+
+		map = map->next;
+	}
+	pthread_cleanup_pop(1);
+
+	return;
+}
+
 /* umount all filesystems mounted under path.  If incl is true, then
    it also tries to umount path itself */
 int umount_multi(struct autofs_point *ap, struct mnt_list *mnts, const char *path, int incl)
@@ -550,8 +588,10 @@ int umount_multi(struct autofs_point *ap
 	}
 
 	/* Delete detritus like unwanted mountpoints and symlinks */
-	if (left == 0)
+	if (left == 0) {
+		update_map_cache(ap, path);
 		check_rm_dirs(ap, path, incl);
+	}
 
 	return left;
 }
diff --git a/daemon/direct.c b/daemon/direct.c
index 817e38b..bfe4dbf 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -451,6 +451,15 @@ int mount_autofs_direct(struct autofs_po
 	master_source_readlock(ap->entry);
 	map = ap->entry->first;
 	while (map) {
+		/*
+		 * Only consider map sources that have been read since
+		 * the map entry was last updated.
+		 */
+		if (ap->entry->age > map->age) {
+			map = map->next;
+			continue;
+		}
+
 		ap->entry->current = map;
 		mc = map->mc;
 		pthread_cleanup_push(cache_lock_cleanup, mc);
@@ -546,7 +555,7 @@ int mount_autofs_offset(struct autofs_po
 	struct stat st;
 	int status, ret;
 
-	if (is_mounted(_PROC_MOUNTS, me->key)) {
+	if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
 		if (ap->state != ST_READMAP)
 			debug(ap->logopt,
 			      "trigger %s already mounted", me->key);
@@ -1191,6 +1200,15 @@ int handle_packet_missing_direct(struct 
 	master_source_readlock(ap->entry);
 	map = ap->entry->first;
 	while (map) {
+		/*
+		 * Only consider map sources that have been read since
+		 * the map entry was last updated.
+		 */
+		if (ap->entry->age > map->age) {
+			map = map->next;
+			continue;
+		}
+
 		mc = map->mc;
 		cache_readlock(mc);
 		me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index a88abdf..4db7cef 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -402,7 +402,8 @@ int lookup_nss_read_map(struct autofs_po
 	master_source_readlock(entry);
 	map = entry->first;
 	while (map) {
-		if (!map->stale) {
+		/* Is map source up to date or no longer valid */
+		if (!map->stale || entry->age > map->age) {
 			map = map->next;
 			continue;
 		}
@@ -484,6 +485,7 @@ done:
 
 int lookup_ghost(struct autofs_point *ap)
 {
+	struct master_mapent *entry = ap->entry;
 	struct map_source *map;
 	struct mapent_cache *mc;
 	struct mapent *me;
@@ -498,10 +500,19 @@ int lookup_ghost(struct autofs_point *ap
 	if (!ap->ghost)
 		return LKP_INDIRECT;
 
-	pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
-	master_source_readlock(ap->entry);
-	map = ap->entry->first;
+	pthread_cleanup_push(master_source_lock_cleanup, entry);
+	master_source_readlock(entry);
+	map = entry->first;
 	while (map) {
+		/*
+		 * Only consider map sources that have been read since 
+		 * the map entry was last updated.
+		 */
+		if (entry->age > map->age) {
+			map = map->next;
+			continue;
+		}
+
 		mc = map->mc;
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_readlock(mc);
@@ -715,6 +726,15 @@ int lookup_nss_mount(struct autofs_point
 	master_source_readlock(entry);
 	map = entry->first;
 	while (map) {
+		/*
+		 * Only consider map sources that have been read since 
+		 * the map entry was last updated.
+		 */
+		if (entry->age > map->age) {
+			map = map->next;
+			continue;
+		}
+
 		sched_yield();
 		entry->current = map;
 		if (map->type) {
@@ -839,16 +859,16 @@ static char *make_fullpath(const char *r
 
 int lookup_prune_cache(struct autofs_point *ap, time_t age)
 {
+	struct master_mapent *entry = ap->entry;
 	struct map_source *map;
 	struct mapent_cache *mc;
 	struct mapent *me, *this;
-	struct master_mapent *entry = ap->entry;
 	char *path;
 	int status = CHE_FAIL;
 
 	master_source_readlock(entry);
 
-	map = ap->entry->first;
+	map = entry->first;
 	while (map) {
 		if (!map->stale) {
 			map = map->next;
@@ -878,7 +898,7 @@ int lookup_prune_cache(struct autofs_poi
 				continue;
 			}
 
-			if (is_mounted(_PATH_MOUNTED, path)) {
+			if (is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
 				debug(ap->logopt,
 				      "prune posponed, %s is mounted", path);
 				free(key);
@@ -904,8 +924,10 @@ int lookup_prune_cache(struct autofs_poi
 			status = cache_delete(mc, key);
 			cache_unlock(mc);
 
-			if (status != CHE_FAIL)
-				rmdir_path(ap, path);
+			if (status != CHE_FAIL) {
+				if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS))
+					rmdir_path(ap, path);
+			}
 
 			if (!next_key) {
 				free(key);
diff --git a/daemon/state.c b/daemon/state.c
index cf2df67..cf9282f 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -370,7 +370,8 @@ static void *do_readmap(void *arg)
 		master_source_readlock(ap->entry);
 		map = ap->entry->first;
 		while (map) {
-			if (!map->stale) {
+			/* Is map source up to date or no longer valid */
+			if (!map->stale || ap->entry->age > map->age) {
 				map = map->next;
 				continue;
 			}
diff --git a/include/automount.h b/include/automount.h
index b01373f..2630722 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -309,6 +309,10 @@ int ncat_path(char *buf, size_t len,
 
 /* mount table utilities */
 
+#define MNTS_ALL	0x0000
+#define MNTS_REAL	0x0001
+#define MNTS_AUTOFS	0x0002
+
 struct mnt_list {
 	char *path;
 	char *fs_type;
@@ -338,7 +342,7 @@ char *make_mnt_name_string(char *path);
 struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
 struct mnt_list *reverse_mnt_list(struct mnt_list *list);
 void free_mnt_list(struct mnt_list *list);
-int is_mounted(const char *table, const char *path);
+int is_mounted(const char *table, const char *path, unsigned int type);
 int has_fstab_option(const char *path, const char *opt);
 char *find_mnt_ino(const char *table, dev_t dev, ino_t ino);
 char *get_offset(const char *prefix, char *offset,
diff --git a/lib/master.c b/lib/master.c
index 167054d..b0c5b58 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -630,24 +630,27 @@ void master_free_mapent_sources(struct m
 			m = n;
 		}
 		entry->maps = NULL;
+		entry->first = NULL;
 	}
 
 	master_source_unlock(entry);
 
-	status = pthread_rwlock_destroy(&entry->source_lock);
-	if (status)
-		fatal(status);
-
 	return;
 }
 
 void master_free_mapent(struct master_mapent *entry)
 {
+	int status;
+
 	if (entry->path)
 		free(entry->path);
 
 	master_free_autofs_point(entry->ap);
 
+	status = pthread_rwlock_destroy(&entry->source_lock);
+	if (status)
+		fatal(status);
+
 	free(entry);
 
 	return;
@@ -926,22 +929,37 @@ static void check_update_map_sources(str
 
 	master_source_writelock(entry);
 
-	source = entry->maps;
 	last = NULL;
+	source = entry->maps;
 	while (source) {
 		if (readall)
 			source->stale = 1;
 
-		/* Map source has gone away */
-		if (source->age < age) {
-			struct map_source *next;
-			if (last)
-				last->next = source->next;
-			next = source->next;
-			master_free_map_source(source, 1);
-			source = next;
-			map_stale = 1;
-			continue;
+		/*
+		 * If a map source is no longer valid and all it's
+		 * entries have expired away we can get rid of it.
+		 */
+		if (entry->age > source->age) {
+			struct mapent *me;
+			cache_readlock(source->mc);
+			me = cache_lookup_first(source->mc);
+			cache_unlock(source->mc);
+			if (!me) {
+				struct map_source *next = source->next;
+
+				if (!last)
+					entry->maps = next;
+				else
+					last->next = next;
+
+				if (entry->first == source)
+					entry->first = next;
+
+				master_free_map_source(source, 1);
+
+				source = next;
+				continue;
+			}
 		} else if (source->type) {
 			if (!strcmp(source->type, "null")) {
 /*				entry->ap->mc = cache_init(entry->ap); */
diff --git a/lib/master_parse.y b/lib/master_parse.y
index 4d8bcf3..54543af 100644
--- a/lib/master_parse.y
+++ b/lib/master_parse.y
@@ -473,8 +473,7 @@ int master_parse_entry(const char *buffe
 		if (!new)
 			return 0;
 		entry = new;
-	} else
-		entry->age = age;
+	}
 
 	if (!entry->ap) {
 		ret = master_add_autofs_point(entry, timeout, logopt, ghost, 0);
@@ -520,14 +519,20 @@ int master_parse_entry(const char *buffe
 		return 0;
 	}
 
-	source->mc = cache_init(source);
 	if (!source->mc) {
-		error(LOGOPT_ANY, "failed to init source cache");
-		if (new)
-			master_free_mapent(new);
-		return 0;
+		source->mc = cache_init(source);
+		if (!source->mc) {
+			error(LOGOPT_ANY, "failed to init source cache");
+			if (new)
+				master_free_mapent(new);
+			return 0;
+		}
 	}
 
+	entry->age = age;
+	entry->first = entry->maps;
+	entry->current = NULL;
+
 	if (new)
 		master_add_mapent(master, entry);
 
diff --git a/lib/mounts.c b/lib/mounts.c
index ef93d1b..b1d5e48 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -255,7 +255,7 @@ void free_mnt_list(struct mnt_list *list
 	}
 }
 
-int is_mounted(const char *table, const char *path)
+int is_mounted(const char *table, const char *path, unsigned int type)
 {
 	struct mntent *mnt;
 	struct mntent mnt_wrk;
@@ -277,6 +277,20 @@ int is_mounted(const char *table, const 
 	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX))) {
 		int len = strlen(mnt->mnt_dir);
 
+		if (type) {
+			unsigned int autofs_fs;
+
+			autofs_fs = !strcmp(mnt->mnt_type, "autofs");
+
+			if (type & MNTS_REAL)
+				if (autofs_fs)
+					continue;
+
+			if (type & MNTS_AUTOFS)
+				if (!autofs_fs)
+					continue;
+		}
+
 		if (pathlen == len && !strncmp(path, mnt->mnt_dir, pathlen)) {
 			ret = 1;
 			break;
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index b9e7701..6e8b5dc 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -442,7 +442,7 @@ static int check_self_include(const char
 static struct autofs_point *
 prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned int inc)
 {
-	struct master_mapent *entry = ap->entry;
+	struct master_mapent *entry;
 	struct map_source *current = ap->entry->current;
 	struct map_source *source;
 	struct autofs_point *iap;
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 370dba6..885280a 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -82,7 +82,7 @@ int mount_mount(struct autofs_point *ap,
 	else
 		sprintf(fullpath, "%s", name);
 
-	if (is_mounted(_PATH_MOUNTED, fullpath)) {
+	if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
 		error(ap->logopt,
 		      MODPREFIX 
 		      "warning: about to mount over %s, continuing",
diff --git a/modules/mount_bind.c b/modules/mount_bind.c
index 8df2cfa..07c3c3b 100644
--- a/modules/mount_bind.c
+++ b/modules/mount_bind.c
@@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap,
 		if (!status)
 			existed = 0;
 
-		if (is_mounted(_PATH_MOUNTED, fullpath)) {
+		if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
 			error(ap->logopt,
 			      MODPREFIX "warning: %s is already mounted",
 			      fullpath);
diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c
index f137291..16effdd 100644
--- a/modules/mount_ext2.c
+++ b/modules/mount_ext2.c
@@ -84,7 +84,7 @@ int mount_mount(struct autofs_point *ap,
 	if (!status)
 		existed = 0;
 
-	if (is_mounted(_PATH_MOUNTED, fullpath)) {
+	if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
 		error(ap->logopt,
 		      MODPREFIX "warning: %s is already mounted", fullpath);
 		return 0;
diff --git a/modules/mount_generic.c b/modules/mount_generic.c
index 059fc7c..290ccc0 100644
--- a/modules/mount_generic.c
+++ b/modules/mount_generic.c
@@ -83,7 +83,7 @@ int mount_mount(struct autofs_point *ap,
 	if (!status)
 		existed = 0;
 
-	if (is_mounted(_PATH_MOUNTED, fullpath)) {
+	if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
 		error(ap->logopt,
 		      MODPREFIX "warning: %s is already mounted", fullpath);
 		return 0;
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 09f431f..e25988d 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -185,7 +185,7 @@ int mount_mount(struct autofs_point *ap,
 		int err;
 		char *loc;
 
-		if (is_mounted(_PATH_MOUNTED, fullpath)) {
+		if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
 			error(ap->logopt,
 			      MODPREFIX
 			      "warning: %s is already mounted", fullpath);

autofs-5.0.0_beta4-program-map-offset-handling.patch:
 CHANGELOG                |    1 +
 modules/lookup_program.c |   22 ++++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

--- NEW FILE autofs-5.0.0_beta4-program-map-offset-handling.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index a584f4e..553b662 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,7 @@
 - fix memory leak in rpc_portmap_getport and rpc_ping_proto.
 - fix memory leak in initialisation of lookup modules.
 - fix handling of master map entry update.
+- fix program map handling of iinvalid multi-mount offsets.
 
 2/6/2006 autofs-5.0.0_beta4
 ---------------------------
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 0f9f205..e20054b 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -117,11 +117,23 @@ int lookup_mount(struct autofs_point *ap
 	int distance;
 	int alloci = 1;
 
-	debug(ap->logopt, MODPREFIX "looking up %s", name);
-
 	/* Catch installed direct offset triggers */
-	me = cache_lookup(mc, name);
-	if (me) {
+	cache_readlock(mc);
+	me = cache_lookup_distinct(mc, name);
+	if (!me) {
+		cache_unlock(mc);
+		/*
+		 * If there's a '/' in the name and the offset is not in
+		 * the cache then it's not a valid path in the mount tree.
+		 */
+		if (strchr(name, '/')) {
+			debug(ap->logopt,
+			      MODPREFIX "offset %s not found", name);
+			return NSS_STATUS_NOTFOUND;
+		}
+	} else {
+		cache_unlock(mc);
+		/* Otherwise we found a valid offset so try mount it */
 		debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent);
 
 		ret = ctxt->parse->parse_mount(ap, name, name_len,
@@ -136,6 +148,8 @@ int lookup_mount(struct autofs_point *ap
 		return NSS_STATUS_UNAVAIL;
 	}
 
+	debug(ap->logopt, MODPREFIX "looking up %s", name);
+
 	/*
 	 * We don't use popen because we don't want to run /bin/sh plus we
 	 * want to send stderr to the syslog, and we don't use spawnl()




More information about the fedora-cvs-commits mailing list