Blame SOURCES/autofs-5.0.9-amd-lookup-add-handling-of-amd-maps-in-the-master-map.patch

306fa1
autofs-5.0.9 - amd lookup add handling of amd maps in the master map
306fa1
306fa1
From: Ian Kent <raven@themaw.net>
306fa1
306fa1
306fa1
---
306fa1
 daemon/automount.c     |   79 +++++++++++++++++++++++++++++++++++++++++++++++-
306fa1
 include/automount.h    |    1 +
306fa1
 include/master.h       |    2 +
306fa1
 lib/master.c           |   44 +++++++++++++++++++++++++++
306fa1
 lib/master_parse.y     |   23 ++++++++++++--
306fa1
 lib/master_tok.l       |    2 +
306fa1
 lib/parse_subs.c       |    1 +
306fa1
 modules/mount_autofs.c |   24 +++++++++++++++
306fa1
 modules/parse_amd.c    |   12 +++++++
306fa1
 9 files changed, 182 insertions(+), 6 deletions(-)
306fa1
306fa1
diff --git a/daemon/automount.c b/daemon/automount.c
306fa1
index fd5a19b..0ba3580 100644
306fa1
--- a/daemon/automount.c
306fa1
+++ b/daemon/automount.c
306fa1
@@ -512,6 +512,9 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
306fa1
 			left++;
306fa1
 		}
306fa1
 		cache_multi_unlock(me->parent);
306fa1
+		if (ap->entry->maps &&
306fa1
+		    (ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD))
306fa1
+			cache_pop_mapent(me);
306fa1
 		pthread_setcancelstate(cur_state, NULL);
306fa1
 	}
306fa1
 
306fa1
@@ -525,13 +528,36 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
306fa1
 	 * it already to ensure it's ok to remove any offset triggers.
306fa1
 	 */
306fa1
 	if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
306fa1
+		struct amd_entry *entry;
306fa1
 		debug(ap->logopt, "unmounting dir = %s", path);
306fa1
 		if (umount_ent(ap, path)) {
306fa1
 			warn(ap->logopt, "could not umount dir %s", path);
306fa1
 			left++;
306fa1
+			goto done;
306fa1
 		}
306fa1
-	}
306fa1
 
306fa1
+		/* Check for an external mount and umount if possible */
306fa1
+		mounts_mutex_lock(ap);
306fa1
+		entry = __master_find_amdmount(ap, path);
306fa1
+		if (!entry) {
306fa1
+			mounts_mutex_unlock(ap);
306fa1
+			goto done;
306fa1
+		}
306fa1
+		list_del(&entry->entries);
306fa1
+		mounts_mutex_unlock(ap);
306fa1
+		if (ext_mount_remove(&entry->ext_mount, entry->fs)) {
306fa1
+			if (umount_ent(ap, entry->fs))
306fa1
+				debug(ap->logopt,
306fa1
+				      "failed to umount external mount %s",
306fa1
+				      entry->fs);
306fa1
+			else
306fa1
+				debug(ap->logopt,
306fa1
+				      "umounted external mount %s",
306fa1
+				      entry->fs);
306fa1
+		}
306fa1
+		free_amd_entry(entry);
306fa1
+	}
306fa1
+done:
306fa1
 	return left;
306fa1
 }
306fa1
 
306fa1
@@ -540,10 +566,55 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
306fa1
 int umount_multi(struct autofs_point *ap, const char *path, int incl)
306fa1
 {
306fa1
 	int is_autofs_fs;
306fa1
+	struct stat st;
306fa1
 	int left;
306fa1
 
306fa1
 	debug(ap->logopt, "path %s incl %d", path, incl);
306fa1
 
306fa1
+	if (lstat(path, &st)) {
306fa1
+		warn(ap->logopt,
306fa1
+		     "failed to stat mount point directory %s", path);
306fa1
+		return 1;
306fa1
+	}
306fa1
+
306fa1
+	/* if this is a symlink we can handle it now */
306fa1
+	if (S_ISLNK(st.st_mode)) {
306fa1
+		struct amd_entry *entry;
306fa1
+		if (st.st_dev != ap->dev) {
306fa1
+			crit(ap->logopt,
306fa1
+			     "symlink %s has the wrong device, "
306fa1
+			     "possible race condition", path);
306fa1
+			return 1;
306fa1
+		}
306fa1
+		debug(ap->logopt, "removing symlink %s", path);
306fa1
+		if (unlink(path)) {
306fa1
+			error(ap->logopt,
306fa1
+			      "failed to remove symlink %s", path);
306fa1
+			return 1;
306fa1
+		}
306fa1
+		/* Check for an external mount and attempt umount if needed */
306fa1
+		mounts_mutex_lock(ap);
306fa1
+		entry = __master_find_amdmount(ap, path);
306fa1
+		if (!entry) {
306fa1
+			mounts_mutex_unlock(ap);
306fa1
+			return 0;
306fa1
+		}
306fa1
+		list_del(&entry->entries);
306fa1
+		mounts_mutex_unlock(ap);
306fa1
+		if (ext_mount_remove(&entry->ext_mount, entry->fs)) {
306fa1
+			if (umount_ent(ap, entry->fs))
306fa1
+				debug(ap->logopt,
306fa1
+				      "failed to umount external mount %s",
306fa1
+				      entry->fs);
306fa1
+			else
306fa1
+				debug(ap->logopt,
306fa1
+				      "umounted external mount %s",
306fa1
+				      entry->fs);
306fa1
+		}
306fa1
+		free_amd_entry(entry);
306fa1
+		return 0;
306fa1
+	}
306fa1
+
306fa1
 	is_autofs_fs = 0;
306fa1
 	if (master_find_submount(ap, path))
306fa1
 		is_autofs_fs = 1;
306fa1
@@ -1475,9 +1546,15 @@ static void handle_mounts_cleanup(void *arg)
306fa1
 		clean = 1;
306fa1
 
306fa1
 	if (submount) {
306fa1
+		struct amd_entry *am;
306fa1
 		/* We are finishing up */
306fa1
 		ap->parent->submnt_count--;
306fa1
 		list_del_init(&ap->mounts);
306fa1
+		am = __master_find_amdmount(ap->parent, ap->path);
306fa1
+		if (am) {
306fa1
+			list_del_init(&am->entries);
306fa1
+			free_amd_entry(am);
306fa1
+		}
306fa1
 	}
306fa1
 
306fa1
 	/* Don't signal the handler if we have already done so */
306fa1
diff --git a/include/automount.h b/include/automount.h
306fa1
index 615efcc..37133fe 100644
306fa1
--- a/include/automount.h
306fa1
+++ b/include/automount.h
306fa1
@@ -510,6 +510,7 @@ struct autofs_point {
306fa1
 	struct autofs_point *parent;	/* Owner of mounts list for submount */
306fa1
 	pthread_mutex_t mounts_mutex;	/* Protect mount lists */
306fa1
 	struct list_head mounts;	/* List of autofs mounts at current level */
306fa1
+	struct list_head amdmounts;	/* List of non submount amd mounts */
306fa1
 	unsigned int submount;		/* Is this a submount */
306fa1
 	unsigned int shutdown;		/* Shutdown notification */
306fa1
 	unsigned int submnt_count;	/* Number of submounts */
306fa1
diff --git a/include/master.h b/include/master.h
306fa1
index 8833ddf..bcc8eeb 100644
306fa1
--- a/include/master.h
306fa1
+++ b/include/master.h
306fa1
@@ -104,6 +104,8 @@ void master_source_current_signal(struct master_mapent *);
306fa1
 struct master_mapent *master_find_mapent(struct master *, const char *);
306fa1
 struct autofs_point *__master_find_submount(struct autofs_point *, const char *);
306fa1
 struct autofs_point *master_find_submount(struct autofs_point *, const char *);
306fa1
+struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *);
306fa1
+struct amd_entry *master_find_amdmount(struct autofs_point *, const char *);
306fa1
 struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
306fa1
 void master_add_mapent(struct master *, struct master_mapent *);
306fa1
 void master_remove_mapent(struct master_mapent *);
306fa1
diff --git a/lib/master.c b/lib/master.c
306fa1
index df4aef6..5e4ab51 100644
306fa1
--- a/lib/master.c
306fa1
+++ b/lib/master.c
306fa1
@@ -120,6 +120,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
306fa1
 	ap->submount = submount;
306fa1
 	INIT_LIST_HEAD(&ap->mounts);
306fa1
 	INIT_LIST_HEAD(&ap->submounts);
306fa1
+	INIT_LIST_HEAD(&ap->amdmounts);
306fa1
 	ap->shutdown = 0;
306fa1
 
306fa1
 	status = pthread_mutex_init(&ap->mounts_mutex, NULL);
306fa1
@@ -136,11 +137,26 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
306fa1
 
306fa1
 void master_free_autofs_point(struct autofs_point *ap)
306fa1
 {
306fa1
+	struct list_head *p, *head;
306fa1
 	int status;
306fa1
 
306fa1
 	if (!ap)
306fa1
 		return;
306fa1
 
306fa1
+	mounts_mutex_lock(ap);
306fa1
+	head = &ap->amdmounts;
306fa1
+	p = head->next;
306fa1
+	while (p != head) {
306fa1
+		struct amd_entry *entry = list_entry(p, struct amd_entry, entries);
306fa1
+		p = p->next;
306fa1
+		if (!list_empty(&entry->ext_mount))
306fa1
+			ext_mount_remove(&entry->ext_mount, entry->fs);
306fa1
+		if (!list_empty(&entry->entries))
306fa1
+			list_del(&entry->entries);
306fa1
+		free(entry);
306fa1
+	}
306fa1
+	mounts_mutex_unlock(ap);
306fa1
+
306fa1
 	status = pthread_mutex_destroy(&ap->mounts_mutex);
306fa1
 	if (status)
306fa1
 		fatal(status);
306fa1
@@ -694,6 +710,34 @@ struct autofs_point *master_find_submount(struct autofs_point *ap, const char *p
306fa1
 	return submount;
306fa1
 }
306fa1
 
306fa1
+struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path)
306fa1
+{
306fa1
+	struct list_head *head, *p;
306fa1
+
306fa1
+	head = &ap->amdmounts;
306fa1
+	list_for_each(p, head) {
306fa1
+		struct amd_entry *entry;
306fa1
+
306fa1
+		entry = list_entry(p, struct amd_entry, entries);
306fa1
+
306fa1
+		if (!strcmp(entry->path, path))
306fa1
+			return entry;
306fa1
+	}
306fa1
+
306fa1
+	return NULL;
306fa1
+}
306fa1
+
306fa1
+struct amd_entry *master_find_amdmount(struct autofs_point *ap, const char *path)
306fa1
+{
306fa1
+	struct amd_entry *entry;
306fa1
+
306fa1
+	mounts_mutex_lock(ap);
306fa1
+	entry = __master_find_amdmount(ap, path);
306fa1
+	mounts_mutex_unlock(ap);
306fa1
+
306fa1
+	return entry;
306fa1
+}
306fa1
+
306fa1
 struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age)
306fa1
 {
306fa1
 	struct master_mapent *entry;
306fa1
diff --git a/lib/master_parse.y b/lib/master_parse.y
306fa1
index 11caf5b..03aedf7 100644
306fa1
--- a/lib/master_parse.y
306fa1
+++ b/lib/master_parse.y
306fa1
@@ -790,12 +790,29 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne
306fa1
 		}
306fa1
 	}
306fa1
 
306fa1
+	if (!format) {
306fa1
+		if (conf_amd_mount_section_exists(path))
306fa1
+			format = strdup("amd");
306fa1
+	}
306fa1
+
306fa1
+	if (format && !strcmp(format, "amd")) {
306fa1
+		unsigned int loglevel = conf_amd_get_log_options();
306fa1
+		if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO)
306fa1
+			logopt = LOGOPT_DEBUG;
306fa1
+		else if (loglevel <= LOG_INFO && loglevel > LOG_ERR)
306fa1
+			logopt = LOGOPT_VERBOSE;
306fa1
+	}
306fa1
+
306fa1
+
306fa1
 	if (timeout < 0) {
306fa1
 		/*
306fa1
-		 * If no timeout is given get the timout from first
306fa1
-		 * map (if it exists).
306fa1
+		 * If no timeout is given get the timout from the
306fa1
+		 * first map (if it exists) or the config for amd
306fa1
+		 * maps.
306fa1
 		 */
306fa1
-		if (entry->maps)
306fa1
+		if (format && !strcmp(format, "amd"))
306fa1
+			timeout = conf_amd_get_dismount_interval(path);
306fa1
+		else if (entry->maps)
306fa1
 			timeout = entry->maps->exp_timeout;
306fa1
 		else
306fa1
 			timeout = default_timeout;
306fa1
diff --git a/lib/master_tok.l b/lib/master_tok.l
306fa1
index a55cc76..d43c1dd 100644
306fa1
--- a/lib/master_tok.l
306fa1
+++ b/lib/master_tok.l
306fa1
@@ -119,7 +119,7 @@ DNNAMESTR2	([[:alnum:]_.\-]+)
306fa1
 INTMAP		(-hosts|-null)
306fa1
 MULTI		((multi)(,(sun|hesiod))?(:{OPTWS}|{WS}))
306fa1
 MULTISEP	([\-]{2}[[:blank:]]+)
306fa1
-MTYPE		((file|program|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?(:{OPTWS}|{WS}))
306fa1
+MTYPE		((file|program|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod|amd))?(:{OPTWS}|{WS}))
306fa1
 
306fa1
 
306fa1
 OPTTOUT		(-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS})
306fa1
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
306fa1
index de5319f..421d18c 100644
306fa1
--- a/lib/parse_subs.c
306fa1
+++ b/lib/parse_subs.c
306fa1
@@ -109,6 +109,7 @@ static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types);
306fa1
 static struct types format_type[] = {
306fa1
 	{ "sun", 3 },
306fa1
 	{ "hesiod", 6 },
306fa1
+	{ "amd", 3},
306fa1
 };
306fa1
 static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types);
306fa1
 
306fa1
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
306fa1
index 61aec70..ab5a8e3 100644
306fa1
--- a/modules/mount_autofs.c
306fa1
+++ b/modules/mount_autofs.c
306fa1
@@ -203,6 +203,30 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
306fa1
 	}
306fa1
 	if (info->map)
306fa1
 		argv[0] = info->map;
306fa1
+	/*
306fa1
+	 * If the parent map format is amd and the format isn't
306fa1
+	 * specified in the map entry set it from the parent map
306fa1
+	 * source.
306fa1
+	 */
306fa1
+	if (!info->format && ap->entry->maps) {
306fa1
+		struct map_source *s = ap->entry->maps;
306fa1
+		/*
306fa1
+		 * For amd maps, if the format and source type aren't
306fa1
+		 * specified try and set them from the parent.
306fa1
+		 */
306fa1
+		if (s->flags & MAP_FLAG_FORMAT_AMD) {
306fa1
+			info->format = strdup("amd");
306fa1
+			if (!info->format)
306fa1
+				warn(ap->logopt, MODPREFIX
306fa1
+				     "failed to set amd map format");
306fa1
+			if (!info->type && s->type) {
306fa1
+				info->type = strdup(s->type);
306fa1
+				if (!info->type)
306fa1
+					warn(ap->logopt, MODPREFIX
306fa1
+					     "failed to set amd map type");
306fa1
+			}
306fa1
+		}
306fa1
+	}
306fa1
 
306fa1
 	if (options) {
306fa1
 		p = options;
306fa1
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
306fa1
index 5d8617e..4322479 100644
306fa1
--- a/modules/parse_amd.c
306fa1
+++ b/modules/parse_amd.c
306fa1
@@ -1563,8 +1563,18 @@ int parse_mount(struct autofs_point *ap, const char *name,
306fa1
 		dequote_entry(ap, this);
306fa1
 
306fa1
 		rv = amd_mount(ap, name, this, source, sv, flags, ctxt);
306fa1
-		if (!rv)
306fa1
+		mounts_mutex_lock(ap);
306fa1
+		if (!rv) {
306fa1
+			/* Add to the parent list of mounts */
306fa1
+			list_add_tail(&this->entries, &ap->amdmounts);
306fa1
+			/* Mounted, leave it on the parent list */
306fa1
+			list_del_init(&this->list);
306fa1
+			mounts_mutex_unlock(ap);
306fa1
 			break;
306fa1
+		}
306fa1
+		/* Not mounted, remove it from the parent list */
306fa1
+		list_del_init(&this->entries);
306fa1
+		mounts_mutex_unlock(ap);
306fa1
 	}
306fa1
 	free_amd_entry(cur_defaults);
306fa1