|
Ian Kent |
cc58c1 |
autofs-5.0.6 - fix remount deadlock
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
From: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
When reconstructing the mount tree upon restart a writelock to the map
|
|
Ian Kent |
cc58c1 |
entry cache cannot be taken when parsing a direct map entry because a
|
|
Ian Kent |
cc58c1 |
readlock is already held higher up in the call tree.
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
In the place this is done it isn't be necessary to alter the direct map
|
|
Ian Kent |
cc58c1 |
entries in the cache. Also, it shouldn't be necessary to delete existing
|
|
Ian Kent |
cc58c1 |
multi-mount cache entries to avoid a duplicate multi-mount entry error
|
|
Ian Kent |
cc58c1 |
return. The check for a duplicate can be done in the cache handling
|
|
Ian Kent |
cc58c1 |
functions.
|
|
Ian Kent |
cc58c1 |
---
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
CHANGELOG | 1
|
|
Ian Kent |
cc58c1 |
lib/cache.c | 8 ++++--
|
|
Ian Kent |
cc58c1 |
modules/parse_sun.c | 60 ++++++++++++++++++++++++++--------------------------
|
|
Ian Kent |
cc58c1 |
3 files changed, 36 insertions(+), 33 deletions(-)
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
--- autofs-5.0.6.orig/CHANGELOG
|
|
Ian Kent |
cc58c1 |
+++ autofs-5.0.6/CHANGELOG
|
|
Ian Kent |
cc58c1 |
@@ -52,6 +52,7 @@
|
|
Ian Kent |
cc58c1 |
- fix nfs4 contacts portmap.
|
|
Ian Kent |
cc58c1 |
- make autofs wait longer for shutdown completion.
|
|
Ian Kent |
cc58c1 |
- fix sss map age not updated.
|
|
Ian Kent |
cc58c1 |
+- fix remount deadlock.
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
28/06/2011 autofs-5.0.6
|
|
Ian Kent |
cc58c1 |
-----------------------
|
|
Ian Kent |
cc58c1 |
--- autofs-5.0.6.orig/lib/cache.c
|
|
Ian Kent |
cc58c1 |
+++ autofs-5.0.6/lib/cache.c
|
|
Ian Kent |
cc58c1 |
@@ -658,10 +658,12 @@ int cache_add_offset(struct mapent_cache
|
|
Ian Kent |
cc58c1 |
return CHE_FAIL;
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
me = cache_lookup_distinct(mc, key);
|
|
Ian Kent |
cc58c1 |
- if (me && me != owner)
|
|
Ian Kent |
cc58c1 |
- return CHE_DUPLICATE;
|
|
Ian Kent |
cc58c1 |
+ if (me && me->age == age) {
|
|
Ian Kent |
cc58c1 |
+ if (me != owner)
|
|
Ian Kent |
cc58c1 |
+ return CHE_DUPLICATE;
|
|
Ian Kent |
cc58c1 |
+ }
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
- ret = cache_add(mc, owner->source, key, mapent, age);
|
|
Ian Kent |
cc58c1 |
+ ret = cache_update(mc, owner->source, key, mapent, age);
|
|
Ian Kent |
cc58c1 |
if (ret == CHE_FAIL) {
|
|
Ian Kent |
cc58c1 |
warn(logopt, "failed to add key %s to cache", key);
|
|
Ian Kent |
cc58c1 |
return CHE_FAIL;
|
|
Ian Kent |
cc58c1 |
--- autofs-5.0.6.orig/modules/parse_sun.c
|
|
Ian Kent |
cc58c1 |
+++ autofs-5.0.6/modules/parse_sun.c
|
|
Ian Kent |
cc58c1 |
@@ -843,12 +843,17 @@ add_offset_entry(struct autofs_point *ap
|
|
Ian Kent |
cc58c1 |
strcpy(m_mapent, loc);
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
ret = cache_add_offset(mc, name, m_key, m_mapent, age);
|
|
Ian Kent |
cc58c1 |
- if (ret == CHE_OK)
|
|
Ian Kent |
cc58c1 |
+ if (ret == CHE_DUPLICATE)
|
|
Ian Kent |
cc58c1 |
+ warn(ap->logopt, MODPREFIX
|
|
Ian Kent |
cc58c1 |
+ "syntax error or duplicate offset %s -> %s", path, loc);
|
|
Ian Kent |
cc58c1 |
+ else if (ret == CHE_FAIL)
|
|
Ian Kent |
cc58c1 |
+ debug(ap->logopt, MODPREFIX
|
|
Ian Kent |
cc58c1 |
+ "failed to add multi-mount offset %s -> %s", path, m_mapent);
|
|
Ian Kent |
cc58c1 |
+ else {
|
|
Ian Kent |
cc58c1 |
+ ret = CHE_OK;
|
|
Ian Kent |
cc58c1 |
debug(ap->logopt, MODPREFIX
|
|
Ian Kent |
cc58c1 |
"added multi-mount offset %s -> %s", path, m_mapent);
|
|
Ian Kent |
cc58c1 |
- else
|
|
Ian Kent |
cc58c1 |
- warn(ap->logopt, MODPREFIX
|
|
Ian Kent |
cc58c1 |
- "syntax error or duplicate offset %s -> %s", path, loc);
|
|
Ian Kent |
cc58c1 |
+ }
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
return ret;
|
|
Ian Kent |
cc58c1 |
}
|
|
Ian Kent |
cc58c1 |
@@ -1410,7 +1415,7 @@ int parse_mount(struct autofs_point *ap,
|
|
Ian Kent |
cc58c1 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
cc58c1 |
struct map_source *source;
|
|
Ian Kent |
cc58c1 |
struct mapent_cache *mc;
|
|
Ian Kent |
cc58c1 |
- struct mapent *me = NULL;
|
|
Ian Kent |
cc58c1 |
+ struct mapent *me;
|
|
Ian Kent |
cc58c1 |
char *pmapent, *options;
|
|
Ian Kent |
cc58c1 |
const char *p;
|
|
Ian Kent |
cc58c1 |
int mapent_len, rv = 0;
|
|
Ian Kent |
cc58c1 |
@@ -1561,33 +1566,28 @@ int parse_mount(struct autofs_point *ap,
|
|
Ian Kent |
cc58c1 |
strcat(m_root, name);
|
|
Ian Kent |
cc58c1 |
}
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
- cache_writelock(mc);
|
|
Ian Kent |
cc58c1 |
- me = cache_lookup_distinct(mc, name);
|
|
Ian Kent |
cc58c1 |
- if (!me) {
|
|
Ian Kent |
cc58c1 |
- int ret;
|
|
Ian Kent |
cc58c1 |
- /*
|
|
Ian Kent |
cc58c1 |
- * Not in the cache, perhaps it's a program map
|
|
Ian Kent |
cc58c1 |
- * or one that doesn't support enumeration
|
|
Ian Kent |
cc58c1 |
- */
|
|
Ian Kent |
cc58c1 |
- ret = cache_add(mc, source, name, mapent, time(NULL));
|
|
Ian Kent |
cc58c1 |
- if (ret == CHE_FAIL) {
|
|
Ian Kent |
cc58c1 |
- cache_unlock(mc);
|
|
Ian Kent |
cc58c1 |
- free(options);
|
|
Ian Kent |
cc58c1 |
- return 1;
|
|
Ian Kent |
cc58c1 |
+ /*
|
|
Ian Kent |
cc58c1 |
+ * Can't take the write lock for direct mount entries here
|
|
Ian Kent |
cc58c1 |
+ * but they should always be present in the map entry cache.
|
|
Ian Kent |
cc58c1 |
+ */
|
|
Ian Kent |
cc58c1 |
+ if (ap->type == LKP_INDIRECT) {
|
|
Ian Kent |
cc58c1 |
+ cache_writelock(mc);
|
|
Ian Kent |
cc58c1 |
+ me = cache_lookup_distinct(mc, name);
|
|
Ian Kent |
cc58c1 |
+ if (!me) {
|
|
Ian Kent |
cc58c1 |
+ int ret;
|
|
Ian Kent |
cc58c1 |
+ /*
|
|
Ian Kent |
cc58c1 |
+ * Not in the cache, perhaps it's a program map
|
|
Ian Kent |
cc58c1 |
+ * or one that doesn't support enumeration.
|
|
Ian Kent |
cc58c1 |
+ */
|
|
Ian Kent |
cc58c1 |
+ ret = cache_add(mc, source, name, mapent, age);
|
|
Ian Kent |
cc58c1 |
+ if (ret == CHE_FAIL) {
|
|
Ian Kent |
cc58c1 |
+ cache_unlock(mc);
|
|
Ian Kent |
cc58c1 |
+ free(options);
|
|
Ian Kent |
cc58c1 |
+ return 1;
|
|
Ian Kent |
cc58c1 |
+ }
|
|
Ian Kent |
cc58c1 |
}
|
|
Ian Kent |
cc58c1 |
- } else {
|
|
Ian Kent |
cc58c1 |
- /*
|
|
Ian Kent |
cc58c1 |
- * If the entry exists it must not have any existing
|
|
Ian Kent |
cc58c1 |
- * multi-mount subordinate entries since we are
|
|
Ian Kent |
cc58c1 |
- * mounting this afresh. We need to do this to allow
|
|
Ian Kent |
cc58c1 |
- * us to fail on the check for duplicate offsets in
|
|
Ian Kent |
cc58c1 |
- * we don't know when submounts go away.
|
|
Ian Kent |
cc58c1 |
- */
|
|
Ian Kent |
cc58c1 |
- cache_multi_writelock(me);
|
|
Ian Kent |
cc58c1 |
- cache_delete_offset_list(mc, name);
|
|
Ian Kent |
cc58c1 |
- cache_multi_unlock(me);
|
|
Ian Kent |
cc58c1 |
+ cache_unlock(mc);
|
|
Ian Kent |
cc58c1 |
}
|
|
Ian Kent |
cc58c1 |
- cache_unlock(mc);
|
|
Ian Kent |
cc58c1 |
|
|
Ian Kent |
cc58c1 |
cache_readlock(mc);
|
|
Ian Kent |
cc58c1 |
me = cache_lookup_distinct(mc, name);
|