aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2022-11-08 14:14:07 +0800
committerIan Kent <raven@themaw.net>2022-11-27 08:14:11 +0800
commitb3b8efbb5d0bef046238d82391821d421920c913 (patch)
tree6fb01382885014203dbb6a6f0ec1e243f0401123
parenta83b45e5fe2d7629da5a3c7efd9549747bcb9e67 (diff)
downloadautofs-b3b8efbb5d0bef046238d82391821d421920c913.tar.gz
autofs-5.1.8 - fix hosts map deadlock on restart
When starting automount(8) with a hosts map that has mounts that were in use at the last exit a deadlock can occur. In this case automount(8) will perform the same steps but not actually perform the mount to re-construct the context of each mount. But, with the hosts map, that leads to calling back into the sun parse module while holding the map module read lock which will again try and take the write lock. Fix this by only taking the write lock in the mount code path if the module handle has not already been opened. Signed-off-by: Ian Kent <raven@themaw.net>
-rw-r--r--CHANGELOG1
-rw-r--r--daemon/lookup.c22
-rw-r--r--modules/parse_amd.c18
3 files changed, 23 insertions, 18 deletions
diff --git a/CHANGELOG b/CHANGELOG
index c75ff9ad..a83bc875 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -44,6 +44,7 @@
- fix parse module instance mutex naming.
- serialise lookup module open and reinit.
- coverity fix for invalid access.
+- fix hosts map deadlock on restart.
19/10/2021 autofs-5.1.8
- add xdr_exports().
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 26026a12..29f43d24 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -809,19 +809,21 @@ int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char
struct lookup_mod *lookup;
int status;
- map_module_writelock(map);
if (!map->lookup) {
- status = open_lookup(map->type, "",
- map->format, map->argc, map->argv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- map_module_unlock(map);
- debug(ap->logopt,
- "lookup module %s open failed", map->type);
- return status;
+ map_module_writelock(map);
+ if (!map->lookup) {
+ status = open_lookup(map->type, "",
+ map->format, map->argc, map->argv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(map);
+ debug(ap->logopt,
+ "lookup module %s open failed", map->type);
+ return status;
+ }
+ map->lookup = lookup;
}
- map->lookup = lookup;
+ map_module_unlock(map);
}
- map_module_unlock(map);
master_source_current_wait(ap->entry);
ap->entry->current = map;
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index a2684664..e2dd0b33 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -1377,17 +1377,19 @@ static int do_host_mount(struct autofs_point *ap, const char *name,
}
}
- map_module_writelock(instance);
if (!instance->lookup) {
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- map_module_unlock(instance);
- debug(ap->logopt, "open lookup module hosts failed");
- goto out;
+ map_module_writelock(instance);
+ if (!instance->lookup) {
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(instance);
+ debug(ap->logopt, "open lookup module hosts failed");
+ goto out;
+ }
+ instance->lookup = lookup;
}
- instance->lookup = lookup;
+ map_module_unlock(instance);
}
- map_module_unlock(instance);
cache_writelock(source->mc);
me = cache_lookup_distinct(source->mc, name);