Blame SOURCES/autofs-5.1.2-set-autofs-mounts-catatonic-at-exit.patch

306fa1
autofs-5.1.2 - set autofs mounts catatonic at exit
306fa1
306fa1
From: Ian Kent <raven@themaw.net>
306fa1
306fa1
Setting direct mounts catatonic at exit doesn't go far enough.
306fa1
306fa1
To avoid possible hang on access of automount managed paths when
306fa1
the daemon has exited all mounted autofs file systems must be set
306fa1
catatonic when the daemon exits.
306fa1
306fa1
Signed-off-by: Ian Kent <raven@themaw.net>
306fa1
---
306fa1
 CHANGELOG          |    1 
306fa1
 daemon/automount.c |    1 
306fa1
 daemon/direct.c    |   17 ++++---------
306fa1
 daemon/indirect.c  |    3 --
306fa1
 include/mounts.h   |    3 +-
306fa1
 lib/mounts.c       |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
306fa1
 6 files changed, 78 insertions(+), 16 deletions(-)
306fa1
306fa1
--- autofs-5.0.7.orig/CHANGELOG
306fa1
+++ autofs-5.0.7/CHANGELOG
306fa1
@@ -214,6 +214,7 @@
306fa1
 - don't return until after master map retry read.
306fa1
 - make lookup_nss_read_master() return nss status.
306fa1
 - make set_direct_mount_catatonic() more general.
306fa1
+- set autofs mounts catatonic at exit.
306fa1
 
306fa1
 25/07/2012 autofs-5.0.7
306fa1
 =======================
306fa1
--- autofs-5.0.7.orig/daemon/automount.c
306fa1
+++ autofs-5.0.7/daemon/automount.c
306fa1
@@ -1732,6 +1732,7 @@ int handle_mounts_exit(struct autofs_poi
306fa1
 	 */
306fa1
 	ret = umount_autofs(ap, NULL, 1);
306fa1
 	if (!ret) {
306fa1
+		set_indirect_mount_tree_catatonic(ap);
306fa1
 		handle_mounts_cleanup(ap);
306fa1
 		return 1;
306fa1
 	}
306fa1
--- autofs-5.0.7.orig/daemon/direct.c
306fa1
+++ autofs-5.0.7/daemon/direct.c
306fa1
@@ -130,20 +130,16 @@ int do_umount_autofs_direct(struct autof
306fa1
 				error(ap->logopt,
306fa1
 				      "ask umount returned busy for %s",
306fa1
 				      me->key);
306fa1
-				if (ap->state != ST_READMAP)
306fa1
-					set_mount_catatonic(ap, me, ioctlfd);
306fa1
 				if (opened)
306fa1
 					ops->close(ap->logopt, ioctlfd);
306fa1
 				return 1;
306fa1
 			} else {
306fa1
 				me->ioctlfd = -1;
306fa1
-				set_mount_catatonic(ap, me, ioctlfd);
306fa1
 				ops->close(ap->logopt, ioctlfd);
306fa1
 				goto force_umount;
306fa1
 			}
306fa1
 		}
306fa1
 		me->ioctlfd = -1;
306fa1
-		set_mount_catatonic(ap, me, ioctlfd);
306fa1
 		ops->close(ap->logopt, ioctlfd);
306fa1
 	} else {
306fa1
 		error(ap->logopt,
306fa1
@@ -173,8 +169,11 @@ int do_umount_autofs_direct(struct autof
306fa1
 			warn(ap->logopt, "mount point %s is in use", me->key);
306fa1
 			if (ap->state == ST_SHUTDOWN_FORCE)
306fa1
 				goto force_umount;
306fa1
-			else
306fa1
+			else {
306fa1
+				if (ap->state != ST_READMAP)
306fa1
+					set_direct_mount_tree_catatonic(ap, me);
306fa1
 				return 0;
306fa1
+			}
306fa1
 			break;
306fa1
 		case ENOTDIR:
306fa1
 			error(ap->logopt, "mount point is not a directory");
306fa1
@@ -238,12 +237,8 @@ int umount_autofs_direct(struct autofs_p
306fa1
 			if (!error)
306fa1
 				goto done;
306fa1
 
306fa1
-			error = set_mount_catatonic(ap, me, me->ioctlfd);
306fa1
-			if (!error)
306fa1
-				goto done;
306fa1
-
306fa1
-			/* We really need to set this, last ditch attempt */
306fa1
-			set_mount_catatonic(ap, me, -1);
306fa1
+			if (ap->state != ST_READMAP)
306fa1
+				set_direct_mount_tree_catatonic(ap, me);
306fa1
 done:
306fa1
 			me = cache_enumerate(mc, me);
306fa1
 		}
306fa1
--- autofs-5.0.7.orig/daemon/indirect.c
306fa1
+++ autofs-5.0.7/daemon/indirect.c
306fa1
@@ -286,9 +286,6 @@ int umount_autofs_indirect(struct autofs
306fa1
 #endif
306fa1
 	}
306fa1
 
306fa1
-	if (ap->shutdown)
306fa1
-		ops->catatonic(ap->logopt, ap->ioctlfd);
306fa1
-
306fa1
 	ops->close(ap->logopt, ap->ioctlfd);
306fa1
 	ap->ioctlfd = -1;
306fa1
 	sched_yield();
306fa1
--- autofs-5.0.7.orig/include/mounts.h
306fa1
+++ autofs-5.0.7/include/mounts.h
306fa1
@@ -114,7 +114,8 @@ void set_tsd_user_vars(unsigned int, uid
306fa1
 const char *mount_type_str(unsigned int);
306fa1
 void notify_mount_result(struct autofs_point *, const char *, time_t, const char *);
306fa1
 int try_remount(struct autofs_point *, struct mapent *, unsigned int);
306fa1
-int set_mount_catatonic(struct autofs_point *, struct mapent *, int);
306fa1
+void set_indirect_mount_tree_catatonic(struct autofs_point *);
306fa1
+void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *);
306fa1
 int umount_ent(struct autofs_point *, const char *);
306fa1
 int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
306fa1
 int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
306fa1
--- autofs-5.0.7.orig/lib/mounts.c
306fa1
+++ autofs-5.0.7/lib/mounts.c
306fa1
@@ -1899,7 +1899,7 @@ int try_remount(struct autofs_point *ap,
306fa1
  * are busy on not, to avoid a hang on access once the daemon has gone
306fa1
  * away.
306fa1
  */
306fa1
-int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd)
306fa1
+static int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd)
306fa1
 {
306fa1
 	struct ioctl_ops *ops = get_ioctl_ops();
306fa1
 	unsigned int opened = 0;
306fa1
@@ -1926,6 +1926,9 @@ int set_mount_catatonic(struct autofs_po
306fa1
 			int err = errno;
306fa1
 			char *estr;
306fa1
 
306fa1
+			if (errno == ENOENT)
306fa1
+				return 0;
306fa1
+
306fa1
 			estr = strerror_r(errno, buf, MAX_ERR_BUF);
306fa1
 			error(ap->logopt,
306fa1
 			      "failed to open ioctlfd for %s, error: %s",
306fa1
@@ -1958,6 +1961,70 @@ int set_mount_catatonic(struct autofs_po
306fa1
 	return 0;
306fa1
 }
306fa1
 
306fa1
+static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
306fa1
+{
306fa1
+	if (!list_empty(&me->multi_list)) {
306fa1
+		struct list_head *head = &me->multi_list;
306fa1
+		struct list_head *p;
306fa1
+
306fa1
+		list_for_each(p, head) {
306fa1
+			struct mapent *this;
306fa1
+
306fa1
+			this = list_entry(p, struct mapent, multi_list);
306fa1
+			set_mount_catatonic(ap, this, this->ioctlfd);
306fa1
+		}
306fa1
+	}
306fa1
+}
306fa1
+
306fa1
+void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
306fa1
+{
306fa1
+	struct master_mapent *entry = ap->entry;
306fa1
+	struct map_source *map;
306fa1
+	struct mapent_cache *mc;
306fa1
+	struct mapent *me;
306fa1
+
306fa1
+	if (!is_mounted(_PROC_MOUNTS, ap->path, MNTS_AUTOFS))
306fa1
+		return;
306fa1
+
306fa1
+	map = entry->maps;
306fa1
+	while (map) {
306fa1
+		mc = map->mc;
306fa1
+		cache_readlock(mc);
306fa1
+		me = cache_enumerate(mc, NULL);
306fa1
+		while (me) {
306fa1
+			/* Skip negative map entries and wildcard entries */
306fa1
+			if (!me->mapent)
306fa1
+				goto next;
306fa1
+
306fa1
+			if (!strcmp(me->key, "*"))
306fa1
+				goto next;
306fa1
+
306fa1
+			/* Only need to set offset mounts catatonic */
306fa1
+			if (me->multi && me->multi == me)
306fa1
+				set_multi_mount_tree_catatonic(ap, me);
306fa1
+next:
306fa1
+			me = cache_enumerate(mc, me);
306fa1
+		}
306fa1
+		cache_unlock(mc);
306fa1
+		map = map->next;
306fa1
+	}
306fa1
+
306fa1
+	/* By the time this function is called ap->ioctlfd will have
306fa1
+	 * been closed so don't try and use it.
306fa1
+	 */
306fa1
+	set_mount_catatonic(ap, NULL, -1);
306fa1
+
306fa1
+	return;
306fa1
+}
306fa1
+
306fa1
+void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
306fa1
+{
306fa1
+	/* Set offset mounts catatonic for this mapent */
306fa1
+	if (me->multi && me->multi == me)
306fa1
+		set_multi_mount_tree_catatonic(ap, me);
306fa1
+	set_mount_catatonic(ap, me, me->ioctlfd);
306fa1
+}
306fa1
+
306fa1
 int umount_ent(struct autofs_point *ap, const char *path)
306fa1
 {
306fa1
 	int rv;