Blob Blame History Raw
autofs-5.1.6 - make external mounts independent of amd_entry

From: Ian Kent <raven@themaw.net>

The external mounts used by amd map entries should not depend
on the amd map entry.

The external mounts list is keyed by the external mount path
and this should be what's used to locate them.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG           |    1 
 daemon/automount.c  |    4 -
 include/mounts.h    |    6 +-
 include/parse_amd.h |    1 
 lib/master.c        |    3 -
 lib/mounts.c        |  114 ++++++++++++++++++++++++++++++----------------------
 modules/parse_amd.c |   14 +++---
 7 files changed, 80 insertions(+), 63 deletions(-)

--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -119,6 +119,7 @@ xx/xx/2018 autofs-5.1.5
 - update list.h.
 - add hashtable implementation.
 - change mountpoint to mp in struct ext_mount.
+- make external mounts independent of amd_entry.
 
 19/12/2017 autofs-5.1.4
 - fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -613,7 +613,7 @@ static int umount_subtree_mounts(struct
 		}
 		list_del(&entry->entries);
 		mounts_mutex_unlock(ap);
-		umount_amd_ext_mount(ap, entry);
+		umount_amd_ext_mount(ap, entry->fs);
 		free_amd_entry(entry);
 	}
 done:
@@ -679,7 +679,7 @@ int umount_multi(struct autofs_point *ap
 		}
 		list_del(&entry->entries);
 		mounts_mutex_unlock(ap);
-		umount_amd_ext_mount(ap, entry);
+		umount_amd_ext_mount(ap, entry->fs);
 		free_amd_entry(entry);
 		return 0;
 	}
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -97,8 +97,8 @@ unsigned int get_kver_minor(void);
 char *make_options_string(char *path, int pipefd,
 			  const char *type, unsigned int flags);
 char *make_mnt_name_string(char *path);
-int ext_mount_add(struct list_head *, const char *, unsigned int);
-int ext_mount_remove(struct list_head *, const char *);
+int ext_mount_add(const char *, const char *);
+int ext_mount_remove(const char *);
 int ext_mount_inuse(const char *);
 struct mnt_list *get_mnt_list(const char *path, int include);
 int unlink_mount_tree(struct autofs_point *ap, const char *mp);
@@ -118,7 +118,7 @@ int try_remount(struct autofs_point *, s
 void set_indirect_mount_tree_catatonic(struct autofs_point *);
 void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *);
 int umount_ent(struct autofs_point *, const char *);
-int umount_amd_ext_mount(struct autofs_point *, struct amd_entry *);
+int umount_amd_ext_mount(struct autofs_point *, const char *);
 int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
 int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
 int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
--- autofs-5.1.4.orig/include/parse_amd.h
+++ autofs-5.1.4/include/parse_amd.h
@@ -66,7 +66,6 @@ struct amd_entry {
 	struct selector *selector;
 	struct list_head list;
 	struct list_head entries;
-	struct list_head ext_mount;
 };
 
 int amd_parse_list(struct autofs_point *,
--- autofs-5.1.4.orig/lib/master.c
+++ autofs-5.1.4/lib/master.c
@@ -154,10 +154,9 @@ void master_free_autofs_point(struct aut
 	while (p != head) {
 		struct amd_entry *entry = list_entry(p, struct amd_entry, entries);
 		p = p->next;
-		if (!list_empty(&entry->ext_mount))
-			ext_mount_remove(&entry->ext_mount, entry->fs);
 		if (!list_empty(&entry->entries))
 			list_del(&entry->entries);
+		ext_mount_remove(entry->fs);
 		free_amd_entry(entry);
 	}
 	mounts_mutex_unlock(ap);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -54,10 +54,10 @@ static size_t maxgrpbuf = 0;
 #define EXT_MOUNTS_HASH_SIZE    50
 
 struct ext_mount {
+	unsigned int ref;
 	char *mp;
-	unsigned int umount;
+	char *umount;
 	struct list_head mount;
-	struct list_head mounts;
 };
 static struct list_head ext_mounts_hash[EXT_MOUNTS_HASH_SIZE];
 static unsigned int ext_mounts_hash_init_done = 0;
@@ -542,7 +542,6 @@ struct amd_entry *new_amd_entry(const st
 	new->path = path;
 	INIT_LIST_HEAD(&new->list);
 	INIT_LIST_HEAD(&new->entries);
-	INIT_LIST_HEAD(&new->ext_mount);
 
 	return new;
 }
@@ -763,7 +762,7 @@ static struct ext_mount *ext_mount_looku
 	return NULL;
 }
 
-int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount)
+int ext_mount_add(const char *path, const char *umount)
 {
 	struct ext_mount *em;
 	u_int32_t hval;
@@ -773,13 +772,7 @@ int ext_mount_add(struct list_head *entr
 
 	em = ext_mount_lookup(path);
 	if (em) {
-		struct list_head *p, *head;
-		head = &em->mounts;
-		list_for_each(p, head) {
-			if (p == entry)
-				goto done;
-		}
-		list_add_tail(entry, &em->mounts);
+		em->ref++;
 		ret = 1;
 		goto done;
 	}
@@ -787,28 +780,34 @@ int ext_mount_add(struct list_head *entr
 	em = malloc(sizeof(struct ext_mount));
 	if (!em)
 		goto done;
+	memset(em, 0, sizeof(*em));
 
 	em->mp = strdup(path);
 	if (!em->mp) {
 		free(em);
 		goto done;
 	}
-	em->umount = umount;
+	if (umount) {
+		em->umount = strdup(umount);
+		if (!em->umount) {
+			free(em->mp);
+			free(em);
+			goto done;
+		}
+	}
+	em->ref = 1;
 	INIT_LIST_HEAD(&em->mount);
-	INIT_LIST_HEAD(&em->mounts);
 
 	hval = hash(path, EXT_MOUNTS_HASH_SIZE);
 	list_add_tail(&em->mount, &ext_mounts_hash[hval]);
 
-	list_add_tail(entry, &em->mounts);
-
 	ret = 1;
 done:
 	pthread_mutex_unlock(&ext_mount_hash_mutex);
 	return ret;
 }
 
-int ext_mount_remove(struct list_head *entry, const char *path)
+int ext_mount_remove(const char *path)
 {
 	struct ext_mount *em;
 	int ret = 0;
@@ -819,18 +818,18 @@ int ext_mount_remove(struct list_head *e
 	if (!em)
 		goto done;
 
-	list_del_init(entry);
-
-	if (!list_empty(&em->mounts))
+	em->ref--;
+	if (em->ref)
 		goto done;
 	else {
 		list_del_init(&em->mount);
-		if (em->umount)
-			ret = 1;
 		if (list_empty(&em->mount)) {
 			free(em->mp);
+			if (em->umount)
+				free(em->umount);
 			free(em);
 		}
+		ret = 1;
 	}
 done:
 	pthread_mutex_unlock(&ext_mount_hash_mutex);
@@ -846,9 +845,7 @@ int ext_mount_inuse(const char *path)
 	em = ext_mount_lookup(path);
 	if (!em)
 		goto done;
-
-	if (!list_empty(&em->mounts))
-		ret = 1;
+	ret = em->ref;
 done:
 	pthread_mutex_unlock(&ext_mount_hash_mutex);
 	return ret;
@@ -2092,29 +2089,49 @@ int umount_ent(struct autofs_point *ap,
 	return rv;
 }
 
-int umount_amd_ext_mount(struct autofs_point *ap, struct amd_entry *entry)
+int umount_amd_ext_mount(struct autofs_point *ap, const char *path)
 {
+	struct ext_mount *em;
+	char *umount = NULL;
+	char *mp;
 	int rv = 1;
 
-	if (entry->umount) {
-		char *prog, *str;
-		char **argv;
-		int argc = -1;
+	pthread_mutex_lock(&ext_mount_hash_mutex);
 
-		str = strdup(entry->umount);
-		if (!str)
+	em = ext_mount_lookup(path);
+	if (!em) {
+		pthread_mutex_unlock(&ext_mount_hash_mutex);
+		goto out;
+	}
+	mp = strdup(em->mp);
+	if (!mp) {
+		pthread_mutex_unlock(&ext_mount_hash_mutex);
+		goto out;
+	}
+	if (em->umount) {
+		umount = strdup(em->umount);
+		if (!umount) {
+			pthread_mutex_unlock(&ext_mount_hash_mutex);
+			free(mp);
 			goto out;
+		}
+	}
+
+	pthread_mutex_unlock(&ext_mount_hash_mutex);
+
+	if (umount) {
+		char *prog;
+		char **argv;
+		int argc = -1;
 
 		prog = NULL;
 		argv = NULL;
 
-		argc = construct_argv(str, &prog, &argv);
-		if (argc == -1) {
-			free(str);
-			goto out;
-		}
+		argc = construct_argv(umount, &prog, &argv);
+		if (argc == -1)
+			goto done;
 
-		if (!ext_mount_remove(&entry->ext_mount, entry->fs)) {
+		if (!ext_mount_remove(mp)) {
 			rv =0;
 			goto out_free;
 		}
@@ -2122,29 +2139,30 @@ int umount_amd_ext_mount(struct autofs_p
 		rv = spawnv(ap->logopt, prog, (const char * const *) argv);
 		if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv)))
 			error(ap->logopt,
-			     "failed to umount program mount at %s", entry->fs);
+			     "failed to umount program mount at %s", mp);
 		else {
 			rv = 0;
-			debug(ap->logopt,
-			      "umounted program mount at %s", entry->fs);
-			rmdir_path(ap, entry->fs, ap->dev);
+			debug(ap->logopt, "umounted program mount at %s", mp);
+			rmdir_path(ap, mp, ap->dev);
 		}
 out_free:
 		free_argv(argc, (const char **) argv);
-		free(str);
 
-		goto out;
+		goto done;
 	}
 
-	if (ext_mount_remove(&entry->ext_mount, entry->fs)) {
-		rv = umount_ent(ap, entry->fs);
+	if (ext_mount_remove(mp)) {
+		rv = umount_ent(ap, mp);
 		if (rv)
 			error(ap->logopt,
-			      "failed to umount external mount %s", entry->fs);
+			      "failed to umount external mount %s", mp);
 		else
-			debug(ap->logopt,
-			      "umounted external mount %s", entry->fs);
+			debug(ap->logopt, "umounted external mount %s", mp);
 	}
+done:
+	if (umount)
+		free(umount);
+	free(mp);
 out:
 	return rv;
 }
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1136,7 +1136,7 @@ symlink:
 
 	if (entry->sublink) {
 		/* failed to complete sublink mount */
-		umount_amd_ext_mount(ap, entry);
+		umount_amd_ext_mount(ap, entry->fs);
 	}
 out:
 	return ret;
@@ -1183,8 +1183,8 @@ static int do_generic_mount(struct autof
 				goto out;
 			umount = 1;
 		}
-		/* We have an external mount */
-		if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) {
+		/* If we have an external mount add it to the list */
+		if (umount && !ext_mount_add(entry->fs, entry->umount)) {
 			umount_ent(ap, entry->fs);
 			error(ap->logopt, MODPREFIX
 			      "error: could not add external mount %s",
@@ -1235,7 +1235,7 @@ static int do_nfs_mount(struct autofs_po
 			umount = 1;
 		}
 		/* We might be using an external mount */
-		if (!ext_mount_add(&entry->ext_mount, entry->fs, umount)) {
+		if (umount && !ext_mount_add(entry->fs, entry->umount)) {
 			umount_ent(ap, entry->fs);
 			error(ap->logopt, MODPREFIX
 			      "error: could not add external mount %s", entry->fs);
@@ -1429,7 +1429,7 @@ static int do_program_mount(struct autof
 		/* An external mount with path entry->fs exists
 		 * so ext_mount_add() won't fail.
 		 */
-		ext_mount_add(&entry->ext_mount, entry->fs, 1);
+		ext_mount_add(entry->fs, entry->umount);
 	} else {
 		rv = mkdir_path(entry->fs, mp_mode);
 		if (rv && errno != EEXIST) {
@@ -1445,7 +1445,7 @@ static int do_program_mount(struct autof
 
 		rv = spawnv(ap->logopt, prog, (const char * const *) argv);
 		if (WIFEXITED(rv) && !WEXITSTATUS(rv)) {
-			if (ext_mount_add(&entry->ext_mount, entry->fs, 1)) {
+			if (ext_mount_add(entry->fs, entry->umount)) {
 				rv = 0;
 				debug(ap->logopt, MODPREFIX
 				     "%s: mounted %s", entry->type, entry->fs);
@@ -1470,7 +1470,7 @@ do_free:
 	if (!rv)
 		goto out;
 
-	if (umount_amd_ext_mount(ap, entry)) {
+	if (umount_amd_ext_mount(ap, entry->fs)) {
 		if (!ext_mount_inuse(entry->fs))
 			rmdir_path(ap, entry->fs, ap->dev);
 		debug(ap->logopt, MODPREFIX