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

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