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);