Blame SOURCES/autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch

4d476f
autofs-5.1.1 - fix handle_mounts() termination condition check
4d476f
4d476f
From: Ian Kent <raven@themaw.net>
4d476f
4d476f
In get_pkt(), if a kernel request is present on the kernel pipe and
4d476f
the autofs mount point state changes to ST_SHUTDOWN after the poll(2)
4d476f
check but before the request has been processed the handle_mounts()
4d476f
thread will exit without shutting down the autofs mount point.
4d476f
4d476f
So change the handle_mounts() exit condition check to take account
4d476f
of this case.
4d476f
4d476f
Signed-off-by: Ian Kent <raven@themaw.net>
4d476f
---
4d476f
 CHANGELOG          |    1 
4d476f
 daemon/automount.c |  191 ++++++++++++++++++++++++++++-------------------------
4d476f
 2 files changed, 105 insertions(+), 87 deletions(-)
4d476f
4d476f
--- autofs-5.0.7.orig/CHANGELOG
4d476f
+++ autofs-5.0.7/CHANGELOG
4d476f
@@ -189,6 +189,7 @@
4d476f
 - always set direct mounts catatonic at exit.
4d476f
 - log pipe read errors.
4d476f
 - fix rwlock unlock crash.
4d476f
+- fix handle_mounts() termination condition check.
4d476f
 
4d476f
 25/07/2012 autofs-5.0.7
4d476f
 =======================
4d476f
--- autofs-5.0.7.orig/daemon/automount.c
4d476f
+++ autofs-5.0.7/daemon/automount.c
4d476f
@@ -1659,6 +1659,99 @@ static void submount_source_unlock_neste
4d476f
 	master_source_unlock(parent->entry);
4d476f
 }
4d476f
 
4d476f
+int handle_mounts_exit(struct autofs_point *ap)
4d476f
+{
4d476f
+	int ret, cur_state;
4d476f
+
4d476f
+	/*
4d476f
+	 * If we're a submount we need to ensure our parent
4d476f
+	 * doesn't try to mount us again until our shutdown
4d476f
+	 * is complete and that any outstanding mounts are
4d476f
+	 * completed before we try to shutdown.
4d476f
+	 */
4d476f
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
4d476f
+
4d476f
+	master_mutex_lock();
4d476f
+
4d476f
+	if (!ap->submount)
4d476f
+		master_source_writelock(ap->entry);
4d476f
+	else {
4d476f
+		/*
4d476f
+		 * If a mount request arrives before the locks are
4d476f
+		 * aquired just return to ready state.
4d476f
+		 */
4d476f
+		ret = submount_source_writelock_nested(ap);
4d476f
+		if (ret) {
4d476f
+			warn(ap->logopt,
4d476f
+			     "can't shutdown submount: mount in progress");
4d476f
+			/* Return to ST_READY is done immediately */
4d476f
+			st_add_task(ap, ST_READY);
4d476f
+			master_mutex_unlock();
4d476f
+			pthread_setcancelstate(cur_state, NULL);
4d476f
+			return 0;
4d476f
+		}
4d476f
+	}
4d476f
+
4d476f
+	if (ap->state != ST_SHUTDOWN) {
4d476f
+		if (!ap->submount)
4d476f
+			alarm_add(ap, ap->exp_runfreq);
4d476f
+		/* Return to ST_READY is done immediately */
4d476f
+		st_add_task(ap, ST_READY);
4d476f
+		if (ap->submount)
4d476f
+			submount_source_unlock_nested(ap);
4d476f
+		else
4d476f
+			master_source_unlock(ap->entry);
4d476f
+		master_mutex_unlock();
4d476f
+
4d476f
+		pthread_setcancelstate(cur_state, NULL);
4d476f
+		return 0;
4d476f
+	}
4d476f
+
4d476f
+	alarm_delete(ap);
4d476f
+	st_remove_tasks(ap);
4d476f
+	st_wait_task(ap, ST_ANY, 0);
4d476f
+
4d476f
+	/*
4d476f
+	 * For a direct mount map all mounts have already gone
4d476f
+	 * by the time we get here and since we only ever
4d476f
+	 * umount direct mounts at shutdown there is no need
4d476f
+	 * to check for possible recovery.
4d476f
+	 */
4d476f
+	if (ap->type == LKP_DIRECT) {
4d476f
+		umount_autofs(ap, NULL, 1);
4d476f
+		handle_mounts_cleanup(ap);
4d476f
+		return 1;
4d476f
+	}
4d476f
+
4d476f
+	/*
4d476f
+	 * If umount_autofs returns non-zero it wasn't able
4d476f
+	 * to complete the umount and has left the mount intact
4d476f
+	 * so we can continue. This can happen if a lookup
4d476f
+	 * occurs while we're trying to umount.
4d476f
+	 */
4d476f
+	ret = umount_autofs(ap, NULL, 1);
4d476f
+	if (!ret) {
4d476f
+		handle_mounts_cleanup(ap);
4d476f
+		return 1;
4d476f
+	}
4d476f
+
4d476f
+	/* Failed shutdown returns to ready */
4d476f
+	warn(ap->logopt, "can't shutdown: filesystem %s still busy", ap->path);
4d476f
+	if (!ap->submount)
4d476f
+		alarm_add(ap, ap->exp_runfreq);
4d476f
+	/* Return to ST_READY is done immediately */
4d476f
+	st_add_task(ap, ST_READY);
4d476f
+	if (ap->submount)
4d476f
+		submount_source_unlock_nested(ap);
4d476f
+	else
4d476f
+		master_source_unlock(ap->entry);
4d476f
+	master_mutex_unlock();
4d476f
+
4d476f
+	pthread_setcancelstate(cur_state, NULL);
4d476f
+
4d476f
+	return 0;
4d476f
+}
4d476f
+
4d476f
 void *handle_mounts(void *arg)
4d476f
 {
4d476f
 	struct startup_cond *suc;
4d476f
@@ -1714,97 +1807,21 @@ void *handle_mounts(void *arg)
4d476f
 
4d476f
 	pthread_setcancelstate(cancel_state, NULL);
4d476f
 
4d476f
-	while (ap->state != ST_SHUTDOWN) {
4d476f
+	while (1) {
4d476f
 		if (handle_packet(ap)) {
4d476f
-			int ret, cur_state;
4d476f
-
4d476f
-			/*
4d476f
-			 * If we're a submount we need to ensure our parent
4d476f
-			 * doesn't try to mount us again until our shutdown
4d476f
-			 * is complete and that any outstanding mounts are
4d476f
-			 * completed before we try to shutdown.
4d476f
-			 */
4d476f
-			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
4d476f
-
4d476f
-			master_mutex_lock();
4d476f
-
4d476f
-			if (ap->submount) {
4d476f
-				/*
4d476f
-				 * If a mount request arrives before the locks are
4d476f
-				 * aquired just return to ready state.
4d476f
-				 */
4d476f
-				ret = submount_source_writelock_nested(ap);
4d476f
-				if (ret) {
4d476f
-					warn(ap->logopt,
4d476f
-					     "can't shutdown submount: mount in progress");
4d476f
-					/* Return to ST_READY is done immediately */
4d476f
-					st_add_task(ap, ST_READY);
4d476f
-					master_mutex_unlock();
4d476f
-					pthread_setcancelstate(cur_state, NULL);
4d476f
-					continue;
4d476f
-				}
4d476f
-			} else
4d476f
-				master_source_writelock(ap->entry);
4d476f
-
4d476f
-			if (ap->state != ST_SHUTDOWN) {
4d476f
-				if (!ap->submount)
4d476f
-					alarm_add(ap, ap->exp_runfreq);
4d476f
-				/* Return to ST_READY is done immediately */
4d476f
-				st_add_task(ap, ST_READY);
4d476f
-				if (ap->submount)
4d476f
-					submount_source_unlock_nested(ap);
4d476f
-				else
4d476f
-					master_source_unlock(ap->entry);
4d476f
-				master_mutex_unlock();
4d476f
-
4d476f
-				pthread_setcancelstate(cur_state, NULL);
4d476f
-				continue;
4d476f
-			}
4d476f
-
4d476f
-			alarm_delete(ap);
4d476f
-			st_remove_tasks(ap);
4d476f
-			st_wait_task(ap, ST_ANY, 0);
4d476f
-
4d476f
-			/*
4d476f
-			 * For a direct mount map all mounts have already gone
4d476f
-			 * by the time we get here and since we only ever
4d476f
-			 * umount direct mounts at shutdown there is no need
4d476f
-			 * to check for possible recovery.
4d476f
-			 */
4d476f
-			if (ap->type == LKP_DIRECT) {
4d476f
-				umount_autofs(ap, NULL, 1);
4d476f
-				handle_mounts_cleanup(ap);
4d476f
+			if (handle_mounts_exit(ap))
4d476f
 				break;
4d476f
-			}
4d476f
+		}
4d476f
 
4d476f
-			/*
4d476f
-			 * If umount_autofs returns non-zero it wasn't able
4d476f
-			 * to complete the umount and has left the mount intact
4d476f
-			 * so we can continue. This can happen if a lookup
4d476f
-			 * occurs while we're trying to umount.
4d476f
-			 */
4d476f
-			ret = umount_autofs(ap, NULL, 1);
4d476f
-			if (!ret) {
4d476f
-				handle_mounts_cleanup(ap);
4d476f
+		/* If we get here a packet has been received and handled
4d476f
+		 * and the autofs mount point has not been shutdown. But
4d476f
+		 * if the autofs mount point has been set to ST_SHUTDOWN
4d476f
+		 * we should attempt to perform the shutdown cleanup and
4d476f
+		 * exit if successful.
4d476f
+		 */
4d476f
+		if (ap->state == ST_SHUTDOWN) {
4d476f
+			if (handle_mounts_exit(ap))
4d476f
 				break;
4d476f
-			}
4d476f
-
4d476f
-			/* Failed shutdown returns to ready */
4d476f
-			warn(ap->logopt,
4d476f
-			     "can't shutdown: filesystem %s still busy",
4d476f
-			     ap->path);
4d476f
-			if (!ap->submount)
4d476f
-				alarm_add(ap, ap->exp_runfreq);
4d476f
-			/* Return to ST_READY is done immediately */
4d476f
-			st_add_task(ap, ST_READY);
4d476f
-			if (ap->submount)
4d476f
-				submount_source_unlock_nested(ap);
4d476f
-			else
4d476f
-				master_source_unlock(ap->entry);
4d476f
-			master_mutex_unlock();
4d476f
-
4d476f
-			pthread_setcancelstate(cur_state, NULL);
4d476f
-
4d476f
 		}
4d476f
 	}
4d476f