|
Ian Kent |
3685ec |
autofs-5.0.3 - fix submount shutdown handling.
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
From: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
When using submount maps on a busy system autofs can hang.
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
This problem comes about because of processes walking into the
|
|
Ian Kent |
3685ec |
submount filesystem when it is in the process of shutting down.
|
|
Ian Kent |
3685ec |
While this race has been fixed for other types of mounts it
|
|
Ian Kent |
3685ec |
still isn't possible to to block processes from walking into
|
|
Ian Kent |
3685ec |
submounts that are expiring so we need to be able to recover
|
|
Ian Kent |
3685ec |
when this happens.
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
This patch improves the submount shutdown logic and allows
|
|
Ian Kent |
3685ec |
submounts that become busy during shutdown to recover.
|
|
Ian Kent |
3685ec |
---
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
CHANGELOG | 1
|
|
Ian Kent |
3685ec |
daemon/automount.c | 208 +++++++++++++++++++-----------------------
|
|
Ian Kent |
3685ec |
daemon/direct.c | 97 ++++++++++++++------
|
|
Ian Kent |
3685ec |
daemon/indirect.c | 114 ++++++++++++++++++-----
|
|
Ian Kent |
3685ec |
daemon/lookup.c | 11 --
|
|
Ian Kent |
3685ec |
daemon/state.c | 235 +++++++++++++++++++++++++++++++++---------------
|
|
Ian Kent |
3685ec |
include/automount.h | 17 ---
|
|
Ian Kent |
3685ec |
include/master.h | 5 -
|
|
Ian Kent |
3685ec |
include/state.h | 9 ++
|
|
Ian Kent |
3685ec |
lib/alarm.c | 14 ---
|
|
Ian Kent |
3685ec |
lib/master.c | 180 +++++++------------------------------
|
|
Ian Kent |
3685ec |
modules/mount_autofs.c | 2
|
|
Ian Kent |
3685ec |
12 files changed, 458 insertions(+), 435 deletions(-)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
diff --git a/CHANGELOG b/CHANGELOG
|
|
Ian Kent |
3685ec |
index 9da7be3..ff04985 100644
|
|
Ian Kent |
3685ec |
--- a/CHANGELOG
|
|
Ian Kent |
3685ec |
+++ b/CHANGELOG
|
|
Ian Kent |
3685ec |
@@ -26,6 +26,7 @@
|
|
Ian Kent |
3685ec |
- add command line option to override check for daemon already running.
|
|
Ian Kent |
3685ec |
- don't use proc file system when checking if the daemon is running.
|
|
Ian Kent |
3685ec |
- make handle_mounts startup condition distinct.
|
|
Ian Kent |
3685ec |
+- fix submount shutdown recovery handling.
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
14/01/2008 autofs-5.0.3
|
|
Ian Kent |
3685ec |
-----------------------
|
|
Ian Kent |
3685ec |
diff --git a/daemon/automount.c b/daemon/automount.c
|
|
Ian Kent |
3685ec |
index 086affb..68bf1d3 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/automount.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/automount.c
|
|
Ian Kent |
3685ec |
@@ -369,6 +369,18 @@ int count_mounts(unsigned logopt, const char *path, dev_t dev)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
static void check_rm_dirs(struct autofs_point *ap, const char *path, int incl)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
+ /*
|
|
Ian Kent |
3685ec |
+ * If we're a submount the kernel can't know we're trying to
|
|
Ian Kent |
3685ec |
+ * shutdown and so cannot block processes walking into the
|
|
Ian Kent |
3685ec |
+ * mount point directory. If this is the call to umount_multi()
|
|
Ian Kent |
3685ec |
+ * made during shutdown (incl == 0) we have to leave any mount
|
|
Ian Kent |
3685ec |
+ * point directories in place so we can recover if needed. The
|
|
Ian Kent |
3685ec |
+ * umount itself will clean these directories up for us
|
|
Ian Kent |
3685ec |
+ * automagically.
|
|
Ian Kent |
3685ec |
+ */
|
|
Ian Kent |
3685ec |
+ if (!incl && ap->submount)
|
|
Ian Kent |
3685ec |
+ return;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
if ((!ap->ghost) ||
|
|
Ian Kent |
3685ec |
(ap->state == ST_SHUTDOWN_PENDING ||
|
|
Ian Kent |
3685ec |
ap->state == ST_SHUTDOWN_FORCE ||
|
|
Ian Kent |
3685ec |
@@ -390,8 +402,6 @@ static void update_map_cache(struct autofs_point *ap, const char *path)
|
|
Ian Kent |
3685ec |
else
|
|
Ian Kent |
3685ec |
key = path;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
|
|
Ian Kent |
3685ec |
- master_source_readlock(ap->entry);
|
|
Ian Kent |
3685ec |
map = ap->entry->maps;
|
|
Ian Kent |
3685ec |
while (map) {
|
|
Ian Kent |
3685ec |
struct mapent *me = NULL;
|
|
Ian Kent |
3685ec |
@@ -413,7 +423,6 @@ static void update_map_cache(struct autofs_point *ap, const char *path)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
map = map->next;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -918,38 +927,22 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt)
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (fds[1].revents & POLLIN) {
|
|
Ian Kent |
3685ec |
- enum states next_state, post_state;
|
|
Ian Kent |
3685ec |
+ enum states next_state;
|
|
Ian Kent |
3685ec |
size_t read_size = sizeof(next_state);
|
|
Ian Kent |
3685ec |
int state_pipe;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- next_state = post_state = ST_INVAL;
|
|
Ian Kent |
3685ec |
+ next_state = ST_INVAL;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
state_pipe = ap->state_pipe[0];
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (fullread(state_pipe, &next_state, read_size)) {
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
continue;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- if (next_state != ST_INVAL && next_state != ap->state) {
|
|
Ian Kent |
3685ec |
- if (next_state != ST_SHUTDOWN)
|
|
Ian Kent |
3685ec |
- post_state = next_state;
|
|
Ian Kent |
3685ec |
- else
|
|
Ian Kent |
3685ec |
- ap->state = ST_SHUTDOWN;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (post_state != ST_INVAL) {
|
|
Ian Kent |
3685ec |
- if (post_state == ST_SHUTDOWN_PENDING ||
|
|
Ian Kent |
3685ec |
- post_state == ST_SHUTDOWN_FORCE) {
|
|
Ian Kent |
3685ec |
- alarm_delete(ap);
|
|
Ian Kent |
3685ec |
- st_remove_tasks(ap);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
- st_add_task(ap, post_state);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (next_state == ST_SHUTDOWN)
|
|
Ian Kent |
3685ec |
return -1;
|
|
Ian Kent |
3685ec |
@@ -985,11 +978,14 @@ int do_expire(struct autofs_point *ap, const char *name, int namelen)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
info(ap->logopt, "expiring path %s", buf);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
|
|
Ian Kent |
3685ec |
+ master_source_readlock(ap->entry);
|
|
Ian Kent |
3685ec |
ret = umount_multi(ap, buf, 1);
|
|
Ian Kent |
3685ec |
if (ret == 0)
|
|
Ian Kent |
3685ec |
info(ap->logopt, "expired %s", buf);
|
|
Ian Kent |
3685ec |
else
|
|
Ian Kent |
3685ec |
warn(ap->logopt, "couldn't complete expire of %s", buf);
|
|
Ian Kent |
3685ec |
+ pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return ret;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1069,7 +1065,7 @@ static int mount_autofs(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
if (status < 0)
|
|
Ian Kent |
3685ec |
return -1;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- ap->state = ST_READY;
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_READY);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1423,44 +1419,6 @@ static void return_start_status(void *arg)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-static void mutex_operation_wait(pthread_mutex_t *mutex)
|
|
Ian Kent |
3685ec |
-{
|
|
Ian Kent |
3685ec |
- int status;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- /*
|
|
Ian Kent |
3685ec |
- * Unlock a mutex, but wait for a pending operation
|
|
Ian Kent |
3685ec |
- * if one is in progress
|
|
Ian Kent |
3685ec |
- */
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_trylock(mutex);
|
|
Ian Kent |
3685ec |
- if (status) {
|
|
Ian Kent |
3685ec |
- if (status == EBUSY) {
|
|
Ian Kent |
3685ec |
- /* Mutex locked - do we own it */
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_unlock(mutex);
|
|
Ian Kent |
3685ec |
- if (status) {
|
|
Ian Kent |
3685ec |
- if (status != EPERM)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- } else
|
|
Ian Kent |
3685ec |
- return;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_lock(mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- } else
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- /* Operation complete, release it */
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_unlock(mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- } else {
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_unlock(mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- return;
|
|
Ian Kent |
3685ec |
-}
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
int handle_mounts_startup_cond_init(struct startup_cond *suc)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
int status;
|
|
Ian Kent |
3685ec |
@@ -1526,22 +1484,25 @@ static void handle_mounts_cleanup(void *arg)
|
|
Ian Kent |
3685ec |
if (!submount && strcmp(ap->path, "/-") && ap->dir_created)
|
|
Ian Kent |
3685ec |
clean = 1;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- /* If we have been canceled then we may hold the state mutex. */
|
|
Ian Kent |
3685ec |
- mutex_operation_wait(&ap->state_mutex);
|
|
Ian Kent |
3685ec |
+ if (submount) {
|
|
Ian Kent |
3685ec |
+ /* We are finishing up */
|
|
Ian Kent |
3685ec |
+ ap->parent->submnt_count--;
|
|
Ian Kent |
3685ec |
+ list_del_init(&ap->mounts);
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- alarm_delete(ap);
|
|
Ian Kent |
3685ec |
- st_remove_tasks(ap);
|
|
Ian Kent |
3685ec |
+ master_remove_mapent(ap->entry);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- umount_autofs(ap, 1);
|
|
Ian Kent |
3685ec |
+ if (submount) {
|
|
Ian Kent |
3685ec |
+ mounts_mutex_unlock(ap->parent);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->parent->entry);
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+ master_mutex_unlock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
destroy_logpri_fifo(ap);
|
|
Ian Kent |
3685ec |
- master_signal_submount(ap, MASTER_SUBMNT_JOIN);
|
|
Ian Kent |
3685ec |
- master_remove_mapent(ap->entry);
|
|
Ian Kent |
3685ec |
master_free_mapent_sources(ap->entry, 1);
|
|
Ian Kent |
3685ec |
master_free_mapent(ap->entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- sched_yield();
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
if (clean) {
|
|
Ian Kent |
3685ec |
if (rmdir(path) == -1) {
|
|
Ian Kent |
3685ec |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Ian Kent |
3685ec |
@@ -1572,8 +1533,6 @@ void *handle_mounts(void *arg)
|
|
Ian Kent |
3685ec |
pthread_cleanup_push(return_start_status, suc);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
status = pthread_mutex_lock(&suc->mutex);
|
|
Ian Kent |
3685ec |
if (status) {
|
|
Ian Kent |
3685ec |
logerr("failed to lock startup condition mutex!");
|
|
Ian Kent |
3685ec |
@@ -1583,7 +1542,6 @@ void *handle_mounts(void *arg)
|
|
Ian Kent |
3685ec |
if (mount_autofs(ap) < 0) {
|
|
Ian Kent |
3685ec |
crit(ap->logopt, "mount of %s failed!", ap->path);
|
|
Ian Kent |
3685ec |
suc->status = 1;
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
umount_autofs(ap, 1);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(cancel_state, NULL);
|
|
Ian Kent |
3685ec |
pthread_exit(NULL);
|
|
Ian Kent |
3685ec |
@@ -1600,56 +1558,70 @@ void *handle_mounts(void *arg)
|
|
Ian Kent |
3685ec |
if (!ap->submount && ap->exp_timeout)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq + rand() % ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- pthread_cleanup_push(handle_mounts_cleanup, ap);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(cancel_state, NULL);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
while (ap->state != ST_SHUTDOWN) {
|
|
Ian Kent |
3685ec |
if (handle_packet(ap)) {
|
|
Ian Kent |
3685ec |
- int ret, result;
|
|
Ian Kent |
3685ec |
+ int ret, cur_state;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ /*
|
|
Ian Kent |
3685ec |
+ * If we're a submount we need to ensure our parent
|
|
Ian Kent |
3685ec |
+ * doesn't try to mount us again until our shutdown
|
|
Ian Kent |
3685ec |
+ * is complete and that any outstanding mounts are
|
|
Ian Kent |
3685ec |
+ * completed before we try to shutdown.
|
|
Ian Kent |
3685ec |
+ */
|
|
Ian Kent |
3685ec |
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ master_mutex_lock();
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (ap->submount) {
|
|
Ian Kent |
3685ec |
+ master_source_writelock(ap->parent->entry);
|
|
Ian Kent |
3685ec |
+ mounts_mutex_lock(ap->parent);
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ master_source_writelock(ap->entry);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (ap->state != ST_SHUTDOWN) {
|
|
Ian Kent |
3685ec |
+ if (!ap->submount)
|
|
Ian Kent |
3685ec |
+ alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
+ /* Return to ST_READY is done immediately */
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_READY);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
+ if (ap->submount) {
|
|
Ian Kent |
3685ec |
+ mounts_mutex_unlock(ap->parent);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->parent->entry);
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ master_mutex_unlock();
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
3685ec |
+ continue;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ alarm_delete(ap);
|
|
Ian Kent |
3685ec |
+ st_remove_tasks(ap);
|
|
Ian Kent |
3685ec |
+ st_wait_task(ap, ST_ANY, 0);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
* For a direct mount map all mounts have already gone
|
|
Ian Kent |
3685ec |
- * by the time we get here.
|
|
Ian Kent |
3685ec |
+ * by the time we get here and since we only ever
|
|
Ian Kent |
3685ec |
+ * umount direct mounts at shutdown there is no need
|
|
Ian Kent |
3685ec |
+ * to check for possible recovery.
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
if (ap->type == LKP_DIRECT) {
|
|
Ian Kent |
3685ec |
- status = 1;
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ umount_autofs(ap, 1);
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
- * If the ioctl fails assume the kernel doesn't have
|
|
Ian Kent |
3685ec |
- * AUTOFS_IOC_ASKUMOUNT and just continue.
|
|
Ian Kent |
3685ec |
+ * If umount_autofs returns non-zero it wasn't able
|
|
Ian Kent |
3685ec |
+ * to complete the umount and has left the mount intact
|
|
Ian Kent |
3685ec |
+ * so we can continue. This can happen if a lookup
|
|
Ian Kent |
3685ec |
+ * occurs while we're trying to umount.
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
- ret = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &result);
|
|
Ian Kent |
3685ec |
- if (ret == -1) {
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ ret = umount_autofs(ap, 1);
|
|
Ian Kent |
3685ec |
+ if (!ret)
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- /* OK to exit */
|
|
Ian Kent |
3685ec |
- if (ap->state == ST_SHUTDOWN) {
|
|
Ian Kent |
3685ec |
- if (result) {
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
- break;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-#ifdef ENABLE_IGNORE_BUSY_MOUNTS
|
|
Ian Kent |
3685ec |
- /*
|
|
Ian Kent |
3685ec |
- * There weren't any active mounts but if the
|
|
Ian Kent |
3685ec |
- * filesystem is busy there may be a mount
|
|
Ian Kent |
3685ec |
- * request in progress so return to the ready
|
|
Ian Kent |
3685ec |
- * state unless a shutdown has been explicitly
|
|
Ian Kent |
3685ec |
- * requested.
|
|
Ian Kent |
3685ec |
- */
|
|
Ian Kent |
3685ec |
- if (ap->shutdown) {
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
- break;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-#endif
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* Failed shutdown returns to ready */
|
|
Ian Kent |
3685ec |
warn(ap->logopt,
|
|
Ian Kent |
3685ec |
@@ -1657,14 +1629,22 @@ void *handle_mounts(void *arg)
|
|
Ian Kent |
3685ec |
ap->path);
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
+ /* Return to ST_READY is done immediately */
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_READY);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
+ if (ap->submount) {
|
|
Ian Kent |
3685ec |
+ mounts_mutex_unlock(ap->parent);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->parent->entry);
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ master_mutex_unlock();
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
- sched_yield();
|
|
Ian Kent |
3685ec |
+ handle_mounts_cleanup(ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return NULL;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
diff --git a/daemon/direct.c b/daemon/direct.c
|
|
Ian Kent |
3685ec |
index a3869a5..334a4b6 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/direct.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/direct.c
|
|
Ian Kent |
3685ec |
@@ -216,8 +216,6 @@ int umount_autofs_direct(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
|
|
Ian Kent |
3685ec |
pthread_cleanup_push(mnts_cleanup, mnts);
|
|
Ian Kent |
3685ec |
- pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
|
|
Ian Kent |
3685ec |
- master_source_readlock(ap->entry);
|
|
Ian Kent |
3685ec |
nc = ap->entry->master->nc;
|
|
Ian Kent |
3685ec |
cache_readlock(nc);
|
|
Ian Kent |
3685ec |
pthread_cleanup_push(cache_lock_cleanup, nc);
|
|
Ian Kent |
3685ec |
@@ -244,7 +242,6 @@ int umount_autofs_direct(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
- pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -572,9 +569,10 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
} else if (!status) {
|
|
Ian Kent |
3685ec |
if (ap->state != ST_SHUTDOWN_FORCE) {
|
|
Ian Kent |
3685ec |
- error(ap->logopt,
|
|
Ian Kent |
3685ec |
- "ask umount returned busy for %s",
|
|
Ian Kent |
3685ec |
- me->key);
|
|
Ian Kent |
3685ec |
+ if (ap->shutdown)
|
|
Ian Kent |
3685ec |
+ error(ap->logopt,
|
|
Ian Kent |
3685ec |
+ "ask umount returned busy for %s",
|
|
Ian Kent |
3685ec |
+ me->key);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
} else {
|
|
Ian Kent |
3685ec |
me->ioctlfd = -1;
|
|
Ian Kent |
3685ec |
@@ -904,7 +902,10 @@ void *expire_proc_direct(void *arg)
|
|
Ian Kent |
3685ec |
* All direct mounts must be present in the map
|
|
Ian Kent |
3685ec |
* entry cache.
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
+ pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
|
|
Ian Kent |
3685ec |
+ master_source_readlock(ap->entry);
|
|
Ian Kent |
3685ec |
me = lookup_source_mapent(ap, next->path, LKP_DISTINCT);
|
|
Ian Kent |
3685ec |
+ pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
if (!me)
|
|
Ian Kent |
3685ec |
continue;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -1110,6 +1111,8 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
3685ec |
struct pending_args *mt;
|
|
Ian Kent |
3685ec |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
pthread_t thid;
|
|
Ian Kent |
3685ec |
+ struct timespec wait;
|
|
Ian Kent |
3685ec |
+ struct timeval now;
|
|
Ian Kent |
3685ec |
int status, state;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
3685ec |
@@ -1124,7 +1127,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
3685ec |
* and since it got mounted we have to trust that
|
|
Ian Kent |
3685ec |
* there is an entry in the cache.
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
- master_source_readlock(ap->entry);
|
|
Ian Kent |
3685ec |
+ master_source_writelock(ap->entry);
|
|
Ian Kent |
3685ec |
map = ap->entry->maps;
|
|
Ian Kent |
3685ec |
while (map) {
|
|
Ian Kent |
3685ec |
mc = map->mc;
|
|
Ian Kent |
3685ec |
@@ -1135,7 +1138,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
map = map->next;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (!me) {
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
@@ -1144,10 +1146,28 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
crit(ap->logopt, "can't find map entry for (%lu,%lu)",
|
|
Ian Kent |
3685ec |
(unsigned long) pkt->dev, (unsigned long) pkt->ino);
|
|
Ian Kent |
3685ec |
+ cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ /* Can't expire it if it isn't mounted */
|
|
Ian Kent |
3685ec |
+ if (me->ioctlfd == -1) {
|
|
Ian Kent |
3685ec |
+ int ioctlfd = open(me->key, O_RDONLY);
|
|
Ian Kent |
3685ec |
+ if (ioctlfd == -1) {
|
|
Ian Kent |
3685ec |
+ crit(ap->logopt, "can't open ioctlfd for %s",
|
|
Ian Kent |
3685ec |
+ me->key);
|
|
Ian Kent |
3685ec |
+ pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
+ return 1;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+ send_ready(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
+ close(ioctlfd);
|
|
Ian Kent |
3685ec |
+ cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
+ pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
+ return 0;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mt = malloc(sizeof(struct pending_args));
|
|
Ian Kent |
3685ec |
if (!mt) {
|
|
Ian Kent |
3685ec |
@@ -1155,6 +1175,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
3685ec |
error(ap->logopt, "malloc: %s", estr);
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, me->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1184,6 +1205,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
3685ec |
error(ap->logopt, "expire thread create failed");
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, mt->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
expire_mutex_unlock(NULL);
|
|
Ian Kent |
3685ec |
pending_cond_destroy(mt);
|
|
Ian Kent |
3685ec |
free_pending_args(mt);
|
|
Ian Kent |
3685ec |
@@ -1192,14 +1214,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
pthread_cleanup_push(expire_mutex_unlock, NULL);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mt->signaled = 0;
|
|
Ian Kent |
3685ec |
while (!mt->signaled) {
|
|
Ian Kent |
3685ec |
+ gettimeofday(&now, NULL);
|
|
Ian Kent |
3685ec |
+ wait.tv_sec = now.tv_sec + 2;
|
|
Ian Kent |
3685ec |
+ wait.tv_nsec = now.tv_usec * 1000;
|
|
Ian Kent |
3685ec |
status = pthread_cond_wait(&mt->cond, &ea_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
+ if (status && status != ETIMEDOUT)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -1263,6 +1289,9 @@ static void *do_mount_direct(void *arg)
|
|
Ian Kent |
3685ec |
if (status == -1) {
|
|
Ian Kent |
3685ec |
error(ap->logopt,
|
|
Ian Kent |
3685ec |
"can't stat direct mount trigger %s", mt.name);
|
|
Ian Kent |
3685ec |
+ send_fail(ap->logopt,
|
|
Ian Kent |
3685ec |
+ mt.ioctlfd, mt.wait_queue_token);
|
|
Ian Kent |
3685ec |
+ close(mt.ioctlfd);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
pthread_exit(NULL);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1272,6 +1301,8 @@ static void *do_mount_direct(void *arg)
|
|
Ian Kent |
3685ec |
error(ap->logopt,
|
|
Ian Kent |
3685ec |
"direct trigger not valid or already mounted %s",
|
|
Ian Kent |
3685ec |
mt.name);
|
|
Ian Kent |
3685ec |
+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|
Ian Kent |
3685ec |
+ close(mt.ioctlfd);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
pthread_exit(NULL);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1290,19 +1321,12 @@ static void *do_mount_direct(void *arg)
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
3685ec |
if (status) {
|
|
Ian Kent |
3685ec |
struct mapent *me;
|
|
Ian Kent |
3685ec |
- int real_mount, set_fd;
|
|
Ian Kent |
3685ec |
- cache_readlock(mt.mc);
|
|
Ian Kent |
3685ec |
+ cache_writelock(mt.mc);
|
|
Ian Kent |
3685ec |
me = cache_lookup_distinct(mt.mc, mt.name);
|
|
Ian Kent |
3685ec |
- real_mount = is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL);
|
|
Ian Kent |
3685ec |
- set_fd = (real_mount || me->multi == me);
|
|
Ian Kent |
3685ec |
- cache_unlock(mt.mc);
|
|
Ian Kent |
3685ec |
- if (set_fd) {
|
|
Ian Kent |
3685ec |
+ if (me)
|
|
Ian Kent |
3685ec |
me->ioctlfd = mt.ioctlfd;
|
|
Ian Kent |
3685ec |
- send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|
Ian Kent |
3685ec |
- } else {
|
|
Ian Kent |
3685ec |
- send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|
Ian Kent |
3685ec |
- close(mt.ioctlfd);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
+ send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|
Ian Kent |
3685ec |
+ cache_unlock(mt.mc);
|
|
Ian Kent |
3685ec |
info(ap->logopt, "mounted %s", mt.name);
|
|
Ian Kent |
3685ec |
} else {
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
|
Ian Kent |
3685ec |
@@ -1325,11 +1349,21 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
struct pending_args *mt;
|
|
Ian Kent |
3685ec |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
int status = 0;
|
|
Ian Kent |
3685ec |
+ struct timespec wait;
|
|
Ian Kent |
3685ec |
+ struct timeval now;
|
|
Ian Kent |
3685ec |
int ioctlfd, len, cl_flags, state;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- master_source_readlock(ap->entry);
|
|
Ian Kent |
3685ec |
+ /*
|
|
Ian Kent |
3685ec |
+ * If our parent is a direct or offset mount that has been
|
|
Ian Kent |
3685ec |
+ * covered by a mount and another lookup occurs after the
|
|
Ian Kent |
3685ec |
+ * mount but before the device and inode are set in the
|
|
Ian Kent |
3685ec |
+ * cache entry we will not be able to find the mapent. So
|
|
Ian Kent |
3685ec |
+ * we must take the source writelock to ensure the parent
|
|
Ian Kent |
3685ec |
+ * has mount is complete before we look for the entry.
|
|
Ian Kent |
3685ec |
+ */
|
|
Ian Kent |
3685ec |
+ master_source_writelock(ap->entry);
|
|
Ian Kent |
3685ec |
map = ap->entry->maps;
|
|
Ian Kent |
3685ec |
while (map) {
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
@@ -1349,7 +1383,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
map = map->next;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (!me) {
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
@@ -1358,6 +1391,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
logerr("can't find map entry for (%lu,%lu)",
|
|
Ian Kent |
3685ec |
(unsigned long) pkt->dev, (unsigned long) pkt->ino);
|
|
Ian Kent |
3685ec |
+ cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1371,6 +1406,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (ioctlfd == -1) {
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
|
|
Ian Kent |
3685ec |
/* TODO: how do we clear wait q in kernel ?? */
|
|
Ian Kent |
3685ec |
@@ -1386,12 +1422,11 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
(unsigned long) pkt->wait_queue_token, me->key, pkt->pid);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* Ignore packet if we're trying to shut down */
|
|
Ian Kent |
3685ec |
- if (ap->shutdown ||
|
|
Ian Kent |
3685ec |
- ap->state == ST_SHUTDOWN_FORCE ||
|
|
Ian Kent |
3685ec |
- ap->state == ST_SHUTDOWN) {
|
|
Ian Kent |
3685ec |
+ if (ap->shutdown || ap->state == ST_SHUTDOWN_FORCE) {
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
close(ioctlfd);
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1402,6 +1437,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
close(ioctlfd);
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1413,6 +1449,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
close(ioctlfd);
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1447,6 +1484,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
close(ioctlfd);
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
mount_mutex_unlock(mt);
|
|
Ian Kent |
3685ec |
pending_cond_destroy(mt);
|
|
Ian Kent |
3685ec |
pending_mutex_destroy(mt);
|
|
Ian Kent |
3685ec |
@@ -1456,6 +1494,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
pthread_cleanup_push(free_pending_args, mt);
|
|
Ian Kent |
3685ec |
pthread_cleanup_push(pending_mutex_destroy, mt);
|
|
Ian Kent |
3685ec |
pthread_cleanup_push(pending_cond_destroy, mt);
|
|
Ian Kent |
3685ec |
@@ -1464,8 +1504,11 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mt->signaled = 0;
|
|
Ian Kent |
3685ec |
while (!mt->signaled) {
|
|
Ian Kent |
3685ec |
- status = pthread_cond_wait(&mt->cond, &mt->mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
+ gettimeofday(&now, NULL);
|
|
Ian Kent |
3685ec |
+ wait.tv_sec = now.tv_sec + 2;
|
|
Ian Kent |
3685ec |
+ wait.tv_nsec = now.tv_usec * 1000;
|
|
Ian Kent |
3685ec |
+ status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait);
|
|
Ian Kent |
3685ec |
+ if (status && status != ETIMEDOUT)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|
Ian Kent |
3685ec |
index 3922f3f..17bed3e 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/indirect.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/indirect.c
|
|
Ian Kent |
3685ec |
@@ -230,11 +230,8 @@ int mount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-int umount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
+static void close_mount_fds(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
- char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
- int ret, rv, retries;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
/*
|
|
Ian Kent |
3685ec |
* Since submounts look after themselves the parent never knows
|
|
Ian Kent |
3685ec |
* it needs to close the ioctlfd for offset mounts so we have
|
|
Ian Kent |
3685ec |
@@ -244,6 +241,25 @@ int umount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
if (ap->submount)
|
|
Ian Kent |
3685ec |
lookup_source_close_ioctlfd(ap->parent, ap->path);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ close(ap->state_pipe[0]);
|
|
Ian Kent |
3685ec |
+ close(ap->state_pipe[1]);
|
|
Ian Kent |
3685ec |
+ ap->state_pipe[0] = -1;
|
|
Ian Kent |
3685ec |
+ ap->state_pipe[1] = -1;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (ap->pipefd >= 0)
|
|
Ian Kent |
3685ec |
+ close(ap->pipefd);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (ap->kpipefd >= 0)
|
|
Ian Kent |
3685ec |
+ close(ap->kpipefd);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ return;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+int umount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
+ int ret, rv, retries;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
/* If we are trying to shutdown make sure we can umount */
|
|
Ian Kent |
3685ec |
rv = ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret;;
|
|
Ian Kent |
3685ec |
if (rv == -1) {
|
|
Ian Kent |
3685ec |
@@ -251,24 +267,20 @@ int umount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
logerr("ioctl failed: %s", estr);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
} else if (!ret) {
|
|
Ian Kent |
3685ec |
+#if defined(ENABLE_IGNORE_BUSY_MOUNTS) || defined(ENABLE_FORCED_SHUTDOWN)
|
|
Ian Kent |
3685ec |
+ if (!ap->shutdown)
|
|
Ian Kent |
3685ec |
+ return 1;
|
|
Ian Kent |
3685ec |
error(ap->logopt, "ask umount returned busy %s", ap->path);
|
|
Ian Kent |
3685ec |
+#else
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
+#endif
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
3685ec |
+ if (ap->shutdown)
|
|
Ian Kent |
3685ec |
+ ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
close(ap->ioctlfd);
|
|
Ian Kent |
3685ec |
ap->ioctlfd = -1;
|
|
Ian Kent |
3685ec |
- close(ap->state_pipe[0]);
|
|
Ian Kent |
3685ec |
- close(ap->state_pipe[1]);
|
|
Ian Kent |
3685ec |
- ap->state_pipe[0] = -1;
|
|
Ian Kent |
3685ec |
- ap->state_pipe[1] = -1;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (ap->pipefd >= 0)
|
|
Ian Kent |
3685ec |
- close(ap->pipefd);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (ap->kpipefd >= 0)
|
|
Ian Kent |
3685ec |
- close(ap->kpipefd);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
sched_yield();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
retries = UMOUNT_RETRIES;
|
|
Ian Kent |
3685ec |
@@ -285,24 +297,61 @@ int umount_autofs_indirect(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
case EINVAL:
|
|
Ian Kent |
3685ec |
error(ap->logopt,
|
|
Ian Kent |
3685ec |
"mount point %s does not exist", ap->path);
|
|
Ian Kent |
3685ec |
+ close_mount_fds(ap);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
case EBUSY:
|
|
Ian Kent |
3685ec |
- error(ap->logopt,
|
|
Ian Kent |
3685ec |
+ debug(ap->logopt,
|
|
Ian Kent |
3685ec |
"mount point %s is in use", ap->path);
|
|
Ian Kent |
3685ec |
- if (ap->state == ST_SHUTDOWN_FORCE)
|
|
Ian Kent |
3685ec |
+ if (ap->state == ST_SHUTDOWN_FORCE) {
|
|
Ian Kent |
3685ec |
+ close_mount_fds(ap);
|
|
Ian Kent |
3685ec |
goto force_umount;
|
|
Ian Kent |
3685ec |
- else
|
|
Ian Kent |
3685ec |
- return 0;
|
|
Ian Kent |
3685ec |
+ } else {
|
|
Ian Kent |
3685ec |
+ int cl_flags;
|
|
Ian Kent |
3685ec |
+ /*
|
|
Ian Kent |
3685ec |
+ * If the umount returns EBUSY there may be
|
|
Ian Kent |
3685ec |
+ * a mount request in progress so we need to
|
|
Ian Kent |
3685ec |
+ * recover unless we have been explicitly
|
|
Ian Kent |
3685ec |
+ * asked to shutdown and configure option
|
|
Ian Kent |
3685ec |
+ * ENABLE_IGNORE_BUSY_MOUNTS is enabled.
|
|
Ian Kent |
3685ec |
+ */
|
|
Ian Kent |
3685ec |
+#ifdef ENABLE_IGNORE_BUSY_MOUNTS
|
|
Ian Kent |
3685ec |
+ if (ap->shutdown) {
|
|
Ian Kent |
3685ec |
+ close_mount_fds(ap);
|
|
Ian Kent |
3685ec |
+ return 0;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+#endif
|
|
Ian Kent |
3685ec |
+ ap->ioctlfd = open(ap->path, O_RDONLY);
|
|
Ian Kent |
3685ec |
+ if (ap->ioctlfd < 0) {
|
|
Ian Kent |
3685ec |
+ warn(ap->logopt,
|
|
Ian Kent |
3685ec |
+ "could not recover autofs path %s",
|
|
Ian Kent |
3685ec |
+ ap->path);
|
|
Ian Kent |
3685ec |
+ close_mount_fds(ap);
|
|
Ian Kent |
3685ec |
+ return 0;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if ((cl_flags = fcntl(ap->ioctlfd, F_GETFD, 0)) != -1) {
|
|
Ian Kent |
3685ec |
+ cl_flags |= FD_CLOEXEC;
|
|
Ian Kent |
3685ec |
+ fcntl(ap->ioctlfd, F_SETFD, cl_flags);
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
case ENOTDIR:
|
|
Ian Kent |
3685ec |
error(ap->logopt, "mount point is not a directory");
|
|
Ian Kent |
3685ec |
+ close_mount_fds(ap);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ /*
|
|
Ian Kent |
3685ec |
+ * We have successfully umounted the mount so we now close
|
|
Ian Kent |
3685ec |
+ * the descriptors. The kernel end of the kernel pipe will
|
|
Ian Kent |
3685ec |
+ * have been put during the umount super block cleanup.
|
|
Ian Kent |
3685ec |
+ */
|
|
Ian Kent |
3685ec |
+ close_mount_fds(ap);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
force_umount:
|
|
Ian Kent |
3685ec |
if (rv != 0) {
|
|
Ian Kent |
3685ec |
warn(ap->logopt,
|
|
Ian Kent |
3685ec |
@@ -439,9 +488,12 @@ void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
3685ec |
* Otherwise it's a top level indirect mount (possibly
|
|
Ian Kent |
3685ec |
* with offsets in it) and we use the usual ioctlfd.
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
+ pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
|
|
Ian Kent |
3685ec |
+ master_source_readlock(ap->entry);
|
|
Ian Kent |
3685ec |
me = lookup_source_mapent(ap, next->path, LKP_DISTINCT);
|
|
Ian Kent |
3685ec |
if (!me && ind_key)
|
|
Ian Kent |
3685ec |
me = lookup_source_mapent(ap, ind_key, LKP_NORMAL);
|
|
Ian Kent |
3685ec |
+ pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
if (!me)
|
|
Ian Kent |
3685ec |
continue;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -586,6 +638,8 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
|
|
Ian Kent |
3685ec |
struct pending_args *mt;
|
|
Ian Kent |
3685ec |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
pthread_t thid;
|
|
Ian Kent |
3685ec |
+ struct timespec wait;
|
|
Ian Kent |
3685ec |
+ struct timeval now;
|
|
Ian Kent |
3685ec |
int status, state;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
3685ec |
@@ -632,8 +686,11 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mt->signaled = 0;
|
|
Ian Kent |
3685ec |
while (!mt->signaled) {
|
|
Ian Kent |
3685ec |
- status = pthread_cond_wait(&mt->cond, &ea_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
+ gettimeofday(&now, NULL);
|
|
Ian Kent |
3685ec |
+ wait.tv_sec = now.tv_sec + 2;
|
|
Ian Kent |
3685ec |
+ wait.tv_nsec = now.tv_usec * 1000;
|
|
Ian Kent |
3685ec |
+ status = pthread_cond_timedwait(&mt->cond, &ea_mutex, &wait);
|
|
Ian Kent |
3685ec |
+ if (status && status != ETIMEDOUT)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -735,6 +792,8 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
|
|
Ian Kent |
3685ec |
pthread_t thid;
|
|
Ian Kent |
3685ec |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
3685ec |
struct pending_args *mt;
|
|
Ian Kent |
3685ec |
+ struct timespec wait;
|
|
Ian Kent |
3685ec |
+ struct timeval now;
|
|
Ian Kent |
3685ec |
int status, state;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
|
Ian Kent |
3685ec |
@@ -743,9 +802,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
|
|
Ian Kent |
3685ec |
(unsigned long) pkt->wait_queue_token, pkt->name, pkt->pid);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* Ignore packet if we're trying to shut down */
|
|
Ian Kent |
3685ec |
- if (ap->shutdown ||
|
|
Ian Kent |
3685ec |
- ap->state == ST_SHUTDOWN_FORCE ||
|
|
Ian Kent |
3685ec |
- ap->state == ST_SHUTDOWN) {
|
|
Ian Kent |
3685ec |
+ if (ap->shutdown || ap->state == ST_SHUTDOWN_FORCE) {
|
|
Ian Kent |
3685ec |
send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(state, NULL);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
@@ -802,8 +859,11 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mt->signaled = 0;
|
|
Ian Kent |
3685ec |
while (!mt->signaled) {
|
|
Ian Kent |
3685ec |
- status = pthread_cond_wait(&mt->cond, &mt->mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
+ gettimeofday(&now, NULL);
|
|
Ian Kent |
3685ec |
+ wait.tv_sec = now.tv_sec + 2;
|
|
Ian Kent |
3685ec |
+ wait.tv_nsec = now.tv_usec * 1000;
|
|
Ian Kent |
3685ec |
+ status = pthread_cond_timedwait(&mt->cond, &mt->mutex, &wait);
|
|
Ian Kent |
3685ec |
+ if (status && status != ETIMEDOUT)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|
Ian Kent |
3685ec |
index 2277623..85ac519 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/lookup.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/lookup.c
|
|
Ian Kent |
3685ec |
@@ -935,16 +935,10 @@ void lookup_close_lookup(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
if (!map)
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- /*
|
|
Ian Kent |
3685ec |
- * Make sure we don't kill the context if a mount
|
|
Ian Kent |
3685ec |
- * request has come in while were shutting down.
|
|
Ian Kent |
3685ec |
- */
|
|
Ian Kent |
3685ec |
- master_source_writelock(ap->entry);
|
|
Ian Kent |
3685ec |
while (map) {
|
|
Ian Kent |
3685ec |
lookup_close_lookup_instances(map);
|
|
Ian Kent |
3685ec |
map = map->next;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1122,7 +1116,6 @@ struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, un
|
|
Ian Kent |
3685ec |
struct mapent_cache *mc;
|
|
Ian Kent |
3685ec |
struct mapent *me = NULL;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- master_source_readlock(entry);
|
|
Ian Kent |
3685ec |
map = entry->maps;
|
|
Ian Kent |
3685ec |
while (map) {
|
|
Ian Kent |
3685ec |
mc = map->mc;
|
|
Ian Kent |
3685ec |
@@ -1136,7 +1129,6 @@ struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, un
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
map = map->next;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- master_source_unlock(entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return me;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1149,8 +1141,6 @@ int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key)
|
|
Ian Kent |
3685ec |
struct mapent *me;
|
|
Ian Kent |
3685ec |
int ret = 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- pthread_cleanup_push(master_source_lock_cleanup, entry);
|
|
Ian Kent |
3685ec |
- master_source_readlock(entry);
|
|
Ian Kent |
3685ec |
map = entry->maps;
|
|
Ian Kent |
3685ec |
while (map) {
|
|
Ian Kent |
3685ec |
mc = map->mc;
|
|
Ian Kent |
3685ec |
@@ -1168,7 +1158,6 @@ int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key)
|
|
Ian Kent |
3685ec |
cache_unlock(mc);
|
|
Ian Kent |
3685ec |
map = map->next;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- pthread_cleanup_pop(1);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return ret;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
diff --git a/daemon/state.c b/daemon/state.c
|
|
Ian Kent |
3685ec |
index 5804707..122177c 100644
|
|
Ian Kent |
3685ec |
--- a/daemon/state.c
|
|
Ian Kent |
3685ec |
+++ b/daemon/state.c
|
|
Ian Kent |
3685ec |
@@ -37,19 +37,19 @@ static LIST_HEAD(state_queue);
|
|
Ian Kent |
3685ec |
static void st_set_thid(struct autofs_point *, pthread_t);
|
|
Ian Kent |
3685ec |
static void st_set_done(struct autofs_point *ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-#define st_mutex_lock() \
|
|
Ian Kent |
3685ec |
-do { \
|
|
Ian Kent |
3685ec |
- int status = pthread_mutex_lock(&mutex); \
|
|
Ian Kent |
3685ec |
- if (status) \
|
|
Ian Kent |
3685ec |
- fatal(status); \
|
|
Ian Kent |
3685ec |
-} while (0)
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
-#define st_mutex_unlock() \
|
|
Ian Kent |
3685ec |
-do { \
|
|
Ian Kent |
3685ec |
- int status = pthread_mutex_unlock(&mutex); \
|
|
Ian Kent |
3685ec |
- if (status) \
|
|
Ian Kent |
3685ec |
- fatal(status); \
|
|
Ian Kent |
3685ec |
-} while (0)
|
|
Ian Kent |
3685ec |
+void st_mutex_lock(void)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ int status = pthread_mutex_lock(&mutex);
|
|
Ian Kent |
3685ec |
+ if (status)
|
|
Ian Kent |
3685ec |
+ fatal(status);
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+void st_mutex_unlock(void)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ int status = pthread_mutex_unlock(&mutex);
|
|
Ian Kent |
3685ec |
+ if (status)
|
|
Ian Kent |
3685ec |
+ fatal(status);
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
int do_mount_autofs_direct(struct autofs_point *, struct mnt_list *, struct mapent *);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -96,21 +96,19 @@ void expire_cleanup(void *arg)
|
|
Ian Kent |
3685ec |
pthread_t thid = pthread_self();
|
|
Ian Kent |
3685ec |
struct expire_args *ec;
|
|
Ian Kent |
3685ec |
struct autofs_point *ap;
|
|
Ian Kent |
3685ec |
- int statefd, success;
|
|
Ian Kent |
3685ec |
+ int success;
|
|
Ian Kent |
3685ec |
enum states next = ST_INVAL;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
ec = (struct expire_args *) arg;
|
|
Ian Kent |
3685ec |
ap = ec->ap;
|
|
Ian Kent |
3685ec |
success = ec->status;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
debug(ap->logopt,
|
|
Ian Kent |
3685ec |
"got thid %lu path %s stat %d",
|
|
Ian Kent |
3685ec |
(unsigned long) thid, ap->path, success);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- statefd = ap->state_pipe[1];
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
/* Check to see if expire process finished */
|
|
Ian Kent |
3685ec |
if (thid == ap->exp_thread) {
|
|
Ian Kent |
3685ec |
int rv, idle;
|
|
Ian Kent |
3685ec |
@@ -199,11 +197,11 @@ void expire_cleanup(void *arg)
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (next != ST_INVAL)
|
|
Ian Kent |
3685ec |
- nextstate(statefd, next);
|
|
Ian Kent |
3685ec |
+ __st_add_task(ap, next);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
st_set_done(ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -216,9 +214,6 @@ static unsigned int st_ready(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
ap->shutdown = 0;
|
|
Ian Kent |
3685ec |
ap->state = ST_READY;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- if (ap->submount)
|
|
Ian Kent |
3685ec |
- master_signal_submount(ap, MASTER_SUBMNT_CONTINUE);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -333,18 +328,18 @@ static void do_readmap_cleanup(void *arg)
|
|
Ian Kent |
3685ec |
ra = (struct readmap_args *) arg;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
ap = ra->ap;
|
|
Ian Kent |
3685ec |
- ap->readmap_thread = 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
+ ap->readmap_thread = 0;
|
|
Ian Kent |
3685ec |
+ st_ready(ap);
|
|
Ian Kent |
3685ec |
st_set_done(ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
free(ra);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
@@ -499,10 +494,8 @@ static unsigned int st_readmap(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
ra = malloc(sizeof(struct readmap_args));
|
|
Ian Kent |
3685ec |
if (!ra) {
|
|
Ian Kent |
3685ec |
error(ap->logopt, "failed to malloc reamap cond struct");
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
/* It didn't work: return to ready */
|
|
Ian Kent |
3685ec |
+ st_ready(ap);
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
@@ -528,10 +521,8 @@ static unsigned int st_readmap(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
error(ap->logopt, "read map thread create failed");
|
|
Ian Kent |
3685ec |
st_readmap_cleanup(ra);
|
|
Ian Kent |
3685ec |
free(ra);
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
/* It didn't work: return to ready */
|
|
Ian Kent |
3685ec |
+ st_ready(ap);
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
@@ -570,7 +561,7 @@ static unsigned int st_prepare_shutdown(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
/* It didn't work: return to ready */
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
+ st_ready(ap);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
case EXP_STARTED:
|
|
Ian Kent |
3685ec |
@@ -596,7 +587,7 @@ static unsigned int st_force_shutdown(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
/* It didn't work: return to ready */
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
+ st_ready(ap);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
case EXP_STARTED:
|
|
Ian Kent |
3685ec |
@@ -605,6 +596,18 @@ static unsigned int st_force_shutdown(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+static unsigned int st_shutdown(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ debug(ap->logopt, "state %d path %s", ap->state, ap->path);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ assert(ap->state == ST_SHUTDOWN_PENDING || ap->state == ST_SHUTDOWN_FORCE);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ ap->state = ST_SHUTDOWN;
|
|
Ian Kent |
3685ec |
+ nextstate(ap->state_pipe[1], ST_SHUTDOWN);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ return 0;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
static unsigned int st_prune(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
debug(ap->logopt, "state %d path %s", ap->state, ap->path);
|
|
Ian Kent |
3685ec |
@@ -617,7 +620,7 @@ static unsigned int st_prune(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
case EXP_PARTIAL:
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
+ st_ready(ap);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
case EXP_STARTED:
|
|
Ian Kent |
3685ec |
@@ -638,7 +641,7 @@ static unsigned int st_expire(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
case EXP_PARTIAL:
|
|
Ian Kent |
3685ec |
if (!ap->submount)
|
|
Ian Kent |
3685ec |
alarm_add(ap, ap->exp_runfreq);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READY);
|
|
Ian Kent |
3685ec |
+ st_ready(ap);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
case EXP_STARTED:
|
|
Ian Kent |
3685ec |
@@ -665,43 +668,35 @@ static struct state_queue *st_alloc_task(struct autofs_point *ap, enum states st
|
|
Ian Kent |
3685ec |
return task;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-/* Insert alarm entry on ordered list. */
|
|
Ian Kent |
3685ec |
-int st_add_task(struct autofs_point *ap, enum states state)
|
|
Ian Kent |
3685ec |
+/*
|
|
Ian Kent |
3685ec |
+ * Insert alarm entry on ordered list.
|
|
Ian Kent |
3685ec |
+ * State queue mutex and ap state mutex, in that order, must be held.
|
|
Ian Kent |
3685ec |
+ */
|
|
Ian Kent |
3685ec |
+int __st_add_task(struct autofs_point *ap, enum states state)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct list_head *head;
|
|
Ian Kent |
3685ec |
struct list_head *p, *q;
|
|
Ian Kent |
3685ec |
struct state_queue *new;
|
|
Ian Kent |
3685ec |
- enum states ap_state;
|
|
Ian Kent |
3685ec |
unsigned int empty = 1;
|
|
Ian Kent |
3685ec |
int status;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* Task termination marker, poke state machine */
|
|
Ian Kent |
3685ec |
if (state == ST_READY) {
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
st_ready(ap);
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- st_mutex_lock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
signaled = 1;
|
|
Ian Kent |
3685ec |
status = pthread_cond_signal(&cond;;
|
|
Ian Kent |
3685ec |
if (status)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- st_mutex_unlock();
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
- ap_state = ap->state;
|
|
Ian Kent |
3685ec |
- if (ap_state == ST_SHUTDOWN) {
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ if (ap->state == ST_SHUTDOWN)
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- st_mutex_lock();
|
|
Ian Kent |
3685ec |
+ if (state == ST_SHUTDOWN)
|
|
Ian Kent |
3685ec |
+ return st_shutdown(ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
head = &state_queue;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -718,8 +713,8 @@ int st_add_task(struct autofs_point *ap, enum states state)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* Don't add duplicate tasks */
|
|
Ian Kent |
3685ec |
if ((task->state == state && !task->done) ||
|
|
Ian Kent |
3685ec |
- (ap_state == ST_SHUTDOWN_PENDING ||
|
|
Ian Kent |
3685ec |
- ap_state == ST_SHUTDOWN_FORCE))
|
|
Ian Kent |
3685ec |
+ (ap->state == ST_SHUTDOWN_PENDING ||
|
|
Ian Kent |
3685ec |
+ ap->state == ST_SHUTDOWN_FORCE))
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* No pending tasks */
|
|
Ian Kent |
3685ec |
@@ -736,8 +731,8 @@ int st_add_task(struct autofs_point *ap, enum states state)
|
|
Ian Kent |
3685ec |
p_task = list_entry(q, struct state_queue, pending);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (p_task->state == state ||
|
|
Ian Kent |
3685ec |
- (ap_state == ST_SHUTDOWN_PENDING ||
|
|
Ian Kent |
3685ec |
- ap_state == ST_SHUTDOWN_FORCE))
|
|
Ian Kent |
3685ec |
+ (ap->state == ST_SHUTDOWN_PENDING ||
|
|
Ian Kent |
3685ec |
+ ap->state == ST_SHUTDOWN_FORCE))
|
|
Ian Kent |
3685ec |
goto done;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -760,11 +755,24 @@ done:
|
|
Ian Kent |
3685ec |
if (status)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ return 1;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+int st_add_task(struct autofs_point *ap, enum states state)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ int ret;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
+ ret = __st_add_task(ap, state);
|
|
Ian Kent |
3685ec |
st_mutex_unlock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- return 1;
|
|
Ian Kent |
3685ec |
+ return ret;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+/*
|
|
Ian Kent |
3685ec |
+ * Remove state queue tasks for ap.
|
|
Ian Kent |
3685ec |
+ * State queue mutex and ap state mutex, in that order, must be held.
|
|
Ian Kent |
3685ec |
+ */
|
|
Ian Kent |
3685ec |
void st_remove_tasks(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct list_head *head;
|
|
Ian Kent |
3685ec |
@@ -772,14 +780,10 @@ void st_remove_tasks(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
struct state_queue *task, *waiting;
|
|
Ian Kent |
3685ec |
int status;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- st_mutex_lock();
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
head = &state_queue;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- if (list_empty(head)) {
|
|
Ian Kent |
3685ec |
- st_mutex_unlock();
|
|
Ian Kent |
3685ec |
+ if (list_empty(head))
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
p = head->next;
|
|
Ian Kent |
3685ec |
while (p != head) {
|
|
Ian Kent |
3685ec |
@@ -816,12 +820,107 @@ void st_remove_tasks(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
if (status)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ return;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+static int st_task_active(struct autofs_point *ap, enum states state)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ struct list_head *head;
|
|
Ian Kent |
3685ec |
+ struct list_head *p, *q;
|
|
Ian Kent |
3685ec |
+ struct state_queue *task, *waiting;
|
|
Ian Kent |
3685ec |
+ unsigned int active = 0;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ head = &state_queue;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ list_for_each(p, head) {
|
|
Ian Kent |
3685ec |
+ task = list_entry(p, struct state_queue, list);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (task->ap != ap)
|
|
Ian Kent |
3685ec |
+ continue;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (task->state == state) {
|
|
Ian Kent |
3685ec |
+ active = 1;
|
|
Ian Kent |
3685ec |
+ break;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (state == ST_ANY) {
|
|
Ian Kent |
3685ec |
+ active = 1;
|
|
Ian Kent |
3685ec |
+ break;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ list_for_each(q, &task->pending) {
|
|
Ian Kent |
3685ec |
+ waiting = list_entry(q, struct state_queue, pending);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (waiting->state == state) {
|
|
Ian Kent |
3685ec |
+ active = 1;
|
|
Ian Kent |
3685ec |
+ break;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (state == ST_ANY) {
|
|
Ian Kent |
3685ec |
+ active = 1;
|
|
Ian Kent |
3685ec |
+ break;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
st_mutex_unlock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- return;
|
|
Ian Kent |
3685ec |
+ return active;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+int st_wait_task(struct autofs_point *ap, enum states state, unsigned int seconds)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ unsigned int wait = 0;
|
|
Ian Kent |
3685ec |
+ unsigned int duration = 0;
|
|
Ian Kent |
3685ec |
+ int ret = 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ while (1) {
|
|
Ian Kent |
3685ec |
+ struct timespec t = { 0, 200000000 };
|
|
Ian Kent |
3685ec |
+ struct timespec r;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
|
|
Ian Kent |
3685ec |
+ memcpy(&t, &r, sizeof(struct timespec));
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (wait++ == 4) {
|
|
Ian Kent |
3685ec |
+ wait = 0;
|
|
Ian Kent |
3685ec |
+ duration++;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (!st_task_active(ap, state)) {
|
|
Ian Kent |
3685ec |
+ ret = 1;
|
|
Ian Kent |
3685ec |
+ break;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ if (seconds && duration >= seconds)
|
|
Ian Kent |
3685ec |
+ break;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ return ret;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+int st_wait_state(struct autofs_point *ap, enum states state)
|
|
Ian Kent |
3685ec |
+{
|
|
Ian Kent |
3685ec |
+ while (1) {
|
|
Ian Kent |
3685ec |
+ struct timespec t = { 0, 200000000 };
|
|
Ian Kent |
3685ec |
+ struct timespec r;
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
|
|
Ian Kent |
3685ec |
+ memcpy(&t, &r, sizeof(struct timespec));
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
+ if (ap->state == state) {
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
+ return 1;
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
+ }
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ return 0;
|
|
Ian Kent |
3685ec |
+}
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
static int run_state_task(struct state_queue *task)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct autofs_point *ap;
|
|
Ian Kent |
3685ec |
@@ -831,8 +930,6 @@ static int run_state_task(struct state_queue *task)
|
|
Ian Kent |
3685ec |
ap = task->ap;
|
|
Ian Kent |
3685ec |
next_state = task->state;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
state = ap->state;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (next_state != state) {
|
|
Ian Kent |
3685ec |
@@ -862,8 +959,6 @@ static int run_state_task(struct state_queue *task)
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
return ret;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -888,8 +983,6 @@ static void st_set_done(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
struct list_head *p, *head;
|
|
Ian Kent |
3685ec |
struct state_queue *task;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- st_mutex_lock();
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
head = &state_queue;
|
|
Ian Kent |
3685ec |
list_for_each(p, head) {
|
|
Ian Kent |
3685ec |
task = list_entry(p, struct state_queue, list);
|
|
Ian Kent |
3685ec |
@@ -899,8 +992,6 @@ static void st_set_done(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- st_mutex_unlock();
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
diff --git a/include/automount.h b/include/automount.h
|
|
Ian Kent |
3685ec |
index 1a20cd9..8ff24a7 100644
|
|
Ian Kent |
3685ec |
--- a/include/automount.h
|
|
Ian Kent |
3685ec |
+++ b/include/automount.h
|
|
Ian Kent |
3685ec |
@@ -399,7 +399,6 @@ struct autofs_point {
|
|
Ian Kent |
3685ec |
unsigned logopt; /* Per map logging */
|
|
Ian Kent |
3685ec |
pthread_t exp_thread; /* Thread that is expiring */
|
|
Ian Kent |
3685ec |
pthread_t readmap_thread; /* Thread that is reading maps */
|
|
Ian Kent |
3685ec |
- pthread_mutex_t state_mutex; /* Protect state changes */
|
|
Ian Kent |
3685ec |
enum states state; /* Current state */
|
|
Ian Kent |
3685ec |
int state_pipe[2]; /* State change router pipe */
|
|
Ian Kent |
3685ec |
unsigned dir_created; /* Directory created for this mount? */
|
|
Ian Kent |
3685ec |
@@ -407,8 +406,6 @@ struct autofs_point {
|
|
Ian Kent |
3685ec |
* host from which to mount */
|
|
Ian Kent |
3685ec |
struct autofs_point *parent; /* Owner of mounts list for submount */
|
|
Ian Kent |
3685ec |
pthread_mutex_t mounts_mutex; /* Protect mount lists */
|
|
Ian Kent |
3685ec |
- pthread_cond_t mounts_cond; /* Submounts condition variable */
|
|
Ian Kent |
3685ec |
- unsigned int mounts_signaled; /* Submount signals task complete */
|
|
Ian Kent |
3685ec |
struct list_head mounts; /* List of autofs mounts at current level */
|
|
Ian Kent |
3685ec |
unsigned int submount; /* Is this a submount */
|
|
Ian Kent |
3685ec |
unsigned int shutdown; /* Shutdown notification */
|
|
Ian Kent |
3685ec |
@@ -446,20 +443,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
3685ec |
void rm_unwanted(unsigned logopt, const char *path, int incl, dev_t dev);
|
|
Ian Kent |
3685ec |
int count_mounts(unsigned logopt, const char *path, dev_t dev);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-#define state_mutex_lock(ap) \
|
|
Ian Kent |
3685ec |
-do { \
|
|
Ian Kent |
3685ec |
- int _st_lock = pthread_mutex_lock(&ap->state_mutex); \
|
|
Ian Kent |
3685ec |
- if (_st_lock) \
|
|
Ian Kent |
3685ec |
- fatal(_st_lock); \
|
|
Ian Kent |
3685ec |
-} while(0)
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
-#define state_mutex_unlock(ap) \
|
|
Ian Kent |
3685ec |
-do{ \
|
|
Ian Kent |
3685ec |
- int _st_unlock = pthread_mutex_unlock(&ap->state_mutex); \
|
|
Ian Kent |
3685ec |
- if (_st_unlock) \
|
|
Ian Kent |
3685ec |
- fatal(_st_unlock); \
|
|
Ian Kent |
3685ec |
-} while (0)
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
#define mounts_mutex_lock(ap) \
|
|
Ian Kent |
3685ec |
do { \
|
|
Ian Kent |
3685ec |
int _m_lock = pthread_mutex_lock(&ap->mounts_mutex); \
|
|
Ian Kent |
3685ec |
diff --git a/include/master.h b/include/master.h
|
|
Ian Kent |
3685ec |
index 5f10d1f..86ae045 100644
|
|
Ian Kent |
3685ec |
--- a/include/master.h
|
|
Ian Kent |
3685ec |
+++ b/include/master.h
|
|
Ian Kent |
3685ec |
@@ -20,10 +20,6 @@
|
|
Ian Kent |
3685ec |
#ifndef MASTER_H
|
|
Ian Kent |
3685ec |
#define MASTER_H
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-#define MASTER_SUBMNT_WAIT 0
|
|
Ian Kent |
3685ec |
-#define MASTER_SUBMNT_CONTINUE 1
|
|
Ian Kent |
3685ec |
-#define MASTER_SUBMNT_JOIN 2
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
struct map_source {
|
|
Ian Kent |
3685ec |
char *type;
|
|
Ian Kent |
3685ec |
char *format;
|
|
Ian Kent |
3685ec |
@@ -104,7 +100,6 @@ struct master *master_new(const char *, unsigned int, unsigned int);
|
|
Ian Kent |
3685ec |
int master_read_master(struct master *, time_t, int);
|
|
Ian Kent |
3685ec |
int master_submount_list_empty(struct autofs_point *ap);
|
|
Ian Kent |
3685ec |
int master_notify_submount(struct autofs_point *, const char *path, enum states);
|
|
Ian Kent |
3685ec |
-void master_signal_submount(struct autofs_point *, unsigned int);
|
|
Ian Kent |
3685ec |
void master_notify_state_change(struct master *, int);
|
|
Ian Kent |
3685ec |
int master_mount_mounts(struct master *, time_t, int);
|
|
Ian Kent |
3685ec |
extern inline unsigned int master_get_logopt(void);
|
|
Ian Kent |
3685ec |
diff --git a/include/state.h b/include/state.h
|
|
Ian Kent |
3685ec |
index 8aed234..d7349d9 100644
|
|
Ian Kent |
3685ec |
--- a/include/state.h
|
|
Ian Kent |
3685ec |
+++ b/include/state.h
|
|
Ian Kent |
3685ec |
@@ -38,7 +38,8 @@
|
|
Ian Kent |
3685ec |
*
|
|
Ian Kent |
3685ec |
*/
|
|
Ian Kent |
3685ec |
enum states {
|
|
Ian Kent |
3685ec |
- ST_INVAL = -1,
|
|
Ian Kent |
3685ec |
+ ST_ANY = -2,
|
|
Ian Kent |
3685ec |
+ ST_INVAL,
|
|
Ian Kent |
3685ec |
ST_INIT,
|
|
Ian Kent |
3685ec |
ST_READY,
|
|
Ian Kent |
3685ec |
ST_EXPIRE,
|
|
Ian Kent |
3685ec |
@@ -81,12 +82,18 @@ struct readmap_args {
|
|
Ian Kent |
3685ec |
time_t now; /* Time when map is read */
|
|
Ian Kent |
3685ec |
};
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+void st_mutex_lock(void);
|
|
Ian Kent |
3685ec |
+void st_mutex_unlock(void);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
void expire_cleanup(void *);
|
|
Ian Kent |
3685ec |
void expire_proc_cleanup(void *);
|
|
Ian Kent |
3685ec |
void nextstate(int, enum states);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
int st_add_task(struct autofs_point *, enum states);
|
|
Ian Kent |
3685ec |
+int __st_add_task(struct autofs_point *, enum states);
|
|
Ian Kent |
3685ec |
void st_remove_tasks(struct autofs_point *);
|
|
Ian Kent |
3685ec |
+int st_wait_task(struct autofs_point *, enum states, unsigned int);
|
|
Ian Kent |
3685ec |
+int st_wait_state(struct autofs_point *ap, enum states state);
|
|
Ian Kent |
3685ec |
int st_start_handler(void);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
#endif
|
|
Ian Kent |
3685ec |
diff --git a/lib/alarm.c b/lib/alarm.c
|
|
Ian Kent |
3685ec |
index 6a70ed1..1e32291 100755
|
|
Ian Kent |
3685ec |
--- a/lib/alarm.c
|
|
Ian Kent |
3685ec |
+++ b/lib/alarm.c
|
|
Ian Kent |
3685ec |
@@ -178,7 +178,6 @@ static void *alarm_handler(void *arg)
|
|
Ian Kent |
3685ec |
head = &alarms;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (1) {
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
if (list_empty(head)) {
|
|
Ian Kent |
3685ec |
/* No alarms, wait for one to be added */
|
|
Ian Kent |
3685ec |
status = pthread_cond_wait(&cond, &mutex);
|
|
Ian Kent |
3685ec |
@@ -211,19 +210,8 @@ static void *alarm_handler(void *arg)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (!first->cancel) {
|
|
Ian Kent |
3685ec |
struct autofs_point *ap = first->ap;
|
|
Ian Kent |
3685ec |
- /*
|
|
Ian Kent |
3685ec |
- * We need to unlock the alarm list in case
|
|
Ian Kent |
3685ec |
- * some other thread holds the state_mutex
|
|
Ian Kent |
3685ec |
- *_lock(ap), and is currently trying to do
|
|
Ian Kent |
3685ec |
- * some alarm_* function (i.e if we don't
|
|
Ian Kent |
3685ec |
- * unlock, we might deadlock).
|
|
Ian Kent |
3685ec |
- */
|
|
Ian Kent |
3685ec |
alarm_unlock();
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_EXPIRE);
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_EXPIRE);
|
|
Ian Kent |
3685ec |
alarm_lock();
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
free(first);
|
|
Ian Kent |
3685ec |
diff --git a/lib/master.c b/lib/master.c
|
|
Ian Kent |
3685ec |
index edd3bdc..522b919 100644
|
|
Ian Kent |
3685ec |
--- a/lib/master.c
|
|
Ian Kent |
3685ec |
+++ b/lib/master.c
|
|
Ian Kent |
3685ec |
@@ -90,41 +90,20 @@ int master_add_autofs_point(struct master_mapent *entry,
|
|
Ian Kent |
3685ec |
ap->logopt = logopt;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
ap->parent = NULL;
|
|
Ian Kent |
3685ec |
+ ap->thid = 0;
|
|
Ian Kent |
3685ec |
ap->submnt_count = 0;
|
|
Ian Kent |
3685ec |
ap->submount = submount;
|
|
Ian Kent |
3685ec |
INIT_LIST_HEAD(&ap->mounts);
|
|
Ian Kent |
3685ec |
INIT_LIST_HEAD(&ap->submounts);
|
|
Ian Kent |
3685ec |
ap->shutdown = 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_init(&ap->state_mutex, NULL);
|
|
Ian Kent |
3685ec |
- if (status) {
|
|
Ian Kent |
3685ec |
- free(ap->path);
|
|
Ian Kent |
3685ec |
- free(ap);
|
|
Ian Kent |
3685ec |
- return 0;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
status = pthread_mutex_init(&ap->mounts_mutex, NULL);
|
|
Ian Kent |
3685ec |
if (status) {
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_destroy(&ap->state_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
free(ap->path);
|
|
Ian Kent |
3685ec |
free(ap);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- status = pthread_cond_init(&ap->mounts_cond, NULL);
|
|
Ian Kent |
3685ec |
- if (status) {
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_destroy(&ap->mounts_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_destroy(&ap->state_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- free(ap->path);
|
|
Ian Kent |
3685ec |
- free(ap);
|
|
Ian Kent |
3685ec |
- return 0;
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
entry->ap = ap;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
@@ -137,18 +116,10 @@ void master_free_autofs_point(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
if (!ap)
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_destroy(&ap->state_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
status = pthread_mutex_destroy(&ap->mounts_mutex);
|
|
Ian Kent |
3685ec |
if (status)
|
|
Ian Kent |
3685ec |
fatal(status);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- status = pthread_cond_destroy(&ap->mounts_cond);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
free(ap->path);
|
|
Ian Kent |
3685ec |
free(ap);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -295,11 +266,9 @@ struct map_source *master_find_map_source(struct master_mapent *entry,
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct map_source *source = NULL;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- master_mutex_lock();
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
+ master_source_readlock(entry);
|
|
Ian Kent |
3685ec |
source = __master_find_map_source(entry, type, format, argc, argv);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- master_mutex_unlock();
|
|
Ian Kent |
3685ec |
+ master_source_unlock(entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return source;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -519,13 +488,7 @@ void send_map_update_request(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
if (!need_update)
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_lock(&ap->state_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- nextstate(ap->state_pipe[1], ST_READMAP);
|
|
Ian Kent |
3685ec |
- status = pthread_mutex_unlock(&ap->state_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_READMAP);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -695,17 +658,13 @@ void master_remove_mapent(struct master_mapent *entry)
|
|
Ian Kent |
3685ec |
if (entry->ap->submount)
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- master_mutex_lock();
|
|
Ian Kent |
3685ec |
if (!list_empty(&entry->list))
|
|
Ian Kent |
3685ec |
list_del_init(&entry->list);
|
|
Ian Kent |
3685ec |
- master_mutex_unlock();
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
void master_free_mapent_sources(struct master_mapent *entry, unsigned int free_cache)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
- master_source_writelock(entry);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
if (entry->maps) {
|
|
Ian Kent |
3685ec |
struct map_source *m, *n;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -718,8 +677,6 @@ void master_free_mapent_sources(struct master_mapent *entry, unsigned int free_c
|
|
Ian Kent |
3685ec |
entry->maps = NULL;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- master_source_unlock(entry);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -827,10 +784,9 @@ int master_submount_list_empty(struct autofs_point *ap)
|
|
Ian Kent |
3685ec |
int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct list_head *head, *p;
|
|
Ian Kent |
3685ec |
- struct autofs_point *this;
|
|
Ian Kent |
3685ec |
- pthread_t thid;
|
|
Ian Kent |
3685ec |
+ struct autofs_point *this = NULL;
|
|
Ian Kent |
3685ec |
size_t plen = strlen(path);
|
|
Ian Kent |
3685ec |
- int status, ret = 1;
|
|
Ian Kent |
3685ec |
+ int ret = 1;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mounts_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -869,33 +825,25 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* Now we have a submount to expire */
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(this);
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (this->state == ST_SHUTDOWN) {
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(this);
|
|
Ian Kent |
3685ec |
+ this = NULL;
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- nextstate(this->state_pipe[1], state);
|
|
Ian Kent |
3685ec |
+ this->shutdown = ap->shutdown;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(this);
|
|
Ian Kent |
3685ec |
+ __st_add_task(this, state);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- thid = this->thid;
|
|
Ian Kent |
3685ec |
- ap->mounts_signaled = MASTER_SUBMNT_WAIT;
|
|
Ian Kent |
3685ec |
- while (ap->mounts_signaled == MASTER_SUBMNT_WAIT) {
|
|
Ian Kent |
3685ec |
- status = pthread_cond_wait(&ap->mounts_cond, &ap->mounts_mutex);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
+ mounts_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- if (ap->mounts_signaled == MASTER_SUBMNT_JOIN) {
|
|
Ian Kent |
3685ec |
- status = pthread_join(thid, NULL);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
- } else
|
|
Ian Kent |
3685ec |
- ret = 0;
|
|
Ian Kent |
3685ec |
+ st_wait_task(this, state, 0);
|
|
Ian Kent |
3685ec |
+
|
|
Ian Kent |
3685ec |
+ return ret;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- break;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
mounts_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
@@ -903,38 +851,12 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state
|
|
Ian Kent |
3685ec |
return ret;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-void master_signal_submount(struct autofs_point *ap, unsigned int join)
|
|
Ian Kent |
3685ec |
-{
|
|
Ian Kent |
3685ec |
- int status;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (!ap->parent || !ap->submount)
|
|
Ian Kent |
3685ec |
- return;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- mounts_mutex_lock(ap->parent);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- ap->parent->mounts_signaled = join;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- if (join == MASTER_SUBMNT_JOIN) {
|
|
Ian Kent |
3685ec |
- /* We are finishing up */
|
|
Ian Kent |
3685ec |
- ap->parent->submnt_count--;
|
|
Ian Kent |
3685ec |
- list_del(&ap->mounts);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- status = pthread_cond_signal(&ap->parent->mounts_cond);
|
|
Ian Kent |
3685ec |
- if (status)
|
|
Ian Kent |
3685ec |
- fatal(status);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- mounts_mutex_unlock(ap->parent);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- return;
|
|
Ian Kent |
3685ec |
-}
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
void master_notify_state_change(struct master *master, int sig)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct master_mapent *entry;
|
|
Ian Kent |
3685ec |
struct autofs_point *ap;
|
|
Ian Kent |
3685ec |
struct list_head *p;
|
|
Ian Kent |
3685ec |
- int state_pipe, cur_state;
|
|
Ian Kent |
3685ec |
+ int cur_state;
|
|
Ian Kent |
3685ec |
unsigned int logopt;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
Ian Kent |
3685ec |
@@ -948,13 +870,11 @@ void master_notify_state_change(struct master *master, int sig)
|
|
Ian Kent |
3685ec |
ap = entry->ap;
|
|
Ian Kent |
3685ec |
logopt = ap->logopt;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (ap->state == ST_SHUTDOWN)
|
|
Ian Kent |
3685ec |
goto next;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_pipe = ap->state_pipe[1];
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
switch (sig) {
|
|
Ian Kent |
3685ec |
case SIGTERM:
|
|
Ian Kent |
3685ec |
case SIGINT:
|
|
Ian Kent |
3685ec |
@@ -962,7 +882,7 @@ void master_notify_state_change(struct master *master, int sig)
|
|
Ian Kent |
3685ec |
ap->state != ST_SHUTDOWN_FORCE) {
|
|
Ian Kent |
3685ec |
next = ST_SHUTDOWN_PENDING;
|
|
Ian Kent |
3685ec |
ap->shutdown = 1;
|
|
Ian Kent |
3685ec |
- nextstate(state_pipe, next);
|
|
Ian Kent |
3685ec |
+ __st_add_task(ap, next);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
#ifdef ENABLE_FORCED_SHUTDOWN
|
|
Ian Kent |
3685ec |
@@ -970,14 +890,15 @@ void master_notify_state_change(struct master *master, int sig)
|
|
Ian Kent |
3685ec |
if (ap->state != ST_SHUTDOWN_FORCE &&
|
|
Ian Kent |
3685ec |
ap->state != ST_SHUTDOWN_PENDING) {
|
|
Ian Kent |
3685ec |
next = ST_SHUTDOWN_FORCE;
|
|
Ian Kent |
3685ec |
- nextstate(state_pipe, next);
|
|
Ian Kent |
3685ec |
+ ap->shutdown = 1;
|
|
Ian Kent |
3685ec |
+ __st_add_task(ap, next);
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
#endif
|
|
Ian Kent |
3685ec |
case SIGUSR1:
|
|
Ian Kent |
3685ec |
assert(ap->state == ST_READY);
|
|
Ian Kent |
3685ec |
next = ST_PRUNE;
|
|
Ian Kent |
3685ec |
- nextstate(state_pipe, next);
|
|
Ian Kent |
3685ec |
+ __st_add_task(ap, next);
|
|
Ian Kent |
3685ec |
break;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
next:
|
|
Ian Kent |
3685ec |
@@ -986,7 +907,7 @@ next:
|
|
Ian Kent |
3685ec |
"sig %d switching %s from %d to %d",
|
|
Ian Kent |
3685ec |
sig, ap->path, ap->state, next);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
master_mutex_unlock();
|
|
Ian Kent |
3685ec |
@@ -1024,7 +945,6 @@ static int master_do_mount(struct master_mapent *entry)
|
|
Ian Kent |
3685ec |
handle_mounts_startup_cond_destroy(&suc);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- entry->thid = thid;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (!suc.done) {
|
|
Ian Kent |
3685ec |
status = pthread_cond_wait(&suc.cond, &suc.mutex);
|
|
Ian Kent |
3685ec |
@@ -1037,45 +957,18 @@ static int master_do_mount(struct master_mapent *entry)
|
|
Ian Kent |
3685ec |
handle_mounts_startup_cond_destroy(&suc);
|
|
Ian Kent |
3685ec |
return 0;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
+ entry->thid = thid;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
handle_mounts_startup_cond_destroy(&suc);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
-static void shutdown_entry(struct master_mapent *entry)
|
|
Ian Kent |
3685ec |
-{
|
|
Ian Kent |
3685ec |
- int state_pipe;
|
|
Ian Kent |
3685ec |
- struct autofs_point *ap;
|
|
Ian Kent |
3685ec |
- struct stat st;
|
|
Ian Kent |
3685ec |
- int ret;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- ap = entry->ap;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- debug(ap->logopt, "%s", entry->path);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- state_pipe = ap->state_pipe[1];
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- ret = fstat(state_pipe, &st);
|
|
Ian Kent |
3685ec |
- if (ret == -1)
|
|
Ian Kent |
3685ec |
- goto next;
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- nextstate(state_pipe, ST_SHUTDOWN_PENDING);
|
|
Ian Kent |
3685ec |
-next:
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- return;
|
|
Ian Kent |
3685ec |
-}
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
static void check_update_map_sources(struct master_mapent *entry, int readall)
|
|
Ian Kent |
3685ec |
{
|
|
Ian Kent |
3685ec |
struct map_source *source, *last;
|
|
Ian Kent |
3685ec |
- int state_pipe, map_stale = 0;
|
|
Ian Kent |
3685ec |
struct autofs_point *ap;
|
|
Ian Kent |
3685ec |
- struct stat st;
|
|
Ian Kent |
3685ec |
- int ret;
|
|
Ian Kent |
3685ec |
+ int map_stale = 0;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (readall)
|
|
Ian Kent |
3685ec |
map_stale = 1;
|
|
Ian Kent |
3685ec |
@@ -1128,17 +1021,8 @@ static void check_update_map_sources(struct master_mapent *entry, int readall)
|
|
Ian Kent |
3685ec |
master_source_unlock(entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* The map sources have changed */
|
|
Ian Kent |
3685ec |
- if (map_stale) {
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- state_pipe = entry->ap->state_pipe[1];
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- ret = fstat(state_pipe, &st);
|
|
Ian Kent |
3685ec |
- if (ret != -1)
|
|
Ian Kent |
3685ec |
- nextstate(state_pipe, ST_READMAP);
|
|
Ian Kent |
3685ec |
-
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
- }
|
|
Ian Kent |
3685ec |
+ if (map_stale)
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_READMAP);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
return;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
@@ -1169,17 +1053,19 @@ int master_mount_mounts(struct master *master, time_t age, int readall)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
/* A master map entry has gone away */
|
|
Ian Kent |
3685ec |
if (this->age < age) {
|
|
Ian Kent |
3685ec |
- shutdown_entry(this);
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_SHUTDOWN_PENDING);
|
|
Ian Kent |
3685ec |
continue;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
+ master_source_writelock(ap->entry);
|
|
Ian Kent |
3685ec |
lookup_close_lookup(ap);
|
|
Ian Kent |
3685ec |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
cache_readlock(nc);
|
|
Ian Kent |
3685ec |
ne = cache_lookup_distinct(nc, this->path);
|
|
Ian Kent |
3685ec |
if (ne && this->age > ne->age) {
|
|
Ian Kent |
3685ec |
cache_unlock(nc);
|
|
Ian Kent |
3685ec |
- shutdown_entry(this);
|
|
Ian Kent |
3685ec |
+ st_add_task(ap, ST_SHUTDOWN_PENDING);
|
|
Ian Kent |
3685ec |
continue;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
nested = cache_partial_match(nc, this->path);
|
|
Ian Kent |
3685ec |
@@ -1195,7 +1081,7 @@ int master_mount_mounts(struct master *master, time_t age, int readall)
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
check_update_map_sources(this, readall);
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_lock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_lock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
state_pipe = this->ap->state_pipe[1];
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
@@ -1203,7 +1089,7 @@ int master_mount_mounts(struct master *master, time_t age, int readall)
|
|
Ian Kent |
3685ec |
ret = fstat(state_pipe, &st);
|
|
Ian Kent |
3685ec |
save_errno = errno;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
- state_mutex_unlock(ap);
|
|
Ian Kent |
3685ec |
+ st_mutex_unlock();
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
if (ret == -1 && save_errno == EBADF)
|
|
Ian Kent |
3685ec |
if (!master_do_mount(this)) {
|
|
Ian Kent |
3685ec |
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
|
|
Ian Kent |
3685ec |
index 6f66564..d6cbda8 100644
|
|
Ian Kent |
3685ec |
--- a/modules/mount_autofs.c
|
|
Ian Kent |
3685ec |
+++ b/modules/mount_autofs.c
|
|
Ian Kent |
3685ec |
@@ -242,7 +242,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
Ian Kent |
3685ec |
master_free_mapent(entry);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
- nap->thid = thid;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
while (!suc.done) {
|
|
Ian Kent |
3685ec |
status = pthread_cond_wait(&suc.cond, &suc.mutex);
|
|
Ian Kent |
3685ec |
@@ -264,6 +263,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
|
Ian Kent |
3685ec |
master_free_mapent(entry);
|
|
Ian Kent |
3685ec |
return 1;
|
|
Ian Kent |
3685ec |
}
|
|
Ian Kent |
3685ec |
+ nap->thid = thid;
|
|
Ian Kent |
3685ec |
|
|
Ian Kent |
3685ec |
ap->submnt_count++;
|
|
Ian Kent |
3685ec |
list_add(&nap->mounts, &ap->submounts);
|