Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 267

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

diff --git a/daemon/automount.c b/daemon/automount.c
index f31ec11..afbcb56 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1564,9 +1564,24 @@ void *handle_mounts(void *arg)
 			}
 
 			/* OK to exit */
-			if (ap->state == ST_SHUTDOWN || result) {
-				state_mutex_unlock(ap);
-				break;
+			if (ap->state == ST_SHUTDOWN) {
+				if (result) {
+					state_mutex_unlock(ap);
+					break;
+				}
+#ifdef ENABLE_IGNORE_BUSY_MOUNTS
+				/*
+				 * There weren't any active mounts but if the
+				 * filesystem is busy there may be a mount
+				 * request in progress so return to the ready
+				 * state unless a shutdown has been explicitly
+				 * requested.
+				 */
+				if (ap->shutdown) {
+					state_mutex_unlock(ap);
+					break;
+				}
+#endif
 			}
 
 			/* Failed shutdown returns to ready */
diff --git a/daemon/direct.c b/daemon/direct.c
index 619efce..529f143 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1494,7 +1494,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 		  (unsigned long) pkt->wait_queue_token, me->key, pkt->pid);
 
 	/* Ignore packet if we're trying to shut down */
-	if (ap->state == ST_SHUTDOWN_PENDING ||
+	if (ap->shutdown ||
 	    ap->state == ST_SHUTDOWN_FORCE ||
 	    ap->state == ST_SHUTDOWN) {
 		send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index f6b93d0..fd94e59 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -863,7 +863,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
 		(unsigned long) pkt->wait_queue_token, pkt->name, pkt->pid);
 
 	/* Ignore packet if we're trying to shut down */
-	if (ap->state == ST_SHUTDOWN_PENDING ||
+	if (ap->shutdown ||
 	    ap->state == ST_SHUTDOWN_FORCE ||
 	    ap->state == ST_SHUTDOWN) {
 		send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index eb72411..eac6053 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -928,10 +928,17 @@ void lookup_close_lookup(struct autofs_point *ap)
 	if (!map)
 		return;
 
+	/*
+	 * Make sure we don't kill the context if a mount
+	 * request has come in while were shutting down.
+	 */
+	master_source_writelock(ap->entry);
 	while (map) {
 		lookup_close_lookup_instances(map);
 		map = map->next;
 	}
+	master_source_unlock(ap->entry);
+
 	return;
 }
 
diff --git a/daemon/state.c b/daemon/state.c
index 5bccfef..5804707 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -113,6 +113,8 @@ void expire_cleanup(void *arg)
 
 	/* Check to see if expire process finished */
 	if (thid == ap->exp_thread) {
+		int rv, idle;
+
 		ap->exp_thread = 0;
 
 		switch (ap->state) {
@@ -133,8 +135,6 @@ void expire_cleanup(void *arg)
 			 * allowing it to shutdown.
 			 */
 			if (ap->submount && !success) {
-				int rv, idle;
-
 				rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &idle);
 				if (!rv && idle && ap->submount > 1) {
 					next = ST_SHUTDOWN_PENDING;
@@ -155,6 +155,19 @@ void expire_cleanup(void *arg)
 			break;
 
 		case ST_SHUTDOWN_PENDING:
+			/*
+			 * If we reveive a mount request while trying to
+			 * shutdown return to ready state unless we have
+			 * been signaled to shutdown.
+			 */
+			rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &idle);
+			if (!idle && !ap->shutdown) {
+				next = ST_READY;
+				if (!ap->submount)
+					alarm_add(ap, ap->exp_runfreq);
+				break;
+			}
+
 			next = ST_SHUTDOWN;
 #ifdef ENABLE_IGNORE_BUSY_MOUNTS
 			break;
@@ -200,6 +213,7 @@ static unsigned int st_ready(struct autofs_point *ap)
 	debug(ap->logopt,
 	      "st_ready(): state = %d path %s", ap->state, ap->path);
 
+	ap->shutdown = 0;
 	ap->state = ST_READY;
 
 	if (ap->submount)
diff --git a/include/automount.h b/include/automount.h
index 133fd32..cd8ce7b 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -461,6 +461,7 @@ struct autofs_point {
 	unsigned int mounts_signaled;	/* Submount signals task complete */
 	struct list_head mounts;	/* List of autofs mounts at current level */
 	unsigned int submount;		/* Is this a submount */
+	unsigned int shutdown;		/* Shutdown notification */
 	unsigned int submnt_count;	/* Number of submounts */
 	struct list_head submounts;	/* List of child submounts */
 };
diff --git a/lib/master.c b/lib/master.c
index c001d20..ed82131 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -94,6 +94,7 @@ int master_add_autofs_point(struct master_mapent *entry,
 	ap->submount = submount;
 	INIT_LIST_HEAD(&ap->mounts);
 	INIT_LIST_HEAD(&ap->submounts);
+	ap->shutdown = 0;
 
 	status = pthread_mutex_init(&ap->state_mutex, NULL);
 	if (status) {
@@ -968,6 +969,7 @@ void master_notify_state_change(struct master *master, int sig)
 			if (ap->state != ST_SHUTDOWN_PENDING &&
 			    ap->state != ST_SHUTDOWN_FORCE) {
 				next = ST_SHUTDOWN_PENDING;
+				ap->shutdown = 1;
 				nextstate(state_pipe, next);
 			}
 			break;
@@ -1180,9 +1182,7 @@ int master_mount_mounts(struct master *master, time_t age, int readall)
 			continue;
 		}
 
-		master_source_writelock(this);
 		lookup_close_lookup(ap);
-		master_source_unlock(this);
 
 		cache_readlock(nc);
 		ne = cache_lookup_distinct(nc, this->path);