rpms/autofs/devel autofs-5.0.1-rc1-cthon-expire-nested.patch, NONE, 1.1 autofs.spec, 1.132, 1.133

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Thu Jul 27 08:41:46 UTC 2006


Author: ikent

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

Modified Files:
	autofs.spec 
Added Files:
	autofs-5.0.1-rc1-cthon-expire-nested.patch 
Log Message:
* Thu Jul 27 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.7
- cthon fix expire of various forms of nested mounts.


autofs-5.0.1-rc1-cthon-expire-nested.patch:
 CHANGELOG              |    1 
 daemon/automount.c     |   75 ++++++++++++++++++-------------------------------
 daemon/direct.c        |   46 +++++++++++++++++++-----------
 daemon/indirect.c      |   69 ++++++++++++++++++++++-----------------------
 daemon/lookup.c        |   68 ++++++++++++++++++++++++++++++++++++++++----
 daemon/state.c         |   21 +++----------
 include/automount.h    |   10 +++---
 include/master.h       |    6 +++
 include/state.h        |   28 ++++++++++++++++++
 lib/master.c           |   28 ++++++++++++++----
 lib/mounts.c           |   26 +++++++++++++---
 modules/mount_autofs.c |    2 -
 modules/parse_sun.c    |   38 +++++++++++++++---------
 13 files changed, 268 insertions(+), 150 deletions(-)

--- NEW FILE autofs-5.0.1-rc1-cthon-expire-nested.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index 111c6af..f68e16e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,7 @@
 - cthon fix submount operation broken by above.
 - cthon more parser corrections and attempt to fix multi-mounts
   with various combinations of submounts (still broken).
+- cthon fix expire of various forms of nested mounts.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 8fcf19a..91f4d15 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -550,21 +550,35 @@ int umount_multi(struct autofs_point *ap
 
 	left = 0;
 	list_for_each(p, &list) {
+		struct autofs_point *oap = ap;
+		char *has_opt_direct;
+		int is_autofs;
+
 		mptr = list_entry(p, struct mnt_list, list);
 
-		/* We only want real mounts */
-		if (!strcmp(mptr->fs_type, "autofs"))
+		is_autofs = !strcmp(mptr->fs_type, "autofs");
+		has_opt_direct = strstr(mptr->opts, "direct");
+
+		/* We only want real mounts and top level direct mounts */
+		if (is_autofs && !has_opt_direct)
 			continue;
 
+		if (ap->submount)
+			oap = ap->parent;
+
 		sched_yield();
 
-		if (umount_offsets(ap, mnts, mptr->path))
-			warn(ap->logopt, "could not umount some offsets under %s",
-				mptr->path);
+		if (umount_offsets(oap, mnts, mptr->path))
+			warn(ap->logopt,
+			     "could not umount some offsets under %s",
+			     mptr->path);
+
+		if (is_autofs)
+			continue;
 
 		sched_yield();
 
-		debug(ap->logopt, "unmounting dir = %s", mptr->path);
+		warn(ap->logopt, "unmounting dir = %s", mptr->path);
 
 		if (umount_ent(ap, mptr->path, mptr->fs_type)) {
 			warn(ap->logopt, "could not umount dir %s",
@@ -573,49 +587,16 @@ int umount_multi(struct autofs_point *ap
 		}
 	}
 
-	/* Lastly check for offsets with no root mount */
-	n = scandir(path, &de, 0, alphasort);
-	if (n && n != -1) {
-		char buf[PATH_MAX + 1];
-
-		while (n--) {
-			size_t size;
-			int ret;
+	/* Catch any offsets of indirect mounts with no root mount */
+	if (!left && !tree_is_mounted(mnts, path, MNTS_ALL)) {
+		struct autofs_point *rap = ap;
 
-			sched_yield();
+		if (ap->submount)
+			rap = ap->parent;
 
-			if (strcmp(de[n]->d_name, ".") == 0 ||
-			    strcmp(de[n]->d_name, "..") == 0) {
-				free(de[n]);
-				continue;
-			}
-
-			size = sizeof(buf);
-			ret = cat_path(buf, size, path, de[n]->d_name);
-			if (!ret) {
-				do {
-					free(de[n]);
-				} while (n--);
-				left++;
-				break;
-			}
-
-			if (umount_offsets(ap, mnts, buf)) {
-				warn(ap->logopt,
-				     "could not umount some offsets under %s",
-				     buf);
-				left++;
-			}
-			free(de[n]);
-		}
-		free(de);
-	}
-
-	if (!left && !tree_is_mounted(mnts, path)) {
-		sched_yield();
-		if (umount_offsets(ap, mnts, path)) {
+		if (umount_offsets(rap, mnts, path)) {
 			warn(ap->logopt,
-			      "could not umount some offsets under %s", path);
+			     "could not umount some offsets under %s", path);
 			left++;
 		}
 	}
@@ -1229,7 +1210,7 @@ static void handle_mounts_cleanup(void *
 	umount_autofs(ap, 1);
 
 	if (submount)
-		master_signal_submount(ap);
+		master_signal_submount(ap, MASTER_SUBMNT_JOIN);
 	else
 		master_remove_mapent(ap->entry);
 	master_free_mapent_sources(ap->entry, 1);
diff --git a/daemon/direct.c b/daemon/direct.c
index 89c8db2..f4f60f3 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -125,6 +125,24 @@ int do_umount_autofs_direct(struct autof
 		me->ioctlfd = open(me->key, O_RDONLY);
 
 	if (me->ioctlfd >= 0) {
+		int status = 1;
+
+		rv = ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
+		if (rv) {
+			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+			error(ap->logopt, "ioctl failed: %s", estr);
+			return 1;
+		} else if (!status) {
+			if (ap->state != ST_SHUTDOWN_FORCE) {
+				debug(ap->logopt, "ask umount returned busy");
+				return 1;
+			} else {
+				ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
+				close(me->ioctlfd);
+				me->ioctlfd = -1;
+				goto force_umount;
+			}
+		}
 		ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
 		close(me->ioctlfd);
 		me->ioctlfd = -1;
@@ -136,7 +154,7 @@ int do_umount_autofs_direct(struct autof
 	}
 
 	rv = umount(me->key);
-	if (rv != 0) {
+	if (rv == -1) {
 		switch (errno) {
 		case ENOENT:
 		case EINVAL:
@@ -468,8 +486,12 @@ int umount_autofs_offset(struct autofs_p
 	if (me->ioctlfd >= 0) {
 		int status = 1;
 
-		ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
-		if (!status) {
+		rv = ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
+		if (rv) {
+			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+			error(ap->logopt, "ioctl failed: %s", estr);
+			return 1;
+		} else if (!status) {
 			if (ap->state != ST_SHUTDOWN_FORCE) {
 				debug(ap->logopt, "ask umount returned busy");
 				return 1;
@@ -517,15 +539,7 @@ force_umount:
 		rv = umount2(me->key, MNT_DETACH);
 	} else
 		msg("umounted offset %s", me->key);
-/*
-	if (!rv && me->dir_created) {
-		if  (rmdir(me->key) == -1) {
-			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-			warn(ap->logopt,
-			     "failed to remove dir %s: %s", me->key, estr);
-		}
-	}
-*/
+
 	return rv;
 }
 
@@ -800,25 +814,25 @@ static void kernel_callback_cleanup(void
 	mc = mt->mc;
 
 	if (mt->status) {
+		cache_writelock(mc);
 		send_ready(mt->ioctlfd, mt->wait_queue_token);
 		if (mt->type == NFY_EXPIRE) {
 			close(mt->ioctlfd);
-			cache_writelock(mc);
 			me = cache_lookup_distinct(mc, mt->name);
 			if (me)
 				me->ioctlfd = -1;
-			cache_unlock(mc);
 		}
+		cache_unlock(mc);
 	} else {
+		cache_writelock(mc);
 		send_fail(mt->ioctlfd, mt->wait_queue_token);
 		if (mt->type == NFY_MOUNT) {
 			close(mt->ioctlfd);
-			cache_writelock(mc);
 			me = cache_lookup_distinct(mc, mt->name);
 			if (me)
 				me->ioctlfd = -1;
-			cache_unlock(mc);
 		}
+		cache_unlock(mc);
 	}
 
 	free(mt);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 7bde7ec..737d965 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -289,40 +289,24 @@ int umount_autofs_indirect(struct autofs
 	 * to do it here. If the cache entry isn't found then there aren't
 	 * any offset mounts.
 	 */
-	if (ap->submount) {
-		struct master_mapent *entry = ap->parent->entry;
-		struct map_source *map;
-		struct mapent_cache *mc;
-		struct mapent *me;
-
-		pthread_cleanup_push(master_source_lock_cleanup, entry);
-		master_source_readlock(entry);
-		map = entry->first;
-		while (map) {
-			mc = map->mc;
-			cache_readlock(mc);
-			me = cache_lookup_distinct(mc, ap->path);
-			if (me) {
-				close(me->ioctlfd);
-				me->ioctlfd = -1;
-				cache_unlock(mc);
-				break;
-			}
-			cache_unlock(mc);
-			map = map->next;
-		}
-		pthread_cleanup_pop(1);
-	}
+	if (ap->submount)
+		lookup_source_close_ioctlfd(ap->parent, ap->path);
 
 	/* If we are trying to shutdown make sure we can umount */
-	if (!ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
-		if (!ret)
-			warn(ap->logopt, "mount still busy %s", ap->path);
+	rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret);
+	if (rv) {
+		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+		error(ap->logopt, "ioctl failed: %s", estr);
+		return 1;
+	} else if (!ret) {
+		error(ap->logopt, "ask umount returned busy %s", ap->path);
+		busy = 1;
 	}
 
 	if (ap->ioctlfd >= 0) {
 		ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
 		close(ap->ioctlfd);
+		ap->ioctlfd = -1;
 		close(ap->state_pipe[0]);
 		close(ap->state_pipe[1]);
 		ap->state_pipe[0] = -1;
@@ -340,12 +324,12 @@ int umount_autofs_indirect(struct autofs
 		switch (errno) {
 		case ENOENT:
 		case EINVAL:
-			warn(ap->logopt,
+			error(ap->logopt,
 			      "mount point %s does not exist", ap->path);
 			return 0;
 			break;
 		case EBUSY:
-			warn(ap->logopt,
+			error(ap->logopt,
 			      "mount point %s is in use", ap->path);
 			if (ap->state == ST_SHUTDOWN_FORCE)
 				goto force_umount;
@@ -385,6 +369,7 @@ void *expire_proc_indirect(void *arg)
 	int offsets, submnts, count;
 	int ioctlfd;
 	int status, ret;
+	char buf[MAX_ERR_BUF];
 
 	ea = (struct expire_args *) arg;
 
@@ -470,8 +455,9 @@ void *expire_proc_indirect(void *arg)
 
 		ret = ioctl(ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &now);
 		if (ret < 0 && errno != EAGAIN) {
+			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 			warn(ap->logopt,
-			      "failed to expire mount %s", next->path);
+			     "failed to expire mount %s:", next->path, estr);
 			ea->status = 1;
 			break;
 		}
@@ -479,7 +465,7 @@ void *expire_proc_indirect(void *arg)
 	free_mnt_list(mnts);
 
 	count = offsets = submnts = 0;
-	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
+	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
 	/* Are there any real mounts left */
 	for (next = mnts; next; next = next->next) {
 		if (strcmp(next->fs_type, "autofs"))
@@ -497,10 +483,10 @@ void *expire_proc_indirect(void *arg)
 	 * have some offset mounts with no '/' offset so we need to
 	 * umount them here.
 	 */
-	if (mnts && !ea->status && !count) {
-		int ret;
+	if (mnts) {
+		int ret, tries = (count + submnts + offsets + 2) * 2;
 
-		while (offsets--) {
+		while (tries--) {
 			ret = ioctl(ap->ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &now);
 			if (ret < 0 && errno != EAGAIN) {
 				warn(ap->logopt,
@@ -513,6 +499,21 @@ void *expire_proc_indirect(void *arg)
 	}
 	free_mnt_list(mnts);
 
+	count = offsets = submnts = 0;
+	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
+	/* Are there any real mounts left */
+	for (next = mnts; next; next = next->next) {
+		if (strcmp(next->fs_type, "autofs"))
+			count++;
+		else {
+			if (strstr(next->opts, "indirect"))
+				submnts++;
+			else
+				offsets++;
+		}
+	}
+	free_mnt_list(mnts);
+
 	if (submnts) {
 		debug(ap->logopt,
 		      "%d submounts remaining in %s", submnts, ap->path);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index f0f9718..a8ef518 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -395,6 +395,7 @@ int lookup_nss_read_map(struct autofs_po
 	struct list_head *head, *p;
 	struct nss_source *this;
 	struct map_source *map;
+	enum nsswitch_status status;
 	int result = 0;
 
 	/*
@@ -445,17 +446,16 @@ int lookup_nss_read_map(struct autofs_po
 
 		INIT_LIST_HEAD(&nsslist);
 
-		result = nsswitch_parse(&nsslist);
-		if (result) {
+		status = nsswitch_parse(&nsslist);
+		if (status) {
 			error(ap->logopt,
 			      "can't to read name service switch config.");
+			result = 1;
 			break;
 		}
 
 		head = &nsslist;
 		list_for_each(p, head) {
-			int status;
-
 			this = list_entry(p, struct nss_source, list);
 
 			debug(ap->logopt,
@@ -721,6 +721,7 @@ int lookup_nss_mount(struct autofs_point
 	struct list_head *head, *p;
 	struct nss_source *this;
 	struct map_source *map;
+	enum nsswitch_status status;
 	int result = 0;
 
 	/*
@@ -775,8 +776,8 @@ int lookup_nss_mount(struct autofs_point
 
 		INIT_LIST_HEAD(&nsslist);
 
-		result = nsswitch_parse(&nsslist);
-		if (result) {
+		status = nsswitch_parse(&nsslist);
+		if (status) {
 			error(ap->logopt,
 			      "can't to read name service switch config.");
 			result = 1;
@@ -961,3 +962,58 @@ next:
 	return 1;
 }
 
+/* Return with cache readlock held */
+struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key)
+{
+	struct master_mapent *entry = ap->entry;
+	struct map_source *map;
+	struct mapent_cache *mc;
+	struct mapent *me;
+
+	pthread_cleanup_push(master_source_lock_cleanup, entry);
+	master_source_readlock(entry);
+	map = entry->first;
+	while (map) {
+		mc = map->mc;
+		cache_readlock(mc);
+		me = cache_lookup_distinct(mc, key);
+		if (me)
+			break;
+		cache_unlock(mc);
+		map = map->next;
+	}
+	pthread_cleanup_pop(1);
+
+	return me;
+}
+
+int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key)
+{
+	struct master_mapent *entry = ap->entry;
+	struct map_source *map;
+	struct mapent_cache *mc;
+	struct mapent *me;
+	int ret = 0;
+
+	pthread_cleanup_push(master_source_lock_cleanup, entry);
+	master_source_readlock(entry);
+	map = entry->first;
+	while (map) {
+		mc = map->mc;
+		cache_readlock(mc);
+		me = cache_lookup_distinct(mc, key);
+		if (me) {
+			close(me->ioctlfd);
+			me->ioctlfd = -1;
+			cache_unlock(mc);
+			ret = 1;
+			break;
+		}
+		cache_unlock(mc);
+		map = map->next;
+	}
+	pthread_cleanup_pop(1);
+
+	return ret;
+}
+
diff --git a/daemon/state.c b/daemon/state.c
index e74674a..caeb3e3 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -103,7 +103,6 @@ void expire_cleanup(void *arg)
 	/* Check to see if expire process finished */
 	if (thid == ap->exp_thread) {
 		ap->exp_thread = 0;
-		st_set_thid(ap, 0);
 
 		switch (ap->state) {
 		case ST_EXPIRE:
@@ -174,7 +173,7 @@ static unsigned int st_ready(struct auto
 	ap->state = ST_READY;
 
 	if (ap->submount)
-		master_signal_submount(ap);
+		master_signal_submount(ap, MASTER_SUBMNT_CONTINUE);
 
 	return 1;
 }
@@ -362,7 +361,7 @@ static void *do_readmap(void *arg)
 			while (me) {
 				/* TODO: check return of do_... */
 				if (me->age < now) {
-					if (!tree_is_mounted(mnts, me->key))
+					if (!tree_is_mounted(mnts, me->key, MNTS_REAL))
 						do_umount_autofs_direct(ap, mnts, me);
 					else
                                 		debug(ap->logopt,
@@ -586,18 +585,14 @@ int st_add_task(struct autofs_point *ap,
 
 		state_mutex_unlock(ap);
 
-		status = pthread_mutex_lock(&mutex);
-		if (status)
-			fatal(status);
+		st_mutex_lock();
 
 		signaled = 1;
 		status = pthread_cond_signal(&cond);
 		if (status)
 			fatal(status);
 
-		status = pthread_mutex_unlock(&mutex);
-		if (status)
-			fatal(status);
+		st_mutex_unlock();
 
 		return 1;
 	}
@@ -620,9 +615,7 @@ int st_add_task(struct autofs_point *ap,
 	INIT_LIST_HEAD(&new->list);
 	INIT_LIST_HEAD(&new->pending);
 
-	status = pthread_mutex_lock(&mutex);
-	if (status)
-		fatal(status);
+	st_mutex_lock();
 
 	head = &state_queue;
 
@@ -648,9 +641,7 @@ int st_add_task(struct autofs_point *ap,
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_unlock(&mutex);
-	if (status)
-		fatal(status);
+	st_mutex_unlock();
 
 	return 1;
 }
diff --git a/include/automount.h b/include/automount.h
index a689046..b10cfad 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -224,6 +224,8 @@ int lookup_ghost(struct autofs_point *ap
 int lookup_nss_mount(struct autofs_point *ap, 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_mapent(struct autofs_point *ap, const char *key);
+int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key);
 
 #ifdef MODULE_LOOKUP
 int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context);
@@ -313,9 +315,9 @@ int ncat_path(char *buf, size_t len,
 
 /* mount table utilities */
 
-#define MNTS_ALL	0x0000
-#define MNTS_REAL	0x0001
-#define MNTS_AUTOFS	0x0002
+#define MNTS_ALL	0x0001
+#define MNTS_REAL	0x0002
+#define MNTS_AUTOFS	0x0004
 
 struct mnt_list {
 	char *path;
@@ -356,7 +358,7 @@ void tree_free_mnt_tree(struct mnt_list 
 struct mnt_list *tree_make_mnt_tree(const char *table, const char *path);
 int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
 int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
-int tree_is_mounted(struct mnt_list *mnts, const char *path);
+int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
 
 /* Core automount definitions */
 
diff --git a/include/master.h b/include/master.h
index 57760a6..ada18d4 100644
--- a/include/master.h
+++ b/include/master.h
@@ -20,6 +20,10 @@
 #ifndef MASTER_H
 #define MASTER_H
 
+#define MASTER_SUBMNT_WAIT	0
+#define MASTER_SUBMNT_CONTINUE	1
+#define MASTER_SUBMNT_JOIN	2
+
 struct map_source {
 	char *type;
 	char *format;
@@ -94,7 +98,7 @@ void master_free_mapent(struct master_ma
 struct master *master_new(const char *, unsigned int, unsigned int);
 int master_read_master(struct master *, time_t, int);
 void master_notify_submounts(struct autofs_point *, enum states);
-void master_signal_submount(struct autofs_point *);
+void master_signal_submount(struct autofs_point *, unsigned int);
 void master_notify_state_change(struct master *, int);
 int master_mount_mounts(struct master *, time_t, int);
 int master_list_empty(struct master *);
diff --git a/include/state.h b/include/state.h
index 69355b0..ea4c62a 100644
--- a/include/state.h
+++ b/include/state.h
@@ -59,6 +59,20 @@ struct expire_args {
 	int status;		 /* Return status */
 };
 
+#define expire_args_mutex_lock(ea) \
+do { \
+	int status = pthread_mutex_lock(&ea->mutex); \
+	if (status) \
+		fatal(status); \
+} while (0)
+
+#define expire_args_mutex_unlock(ea) \
+do { \
+	int status = pthread_mutex_unlock(&ea->mutex); \
+	if (status) \
+		fatal(status); \
+} while (0)
+
 struct readmap_args {
 	pthread_mutex_t mutex;
 	pthread_cond_t cond;
@@ -75,4 +89,18 @@ int st_add_task(struct autofs_point *, e
 void st_remove_tasks(struct autofs_point *);
 int st_start_handler(void);
 
+#define st_mutex_lock() \
+do { \
+	int status = pthread_mutex_lock(&mutex); \
+	if (status) \
+		fatal(status); \
+} while (0)
+
+#define st_mutex_unlock() \
+do { \
+	int status = pthread_mutex_unlock(&mutex); \
+	if (status) \
+		fatal(status); \
+} while (0)
+
 #endif
diff --git a/lib/master.c b/lib/master.c
index 6bf21ad..d5e58d2 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -754,15 +754,20 @@ int master_read_master(struct master *ma
 
 static void notify_submounts(struct autofs_point *ap, enum states state)
 {
-	struct list_head *p;
+	struct list_head *head, *p;
 	struct autofs_point *this;
+	pthread_t thid;
 	int status;
 
 	mounts_mutex_lock(ap);
 
-	list_for_each(p, &ap->submounts) {
+	head = &ap->submounts;
+	p = head->next;
+	while (p != head) {
 		this = list_entry(p, struct autofs_point, mounts);
 
+		p = p->next;
+
 		if (!list_empty(&this->submounts))
 			notify_submounts(this, state);
 
@@ -777,11 +782,19 @@ static void notify_submounts(struct auto
 
 		state_mutex_unlock(this);
 
-		ap->mounts_signaled = 0;
-		while (!ap->mounts_signaled) {
+		thid = this->thid;
+		ap->mounts_signaled = MASTER_SUBMNT_WAIT;
+		while (ap->mounts_signaled == MASTER_SUBMNT_WAIT) {
 			status = pthread_cond_wait(&ap->mounts_cond, &ap->mounts_mutex);
 			if (status)
 				fatal(status);
+			if (ap->mounts_signaled == MASTER_SUBMNT_JOIN) {
+				mounts_mutex_unlock(ap);
+				status = pthread_join(thid, NULL);
+				if (status)
+					fatal(status);
+				mounts_mutex_lock(ap);
+			}
 		}
 	}
 
@@ -801,7 +814,7 @@ void master_notify_submounts(struct auto
 	return;
 }
 
-void master_signal_submount(struct autofs_point *ap)
+void master_signal_submount(struct autofs_point *ap, unsigned int join)
 {
 	int status;
 
@@ -810,7 +823,10 @@ void master_signal_submount(struct autof
 
 	mounts_mutex_lock(ap->parent);
 
-	ap->parent->mounts_signaled = 1;
+	if (join)
+		ap->parent->mounts_signaled = 1;
+	else
+		ap->parent->mounts_signaled = 2;
 	status = pthread_cond_signal(&ap->parent->mounts_cond);
 	if (status)
 		fatal(status);
diff --git a/lib/mounts.c b/lib/mounts.c
index dd73f9f..b11c4c7 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -744,7 +744,7 @@ int tree_find_mnt_ents(struct mnt_list *
 	return 0;
 }
 
-int tree_is_mounted(struct mnt_list *mnts, const char *path)
+int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type)
 {
 	struct list_head *p;
 	struct list_head list;
@@ -760,13 +760,27 @@ int tree_is_mounted(struct mnt_list *mnt
 
 		mptr = list_entry(p, struct mnt_list, list);
 
-		/* We only want real mounts */
-		if (!strcmp(mptr->fs_type, "autofs"))
-			continue;
+		if (type) {
+			unsigned int autofs_fs;
 
-		mounted++;
-	}
+			autofs_fs = !strcmp(mptr->fs_type, "autofs");
 
+			if (type & MNTS_REAL) {
+				if (!autofs_fs) {
+					mounted = 1;
+					break;
+				}
+			} else if (type & MNTS_AUTOFS) {
+				if (autofs_fs) {
+					mounted = 1;
+					break;
+				}
+			} else {
+				mounted = 1;
+				break;
+			}
+		}
+	}
 	return mounted;
 }
 
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 95fe00d..9bccdd1 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -201,7 +201,7 @@ int mount_mount(struct autofs_point *ap,
 
 	mounts_mutex_lock(ap);
 
-	if (pthread_create(&thid, &thread_attr, handle_mounts, nap)) {
+	if (pthread_create(&thid, NULL, handle_mounts, nap)) {
 		crit(ap->logopt,
 		     MODPREFIX
 		     "failed to create mount handler thread for %s",
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index c6dffef..6007828 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -839,7 +839,7 @@ static int parse_mapent(const char *ent,
 		l = chunklen(p, check_colon(p));
 		ent = dequote(p, l, logopt);
 		if (!ent) {
-			error(logopt, MODPREFIX "out of memory");
+			warn(logopt, MODPREFIX "null location or out of memory");
 			free(myoptions);
 			free(loc);
 			return 0;
@@ -1056,7 +1056,7 @@ int parse_mount(struct autofs_point *ap,
 			}
 
 			if (!path) {
-				error(ap->logopt, MODPREFIX "out of memory");
+				warn(ap->logopt, MODPREFIX "null path or out of memory");
 				cache_readlock(mc);
 				cache_multi_lock(mc);
 				cache_delete_offset_list(mc, name);
@@ -1174,6 +1174,7 @@ int parse_mount(struct autofs_point *ap,
 		return rv;
 	} else {
 		/* Normal (and non-root multi-mount) entries */
+		struct autofs_point *oap = ap;
 		char *loc;
 		int loclen;
 		int l;
@@ -1185,14 +1186,11 @@ int parse_mount(struct autofs_point *ap,
 			free(options);
 			return 1;
 		}
-/*
-		if (*p == ':')
-			p++;	/* Sun escape for entries starting with / */ /*
-*/
+
 		l = chunklen(p, check_colon(p));
 		loc = dequote(p, l, ap->logopt);
 		if (!loc) {
-			error(ap->logopt, MODPREFIX "out of memory");
+			warn(ap->logopt, MODPREFIX "null location or out of memory");
 			free(options);
 			return 1;
 		}
@@ -1216,7 +1214,8 @@ int parse_mount(struct autofs_point *ap,
 			l = chunklen(p, check_colon(p));
 			ent = dequote(p, l, ap->logopt);
 			if (!ent) {
-				error(ap->logopt, MODPREFIX "out of memory");
+				warn(ap->logopt,
+				     MODPREFIX "null location or out of memory");
 				free(loc);
 				free(options);
 				return 1;
@@ -1277,13 +1276,24 @@ int parse_mount(struct autofs_point *ap,
 		 * If it's a multi-mount insert the triggers
 		 * These are always direct mount triggers so root = ""
 		 */
-		cache_readlock(mc);
-		me = cache_lookup_distinct(mc, name);
-		if (me && me->multi) {
-			char *m_key = me->multi->key;
+		if (ap->submount)
+			oap = ap->parent;
+
+		me = lookup_source_mapent(oap, name);
+		if (me) {
+			char *m_key;
 			int start;
 			char *base, *m_root;
 
+			mc = me->source->mc;
+
+			if (!me->multi) {
+				cache_unlock(mc);
+				return rv;
+			}
+
+			m_key = me->multi->key;
+
 			if (*m_key == '/') {
 				m_root = m_key;
 				start = strlen(m_key);
@@ -1308,14 +1318,14 @@ int parse_mount(struct autofs_point *ap,
 			base = &me->key[start];
 
 			cache_multi_lock(mc);
-			if (!mount_multi_triggers(ap, m_root, me->multi, base)) {
+			if (!mount_multi_triggers(oap, m_root, me->multi, base)) {
 				error(ap->logopt,
 				      MODPREFIX "failed to mount offset triggers");
 				rv = 1;
 			}
 			cache_multi_unlock(mc);
+			cache_unlock(mc);
 		}
-		cache_unlock(mc);
 	}
 	return rv;
 }


Index: autofs.spec
===================================================================
RCS file: /cvs/dist/rpms/autofs/devel/autofs.spec,v
retrieving revision 1.132
retrieving revision 1.133
diff -u -r1.132 -r1.133
--- autofs.spec	24 Jul 2006 13:09:24 -0000	1.132
+++ autofs.spec	27 Jul 2006 08:41:42 -0000	1.133
@@ -4,7 +4,7 @@
 Summary: A tool for automatically mounting and unmounting filesystems.
 Name: autofs
 %define version 5.0.1
-%define release 0.rc1.6
+%define release 0.rc1.7
 Version: %{version}
 Release: %{release}
 Epoch: 1
@@ -23,6 +23,7 @@
 Patch10: autofs-5.0.1-rc1-cthon-host-name-validation.patch
 Patch11: autofs-5.0.1-rc1-cthon-submount-fix.patch
 Patch12: autofs-5.0.1-rc1-cthon-parse-and-submounts.patch
+Patch13: autofs-5.0.1-rc1-cthon-expire-nested.patch
 Buildroot: /var/tmp/autofs-tmp
 BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel
 Prereq: chkconfig
@@ -74,6 +75,7 @@
 %patch10 -p1
 %patch11 -p1
 %patch12 -p1
+%patch13 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -130,7 +132,10 @@
 %{_libdir}/autofs/*
 
 %changelog
-* Thu Jul 24 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.6
+* Thu Jul 27 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.7
+- cthon fix expire of various forms of nested mounts.
+
+* Mon Jul 24 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.6
 - cthon more parser corrections and attempt to fix multi-mounts
   with various combinations of submounts (still not right).
 




More information about the fedora-cvs-commits mailing list