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

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