Blame SOURCES/autofs-5.1.2-make-set_direct_mount_catatonic-more-general.patch

4d476f
autofs-5.1.2 - make set_direct_mount_catatonic() more general
4d476f
4d476f
From: Ian Kent <raven@themaw.net>
4d476f
4d476f
Setting direct mounts catatonic at exit doesn't go far enough.
4d476f
4d476f
To avoid possible hang on access of automount managed paths when
4d476f
the daemon has exited all mounted autofs file systems must be set
4d476f
catatonic when the daemon exits.
4d476f
4d476f
Start by making set_direct_mount_catatonic() able to handle the
4d476f
different types of autofs mounts and move it to the mounts function
4d476f
library.
4d476f
---
4d476f
 CHANGELOG        |    1 
4d476f
 daemon/direct.c  |   69 +++----------------------------------------------------
4d476f
 include/mounts.h |    1 
4d476f
 lib/mounts.c     |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++
4d476f
 4 files changed, 71 insertions(+), 64 deletions(-)
4d476f
4d476f
--- autofs-5.0.7.orig/CHANGELOG
4d476f
+++ autofs-5.0.7/CHANGELOG
4d476f
@@ -213,6 +213,7 @@
4d476f
 - set sane default master read wait timeout.
4d476f
 - don't return until after master map retry read.
4d476f
 - make lookup_nss_read_master() return nss status.
4d476f
+- make set_direct_mount_catatonic() more general.
4d476f
 
4d476f
 25/07/2012 autofs-5.0.7
4d476f
 =======================
4d476f
--- autofs-5.0.7.orig/daemon/direct.c
4d476f
+++ autofs-5.0.7/daemon/direct.c
4d476f
@@ -82,65 +82,6 @@ static void mnts_cleanup(void *arg)
4d476f
 	return;
4d476f
 }
4d476f
 
4d476f
-/* When exiting direct mount triggers must be set catatonic, regardless
4d476f
- * of whether they are busy on not, to avoid a hang on access once the
4d476f
- * daemon has gone away.
4d476f
- */
4d476f
-static int set_direct_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd)
4d476f
-{
4d476f
-	struct ioctl_ops *ops = get_ioctl_ops();
4d476f
-	unsigned int opened = 0;
4d476f
-	char buf[MAX_ERR_BUF];
4d476f
-	int fd = -1;
4d476f
-	int error;
4d476f
-
4d476f
-	/* In case the miscellaneous device isn't being used try
4d476f
-	 * and use an existing ioctl control fd. In this case if
4d476f
-	 * we don't already have an ioctl fd the mount can't be
4d476f
-	 * set catatonic if it's covered.
4d476f
-	 */
4d476f
-	if (ioctlfd >= 0)
4d476f
-		fd = ioctlfd;
4d476f
-	else if (me->ioctlfd >= 0)
4d476f
-		fd = me->ioctlfd;
4d476f
-	else {
4d476f
-		error = ops->open(ap->logopt, &fd, me->dev, me->key);
4d476f
-		if (error == -1) {
4d476f
-			int err = errno;
4d476f
-			char *estr;
4d476f
-
4d476f
-			estr = strerror_r(errno, buf, MAX_ERR_BUF);
4d476f
-			error(ap->logopt,
4d476f
-			      "failed to open ioctlfd for %s, error: %s",
4d476f
-			      me->key, estr);
4d476f
-			return err;
4d476f
-		}
4d476f
-		opened = 1;
4d476f
-	}
4d476f
-
4d476f
-	if (fd >= 0) {
4d476f
-		error = ops->catatonic(ap->logopt, fd);
4d476f
-		if (error == -1) {
4d476f
-			int err = errno;
4d476f
-			char *estr;
4d476f
-
4d476f
-			estr = strerror_r(errno, buf, MAX_ERR_BUF);
4d476f
-			error(ap->logopt,
4d476f
-			      "failed to set %s catatonic, error: %s",
4d476f
-			      me->key, estr);
4d476f
-			if (opened)
4d476f
-				ops->close(ap->logopt, fd);
4d476f
-			return err;
4d476f
-		}
4d476f
-		if (opened)
4d476f
-			ops->close(ap->logopt, fd);
4d476f
-	}
4d476f
-
4d476f
-	debug(ap->logopt, "set %s catatonic", me->key);
4d476f
-
4d476f
-	return 0;
4d476f
-}
4d476f
-
4d476f
 int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
4d476f
 {
4d476f
 	struct ioctl_ops *ops = get_ioctl_ops();
4d476f
@@ -190,19 +131,19 @@ int do_umount_autofs_direct(struct autof
4d476f
 				      "ask umount returned busy for %s",
4d476f
 				      me->key);
4d476f
 				if (ap->state != ST_READMAP)
4d476f
-					set_direct_mount_catatonic(ap, me, ioctlfd);
4d476f
+					set_mount_catatonic(ap, me, ioctlfd);
4d476f
 				if (opened)
4d476f
 					ops->close(ap->logopt, ioctlfd);
4d476f
 				return 1;
4d476f
 			} else {
4d476f
 				me->ioctlfd = -1;
4d476f
-				set_direct_mount_catatonic(ap, me, ioctlfd);
4d476f
+				set_mount_catatonic(ap, me, ioctlfd);
4d476f
 				ops->close(ap->logopt, ioctlfd);
4d476f
 				goto force_umount;
4d476f
 			}
4d476f
 		}
4d476f
 		me->ioctlfd = -1;
4d476f
-		set_direct_mount_catatonic(ap, me, ioctlfd);
4d476f
+		set_mount_catatonic(ap, me, ioctlfd);
4d476f
 		ops->close(ap->logopt, ioctlfd);
4d476f
 	} else {
4d476f
 		error(ap->logopt,
4d476f
@@ -297,12 +238,12 @@ int umount_autofs_direct(struct autofs_p
4d476f
 			if (!error)
4d476f
 				goto done;
4d476f
 
4d476f
-			error = set_direct_mount_catatonic(ap, me, me->ioctlfd);
4d476f
+			error = set_mount_catatonic(ap, me, me->ioctlfd);
4d476f
 			if (!error)
4d476f
 				goto done;
4d476f
 
4d476f
 			/* We really need to set this, last ditch attempt */
4d476f
-			set_direct_mount_catatonic(ap, me, -1);
4d476f
+			set_mount_catatonic(ap, me, -1);
4d476f
 done:
4d476f
 			me = cache_enumerate(mc, me);
4d476f
 		}
4d476f
--- autofs-5.0.7.orig/include/mounts.h
4d476f
+++ autofs-5.0.7/include/mounts.h
4d476f
@@ -114,6 +114,7 @@ void set_tsd_user_vars(unsigned int, uid
4d476f
 const char *mount_type_str(unsigned int);
4d476f
 void notify_mount_result(struct autofs_point *, const char *, time_t, const char *);
4d476f
 int try_remount(struct autofs_point *, struct mapent *, unsigned int);
4d476f
+int set_mount_catatonic(struct autofs_point *, struct mapent *, int);
4d476f
 int umount_ent(struct autofs_point *, const char *);
4d476f
 int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
4d476f
 int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
4d476f
--- autofs-5.0.7.orig/lib/mounts.c
4d476f
+++ autofs-5.0.7/lib/mounts.c
4d476f
@@ -1894,6 +1894,70 @@ int try_remount(struct autofs_point *ap,
4d476f
 	return 0;
4d476f
 }
4d476f
 
4d476f
+/*
4d476f
+ * When exiting mounts need be set catatonic, regardless of whether they
4d476f
+ * are busy on not, to avoid a hang on access once the daemon has gone
4d476f
+ * away.
4d476f
+ */
4d476f
+int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd)
4d476f
+{
4d476f
+	struct ioctl_ops *ops = get_ioctl_ops();
4d476f
+	unsigned int opened = 0;
4d476f
+	char buf[MAX_ERR_BUF];
4d476f
+	char *path;
4d476f
+	int fd = -1;
4d476f
+	int error;
4d476f
+	dev_t dev;
4d476f
+
4d476f
+	path = ap->path;
4d476f
+	dev = ap->dev;
4d476f
+	if (me && (ap->type == LKP_DIRECT || *me->key == '/')) {
4d476f
+		path = me->key;
4d476f
+		dev = me->dev;
4d476f
+	}
4d476f
+
4d476f
+	if (ioctlfd >= 0)
4d476f
+		fd = ioctlfd;
4d476f
+	else if (me && me->ioctlfd >= 0)
4d476f
+		fd = me->ioctlfd;
4d476f
+	else {
4d476f
+		error = ops->open(ap->logopt, &fd, dev, path);
4d476f
+		if (error == -1) {
4d476f
+			int err = errno;
4d476f
+			char *estr;
4d476f
+
4d476f
+			estr = strerror_r(errno, buf, MAX_ERR_BUF);
4d476f
+			error(ap->logopt,
4d476f
+			      "failed to open ioctlfd for %s, error: %s",
4d476f
+			      path, estr);
4d476f
+			return err;
4d476f
+		}
4d476f
+		opened = 1;
4d476f
+	}
4d476f
+
4d476f
+	if (fd >= 0) {
4d476f
+		error = ops->catatonic(ap->logopt, fd);
4d476f
+		if (error == -1) {
4d476f
+			int err = errno;
4d476f
+			char *estr;
4d476f
+
4d476f
+			estr = strerror_r(errno, buf, MAX_ERR_BUF);
4d476f
+			error(ap->logopt,
4d476f
+			      "failed to set %s catatonic, error: %s",
4d476f
+			      path, estr);
4d476f
+			if (opened)
4d476f
+				ops->close(ap->logopt, fd);
4d476f
+			return err;
4d476f
+		}
4d476f
+		if (opened)
4d476f
+			ops->close(ap->logopt, fd);
4d476f
+	}
4d476f
+
4d476f
+	debug(ap->logopt, "set %s catatonic", path);
4d476f
+
4d476f
+	return 0;
4d476f
+}
4d476f
+
4d476f
 int umount_ent(struct autofs_point *ap, const char *path)
4d476f
 {
4d476f
 	int rv;