|
Ian Kent |
9ef58b |
autofs-5.0.4 - improve manual umount recovery
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
From: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
The check for manually umounted mounts in the expire of direct mounts is
|
|
Ian Kent |
9ef58b |
racy and the check itself is inadequate in that it can incorrectly clear
|
|
Ian Kent |
9ef58b |
the descriptor of an active mount. Also, we do a similar test following
|
|
Ian Kent |
9ef58b |
the expire which is a waste since we can catch this on the next expire.
|
|
Ian Kent |
9ef58b |
So these two tests have been combined and the check done only prior to
|
|
Ian Kent |
9ef58b |
the expire. In the indirect expire we don't have a check at all so we
|
|
Ian Kent |
9ef58b |
add one.
|
|
Ian Kent |
9ef58b |
---
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
CHANGELOG | 1 +
|
|
Ian Kent |
9ef58b |
daemon/direct.c | 28 ++++++++++------------------
|
|
Ian Kent |
9ef58b |
daemon/indirect.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
|
|
Ian Kent |
9ef58b |
3 files changed, 57 insertions(+), 19 deletions(-)
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
diff --git a/CHANGELOG b/CHANGELOG
|
|
Ian Kent |
9ef58b |
index 5e01812..89aaa99 100644
|
|
Ian Kent |
9ef58b |
--- a/CHANGELOG
|
|
Ian Kent |
9ef58b |
+++ b/CHANGELOG
|
|
Ian Kent |
9ef58b |
@@ -45,6 +45,7 @@
|
|
Ian Kent |
9ef58b |
- fix kernel includes.
|
|
Ian Kent |
9ef58b |
- dont umount existing direct mount on master re-read.
|
|
Ian Kent |
9ef58b |
- fix incorrect shutdown introduced by library relaod fixes.
|
|
Ian Kent |
9ef58b |
+- improve manual umount recovery.
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
4/11/2008 autofs-5.0.4
|
|
Ian Kent |
9ef58b |
-----------------------
|
|
Ian Kent |
9ef58b |
diff --git a/daemon/direct.c b/daemon/direct.c
|
|
Ian Kent |
9ef58b |
index 4f4ff20..1ed2b15 100644
|
|
Ian Kent |
9ef58b |
--- a/daemon/direct.c
|
|
Ian Kent |
9ef58b |
+++ b/daemon/direct.c
|
|
Ian Kent |
9ef58b |
@@ -881,13 +881,14 @@ void *expire_proc_direct(void *arg)
|
|
Ian Kent |
9ef58b |
* avoid maintaining a file handle for control
|
|
Ian Kent |
9ef58b |
* functions as once it's mounted all opens are
|
|
Ian Kent |
9ef58b |
* directed to the mount not the trigger.
|
|
Ian Kent |
9ef58b |
- * But first expire possible rootless offsets first.
|
|
Ian Kent |
9ef58b |
*/
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
- /* Offsets always have a real mount at their base */
|
|
Ian Kent |
9ef58b |
+ /* Check for manual umount */
|
|
Ian Kent |
9ef58b |
cache_writelock(me->mc);
|
|
Ian Kent |
9ef58b |
- if (strstr(next->opts, "offset")) {
|
|
Ian Kent |
9ef58b |
- ops->close(ap->logopt, me->ioctlfd);
|
|
Ian Kent |
9ef58b |
+ if (me->ioctlfd != -1 &&
|
|
Ian Kent |
9ef58b |
+ fstat(ioctlfd, &st) != -1 &&
|
|
Ian Kent |
9ef58b |
+ !count_mounts(ap->logopt, next->path, st.st_dev)) {
|
|
Ian Kent |
9ef58b |
+ ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
9ef58b |
me->ioctlfd = -1;
|
|
Ian Kent |
9ef58b |
cache_unlock(me->mc);
|
|
Ian Kent |
9ef58b |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
9ef58b |
@@ -904,15 +905,6 @@ void *expire_proc_direct(void *arg)
|
|
Ian Kent |
9ef58b |
continue;
|
|
Ian Kent |
9ef58b |
}
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
- cache_writelock(me->mc);
|
|
Ian Kent |
9ef58b |
- if (me->ioctlfd != -1 &&
|
|
Ian Kent |
9ef58b |
- fstat(ioctlfd, &st) != -1 &&
|
|
Ian Kent |
9ef58b |
- !count_mounts(ap->logopt, next->path, st.st_dev)) {
|
|
Ian Kent |
9ef58b |
- ops->close(ap->logopt, ioctlfd);
|
|
Ian Kent |
9ef58b |
- me->ioctlfd = -1;
|
|
Ian Kent |
9ef58b |
- }
|
|
Ian Kent |
9ef58b |
- cache_unlock(me->mc);
|
|
Ian Kent |
9ef58b |
-
|
|
Ian Kent |
9ef58b |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
9ef58b |
continue;
|
|
Ian Kent |
9ef58b |
}
|
|
Ian Kent |
9ef58b |
@@ -1068,7 +1060,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
|
Ian Kent |
9ef58b |
map = ap->entry->maps;
|
|
Ian Kent |
9ef58b |
while (map) {
|
|
Ian Kent |
9ef58b |
mc = map->mc;
|
|
Ian Kent |
9ef58b |
- cache_readlock(mc);
|
|
Ian Kent |
9ef58b |
+ cache_writelock(mc);
|
|
Ian Kent |
9ef58b |
me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
|
|
Ian Kent |
9ef58b |
if (me)
|
|
Ian Kent |
9ef58b |
break;
|
|
Ian Kent |
9ef58b |
@@ -1345,7 +1337,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
9ef58b |
}
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
mc = map->mc;
|
|
Ian Kent |
9ef58b |
- cache_readlock(mc);
|
|
Ian Kent |
9ef58b |
+ cache_writelock(mc);
|
|
Ian Kent |
9ef58b |
me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
|
|
Ian Kent |
9ef58b |
if (me)
|
|
Ian Kent |
9ef58b |
break;
|
|
Ian Kent |
9ef58b |
@@ -1367,10 +1359,10 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
if (me->ioctlfd != -1) {
|
|
Ian Kent |
9ef58b |
/* Maybe someone did a manual umount, clean up ! */
|
|
Ian Kent |
9ef58b |
- ioctlfd = me->ioctlfd;
|
|
Ian Kent |
9ef58b |
+ close(me->ioctlfd);
|
|
Ian Kent |
9ef58b |
me->ioctlfd = -1;
|
|
Ian Kent |
9ef58b |
- } else
|
|
Ian Kent |
9ef58b |
- ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
|
|
Ian Kent |
9ef58b |
+ }
|
|
Ian Kent |
9ef58b |
+ ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
if (ioctlfd == -1) {
|
|
Ian Kent |
9ef58b |
cache_unlock(mc);
|
|
Ian Kent |
9ef58b |
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
|
Ian Kent |
9ef58b |
index 2539282..bc39e63 100644
|
|
Ian Kent |
9ef58b |
--- a/daemon/indirect.c
|
|
Ian Kent |
9ef58b |
+++ b/daemon/indirect.c
|
|
Ian Kent |
9ef58b |
@@ -428,8 +428,53 @@ void *expire_proc_indirect(void *arg)
|
|
Ian Kent |
9ef58b |
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
|
Ian Kent |
9ef58b |
if (strstr(next->opts, "indirect"))
|
|
Ian Kent |
9ef58b |
master_notify_submount(ap, next->path, ap->state);
|
|
Ian Kent |
9ef58b |
- pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
9ef58b |
+ else if (strstr(next->opts, "offset")) {
|
|
Ian Kent |
9ef58b |
+ struct map_source *map;
|
|
Ian Kent |
9ef58b |
+ struct mapent_cache *mc = NULL;
|
|
Ian Kent |
9ef58b |
+ struct mapent *me = NULL;
|
|
Ian Kent |
9ef58b |
+ struct stat st;
|
|
Ian Kent |
9ef58b |
+
|
|
Ian Kent |
9ef58b |
+ master_source_readlock(ap->entry);
|
|
Ian Kent |
9ef58b |
+
|
|
Ian Kent |
9ef58b |
+ map = ap->entry->maps;
|
|
Ian Kent |
9ef58b |
+ while (map) {
|
|
Ian Kent |
9ef58b |
+ mc = map->mc;
|
|
Ian Kent |
9ef58b |
+ cache_writelock(mc);
|
|
Ian Kent |
9ef58b |
+ me = cache_lookup_distinct(mc, next->path);
|
|
Ian Kent |
9ef58b |
+ if (me)
|
|
Ian Kent |
9ef58b |
+ break;
|
|
Ian Kent |
9ef58b |
+ cache_unlock(mc);
|
|
Ian Kent |
9ef58b |
+ map = map->next;
|
|
Ian Kent |
9ef58b |
+ }
|
|
Ian Kent |
9ef58b |
|
|
Ian Kent |
9ef58b |
+ if (!mc || !me) {
|
|
Ian Kent |
9ef58b |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
9ef58b |
+ pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
9ef58b |
+ continue;
|
|
Ian Kent |
9ef58b |
+ }
|
|
Ian Kent |
9ef58b |
+
|
|
Ian Kent |
9ef58b |
+ /* Check for manual umount */
|
|
Ian Kent |
9ef58b |
+ if (me->ioctlfd != -1 &&
|
|
Ian Kent |
9ef58b |
+ (fstat(me->ioctlfd, &st) == -1 ||
|
|
Ian Kent |
9ef58b |
+ !count_mounts(ap->logopt, me->key, st.st_dev))) {
|
|
Ian Kent |
9ef58b |
+ if (is_mounted(_PROC_MOUNTS, me->key, MNTS_REAL)) {
|
|
Ian Kent |
9ef58b |
+ error(ap->logopt,
|
|
Ian Kent |
9ef58b |
+ "error: possible mtab mismatch %s",
|
|
Ian Kent |
9ef58b |
+ me->key);
|
|
Ian Kent |
9ef58b |
+ cache_unlock(mc);
|
|
Ian Kent |
9ef58b |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
9ef58b |
+ pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
9ef58b |
+ continue;
|
|
Ian Kent |
9ef58b |
+ }
|
|
Ian Kent |
9ef58b |
+ close(me->ioctlfd);
|
|
Ian Kent |
9ef58b |
+ me->ioctlfd = -1;
|
|
Ian Kent |
9ef58b |
+ }
|
|
Ian Kent |
9ef58b |
+
|
|
Ian Kent |
9ef58b |
+ cache_unlock(mc);
|
|
Ian Kent |
9ef58b |
+ master_source_unlock(ap->entry);
|
|
Ian Kent |
9ef58b |
+ }
|
|
Ian Kent |
9ef58b |
+
|
|
Ian Kent |
9ef58b |
+ pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
9ef58b |
continue;
|
|
Ian Kent |
9ef58b |
}
|
|
Ian Kent |
9ef58b |
|