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