Blame SOURCES/autofs-5.1.6-use-struct-mnt_list-to-track-mounted-mounts.patch

49b67f
autofs-5.1.6 - use struct mnt_list to track mounted mounts
49b67f
49b67f
From: Ian Kent <raven@themaw.net>
49b67f
49b67f
Use struct mnt_list to track mounted mounts so that it's no longer
49b67f
necessary to use the system mount table to get the list of mounted
49b67f
mounts.
49b67f
49b67f
Signed-off-by: Ian Kent <raven@themaw.net>
49b67f
---
49b67f
 CHANGELOG          |    1 
49b67f
 daemon/automount.c |    5 ++
49b67f
 daemon/direct.c    |   19 ++++++++
49b67f
 daemon/indirect.c  |    3 +
49b67f
 include/mounts.h   |   10 ++++
49b67f
 lib/mounts.c       |  125 +++++++++++++++++++++++++++++++++++++++++++++++++----
49b67f
 6 files changed, 154 insertions(+), 9 deletions(-)
49b67f
49b67f
--- autofs-5.1.4.orig/CHANGELOG
49b67f
+++ autofs-5.1.4/CHANGELOG
49b67f
@@ -128,6 +128,7 @@ xx/xx/2018 autofs-5.1.5
49b67f
 - remove force parameter from umount_all().
49b67f
 - fix remount expire.
49b67f
 - fix stale offset directories disable mount.
49b67f
+- use struct mnt_list to track mounted mounts.
49b67f
 
49b67f
 19/12/2017 autofs-5.1.4
49b67f
 - fix spec file url.
49b67f
--- autofs-5.1.4.orig/daemon/automount.c
49b67f
+++ autofs-5.1.4/daemon/automount.c
49b67f
@@ -677,6 +677,9 @@ int umount_multi(struct autofs_point *ap
49b67f
 			mnts_put_mount(mnt);
49b67f
 		}
49b67f
 
49b67f
+		/* Check for mounted mount and remove it if found */
49b67f
+		mnts_remove_mount(path, MNTS_MOUNTED);
49b67f
+
49b67f
 		return 0;
49b67f
 	}
49b67f
 
49b67f
@@ -1719,6 +1722,8 @@ static void handle_mounts_cleanup(void *
49b67f
 
49b67f
 		/* Submount at ap->path belongs to parent submount list. */
49b67f
 		mnts_remove_submount(ap->path);
49b67f
+		/* Also remove from parent mounted list */
49b67f
+		mnts_remove_mount(ap->path, MNTS_MOUNTED);
49b67f
 		mnt = mnts_find_amdmount(ap->path);
49b67f
 		if (mnt) {
49b67f
 			mnts_remove_amdmount(ap->path);
49b67f
--- autofs-5.1.4.orig/daemon/direct.c
49b67f
+++ autofs-5.1.4/daemon/direct.c
49b67f
@@ -606,6 +606,9 @@ force_umount:
49b67f
 	} else
49b67f
 		info(ap->logopt, "umounted offset mount %s", me->key);
49b67f
 
49b67f
+	if (!rv)
49b67f
+		mnts_remove_mount(me->key, MNTS_OFFSET);
49b67f
+
49b67f
 	return rv;
49b67f
 }
49b67f
 
49b67f
@@ -622,6 +625,7 @@ int mount_autofs_offset(struct autofs_po
49b67f
 	const char *map_name = hosts_map_name;
49b67f
 	const char *type;
49b67f
 	char mountpoint[PATH_MAX];
49b67f
+	struct mnt_list *mnt;
49b67f
 
49b67f
 	if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) {
49b67f
 		ret = try_remount(ap, me, t_offset);
49b67f
@@ -635,6 +639,11 @@ int mount_autofs_offset(struct autofs_po
49b67f
 			if (ap->state != ST_READMAP)
49b67f
 				warn(ap->logopt,
49b67f
 				     "trigger %s already mounted", me->key);
49b67f
+			mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET);
49b67f
+			if (!mnt)
49b67f
+				error(ap->logopt,
49b67f
+				      "failed to add offset mount %s to mounted list",
49b67f
+				      me->key);
49b67f
 			return MOUNT_OFFSET_OK;
49b67f
 		}
49b67f
 
49b67f
@@ -757,6 +766,12 @@ int mount_autofs_offset(struct autofs_po
49b67f
 		notify_mount_result(ap, me->key, timeout, str_offset);
49b67f
 	ops->close(ap->logopt, ioctlfd);
49b67f
 
49b67f
+	mnt = mnts_add_mount(ap, mountpoint, MNTS_OFFSET);
49b67f
+	if (!mnt)
49b67f
+		error(ap->logopt,
49b67f
+		      "failed to add offset mount %s to mounted list",
49b67f
+		      mountpoint);
49b67f
+
49b67f
 	debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
49b67f
 
49b67f
 	return MOUNT_OFFSET_OK;
49b67f
@@ -877,6 +892,7 @@ void *expire_proc_direct(void *arg)
49b67f
 				ops->close(ap->logopt, me->ioctlfd);
49b67f
 				me->ioctlfd = -1;
49b67f
 				cache_unlock(me->mc);
49b67f
+				mnts_remove_mount(next->mp, MNTS_MOUNTED);
49b67f
 				pthread_setcancelstate(cur_state, NULL);
49b67f
 				continue;
49b67f
 			}
49b67f
@@ -1238,7 +1254,10 @@ static void *do_mount_direct(void *arg)
49b67f
 		cache_unlock(mt.mc);
49b67f
 		if (close_fd)
49b67f
 			ops->close(ap->logopt, mt.ioctlfd);
49b67f
+
49b67f
 		info(ap->logopt, "mounted %s", mt.name);
49b67f
+
49b67f
+		mnts_set_mounted_mount(ap, mt.name);
49b67f
 	} else {
49b67f
 		/* TODO: get mount return status from lookup_nss_mount */
49b67f
 		ops->send_fail(ap->logopt,
49b67f
--- autofs-5.1.4.orig/daemon/indirect.c
49b67f
+++ autofs-5.1.4/daemon/indirect.c
49b67f
@@ -751,7 +751,10 @@ static void *do_mount_indirect(void *arg
49b67f
 	if (status) {
49b67f
 		ops->send_ready(ap->logopt,
49b67f
 				ap->ioctlfd, mt.wait_queue_token);
49b67f
+
49b67f
 		info(ap->logopt, "mounted %s", buf);
49b67f
+
49b67f
+		mnts_set_mounted_mount(ap, mt.name);
49b67f
 	} else {
49b67f
 		/* TODO: get mount return status from lookup_nss_mount */
49b67f
 		ops->send_fail(ap->logopt,
49b67f
--- autofs-5.1.4.orig/include/mounts.h
49b67f
+++ autofs-5.1.4/include/mounts.h
49b67f
@@ -39,6 +39,7 @@
49b67f
 #define MNTS_DIRECT	0x0010
49b67f
 #define MNTS_OFFSET	0x0020
49b67f
 #define MNTS_AMD_MOUNT	0x0040
49b67f
+#define MNTS_MOUNTED	0x0080
49b67f
 
49b67f
 #define REMOUNT_SUCCESS		0x0000
49b67f
 #define REMOUNT_FAIL		0x0001
49b67f
@@ -60,6 +61,9 @@ struct mnt_list {
49b67f
 	struct hlist_node hash;
49b67f
 	unsigned int ref;
49b67f
 
49b67f
+	/* List of mounts of an autofs_point */
49b67f
+	struct list_head mount;
49b67f
+
49b67f
 	/* List of sub-mounts of an autofs_point */
49b67f
 	struct autofs_point *ap;
49b67f
 	struct list_head submount;
49b67f
@@ -130,7 +134,13 @@ void mnts_put_submount_list(struct list_
49b67f
 struct mnt_list *mnts_find_amdmount(const char *path);
49b67f
 struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry);
49b67f
 void mnts_remove_amdmount(const char *mp);
49b67f
+struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags);
49b67f
+void mnts_remove_mount(const char *mp, unsigned int flags);
49b67f
 struct mnt_list *get_mnt_list(const char *path, int include);
49b67f
+unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
49b67f
+void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
49b67f
+void mnts_put_expire_list(struct list_head *mnts);
49b67f
+void mnts_set_mounted_mount(struct autofs_point *ap, const char *name);
49b67f
 int unlink_mount_tree(struct autofs_point *ap, const char *mp);
49b67f
 void free_mnt_list(struct mnt_list *list);
49b67f
 int is_mounted(const char *mp, unsigned int type);
49b67f
--- autofs-5.1.4.orig/lib/mounts.c
49b67f
+++ autofs-5.1.4/lib/mounts.c
49b67f
@@ -884,6 +884,7 @@ static struct mnt_list *mnts_alloc_mount
49b67f
 
49b67f
 	this->ref = 1;
49b67f
 	INIT_HLIST_NODE(&this->hash);
49b67f
+	INIT_LIST_HEAD(&this->mount);
49b67f
 	INIT_LIST_HEAD(&this->submount);
49b67f
 	INIT_LIST_HEAD(&this->submount_work);
49b67f
 	INIT_LIST_HEAD(&this->amdmount);
49b67f
@@ -1149,6 +1150,90 @@ done:
49b67f
 	mnts_hash_mutex_unlock();
49b67f
 }
49b67f
 
49b67f
+struct mnt_list *mnts_add_mount(struct autofs_point *ap,
49b67f
+				const char *name, unsigned int flags)
49b67f
+{
49b67f
+	struct mnt_list *this;
49b67f
+	char *mp;
49b67f
+
49b67f
+	if (*name == '/') {
49b67f
+		mp = strdup(name);
49b67f
+		if (!mp)
49b67f
+			goto fail;
49b67f
+	} else {
49b67f
+		int len = strlen(ap->path) + strlen(name) + 2;
49b67f
+
49b67f
+		mp = malloc(len);
49b67f
+		if (!mp)
49b67f
+			goto fail;
49b67f
+		strcpy(mp, ap->path);
49b67f
+		strcat(mp, "/");
49b67f
+		strcat(mp, name);
49b67f
+	}
49b67f
+
49b67f
+	mnts_hash_mutex_lock();
49b67f
+	this = mnts_get_mount(mp);
49b67f
+	if (this) {
49b67f
+		this->flags |= flags;
49b67f
+		if (list_empty(&this->mount))
49b67f
+			list_add(&this->mount, &ap->mounts);
49b67f
+	}
49b67f
+	mnts_hash_mutex_unlock();
49b67f
+	free(mp);
49b67f
+
49b67f
+	return this;
49b67f
+fail:
49b67f
+	if (mp)
49b67f
+		free(mp);
49b67f
+	return NULL;
49b67f
+}
49b67f
+
49b67f
+void mnts_remove_mount(const char *mp, unsigned int flags)
49b67f
+{
49b67f
+	struct mnt_list *this;
49b67f
+
49b67f
+	mnts_hash_mutex_lock();
49b67f
+	this = mnts_lookup(mp);
49b67f
+	if (this && this->flags & flags) {
49b67f
+		this->flags &= ~flags;
49b67f
+		if (!(this->flags & (MNTS_OFFSET|MNTS_MOUNTED)))
49b67f
+			list_del_init(&this->mount);
49b67f
+		__mnts_put_mount(this);
49b67f
+	}
49b67f
+	mnts_hash_mutex_unlock();
49b67f
+}
49b67f
+
49b67f
+void mnts_set_mounted_mount(struct autofs_point *ap, const char *name)
49b67f
+{
49b67f
+	struct mnt_list *mnt;
49b67f
+
49b67f
+	mnt = mnts_add_mount(ap, name, MNTS_MOUNTED);
49b67f
+	if (!mnt) {
49b67f
+		error(ap->logopt,
49b67f
+		      "failed to add mount %s to mounted list", name);
49b67f
+		return;
49b67f
+	}
49b67f
+
49b67f
+	/* Offset mount failed but non-strict returns success */
49b67f
+	if (mnt->flags & MNTS_OFFSET &&
49b67f
+	    !is_mounted(mnt->mp, MNTS_REAL)) {
49b67f
+		mnt->flags &= ~MNTS_MOUNTED;
49b67f
+		mnts_put_mount(mnt);
49b67f
+	}
49b67f
+
49b67f
+	/* Housekeeping.
49b67f
+	 * Set the base type of the mounted mount.
49b67f
+	 * MNTS_AUTOFS and MNTS_OFFSET are set at mount time and
49b67f
+	 * are used during expire.
49b67f
+	 */
49b67f
+	if (!(mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET))) {
49b67f
+		if (ap->type == LKP_INDIRECT)
49b67f
+			mnt->flags |= MNTS_INDIRECT;
49b67f
+		else
49b67f
+			mnt->flags |= MNTS_DIRECT;
49b67f
+	}
49b67f
+}
49b67f
+
49b67f
 /* From glibc decode_name() */
49b67f
 /* Since the values in a line are separated by spaces, a name cannot
49b67f
  * contain a space.  Therefore some programs encode spaces in names
49b67f
@@ -1962,7 +2047,8 @@ void notify_mount_result(struct autofs_p
49b67f
 	return;
49b67f
 }
49b67f
 
49b67f
-static int do_remount_direct(struct autofs_point *ap, int fd, const char *path)
49b67f
+static int do_remount_direct(struct autofs_point *ap,
49b67f
+			     const unsigned int type, int fd, const char *path)
49b67f
 {
49b67f
 	struct ioctl_ops *ops = get_ioctl_ops();
49b67f
 	int status = REMOUNT_SUCCESS;
49b67f
@@ -1975,9 +2061,21 @@ static int do_remount_direct(struct auto
49b67f
 		set_tsd_user_vars(ap->logopt, uid, gid);
49b67f
 
49b67f
 	ret = lookup_nss_mount(ap, NULL, path, strlen(path));
49b67f
-	if (ret)
49b67f
+	if (ret) {
49b67f
+		struct mnt_list *mnt;
49b67f
+
49b67f
+		/* If it's an offset mount add a mount reference */
49b67f
+		if (type == t_offset) {
49b67f
+			mnt = mnts_add_mount(ap, path, MNTS_OFFSET);
49b67f
+			if (!mnt)
49b67f
+				error(ap->logopt,
49b67f
+				      "failed to add mount %s to mounted list", path);
49b67f
+		}
49b67f
+
49b67f
+		mnts_set_mounted_mount(ap, path);
49b67f
+
49b67f
 		info(ap->logopt, "re-connected to %s", path);
49b67f
-	else {
49b67f
+	} else {
49b67f
 		status = REMOUNT_FAIL;
49b67f
 		info(ap->logopt, "failed to re-connect %s", path);
49b67f
 	}
49b67f
@@ -1985,7 +2083,7 @@ static int do_remount_direct(struct auto
49b67f
 	return status;
49b67f
 }
49b67f
 
49b67f
-static int do_remount_indirect(struct autofs_point *ap, int fd, const char *path)
49b67f
+static int do_remount_indirect(struct autofs_point *ap, const unsigned int type, int fd, const char *path)
49b67f
 {
49b67f
 	struct ioctl_ops *ops = get_ioctl_ops();
49b67f
 	int status = REMOUNT_SUCCESS;
49b67f
@@ -2046,9 +2144,11 @@ static int do_remount_indirect(struct au
49b67f
 		len = strlen(de[n]->d_name);
49b67f
 
49b67f
 		ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len);
49b67f
-		if (ret)
49b67f
+		if (ret) {
49b67f
+			mnts_set_mounted_mount(ap, buf);
49b67f
+
49b67f
 			info(ap->logopt, "re-connected to %s", buf);
49b67f
-		else {
49b67f
+		} else {
49b67f
 			status = REMOUNT_FAIL;
49b67f
 			info(ap->logopt, "failed to re-connect %s", buf);
49b67f
 		}
49b67f
@@ -2149,9 +2249,9 @@ static int remount_active_mount(struct a
49b67f
 		 * following will be broken?
49b67f
 		 */
49b67f
 		if (type == t_indirect)
49b67f
-			do_remount_indirect(ap, fd, path);
49b67f
+			do_remount_indirect(ap, type, fd, path);
49b67f
 		else
49b67f
-			do_remount_direct(ap, fd, path);
49b67f
+			do_remount_direct(ap, type, fd, path);
49b67f
 	}
49b67f
 
49b67f
 	debug(ap->logopt, "re-connected to mount %s", path);
49b67f
@@ -2389,7 +2489,7 @@ int umount_ent(struct autofs_point *ap,
49b67f
 		 * so that we do not try to call rmdir_path on the
49b67f
 		 * directory.
49b67f
 		 */
49b67f
-		if (!rv && is_mounted(path, MNTS_REAL)) {
49b67f
+		if (is_mounted(path, MNTS_REAL)) {
49b67f
 			crit(ap->logopt,
49b67f
 			     "the umount binary reported that %s was "
49b67f
 			     "unmounted, but there is still something "
49b67f
@@ -2398,6 +2498,10 @@ int umount_ent(struct autofs_point *ap,
49b67f
 		}
49b67f
 	}
49b67f
 
49b67f
+	/* On success, check for mounted mount and remove it if found */
49b67f
+	if (!rv)
49b67f
+		mnts_remove_mount(path, MNTS_MOUNTED);
49b67f
+
49b67f
 	return rv;
49b67f
 }
49b67f
 
49b67f
@@ -2690,6 +2794,9 @@ int umount_multi_triggers(struct autofs_
49b67f
 		status = cache_delete_offset_list(mc, me->key);
49b67f
 		if (status != CHE_OK)
49b67f
 			warn(ap->logopt, "couldn't delete offset list");
49b67f
+
49b67f
+	       /* check for mounted mount entry and remove it if found */
49b67f
+               mnts_remove_mount(root, MNTS_MOUNTED);
49b67f
 	}
49b67f
 
49b67f
 	return left;