Blame SOURCES/autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch

5a83b1
autofs-5.1.8 - serialise lookup module open and reinit
5a83b1
5a83b1
From: Ian Kent <raven@themaw.net>
5a83b1
5a83b1
Add a map source lock to serialise map setting and use of module
5a83b1
structure fields such as the context.
5a83b1
5a83b1
Signed-off-by: Ian Kent <raven@themaw.net>
5a83b1
---
5a83b1
 CHANGELOG           |    1 +
5a83b1
 daemon/lookup.c     |   35 +++++++++++++++++++++--------------
5a83b1
 daemon/master.c     |   43 +++++++++++++++++++++++++++++++++++++++++++
5a83b1
 include/master.h    |    5 +++++
5a83b1
 modules/parse_amd.c |   26 +++++++++++++++-----------
5a83b1
 5 files changed, 85 insertions(+), 25 deletions(-)
5a83b1
5a83b1
--- autofs-5.1.7.orig/CHANGELOG
5a83b1
+++ autofs-5.1.7/CHANGELOG
5a83b1
@@ -105,6 +105,7 @@
5a83b1
 - fix invalid tsv access.
5a83b1
 - fix missing unlock in sasl_do_kinit_ext_cc().
5a83b1
 - fix parse module instance mutex naming.
5a83b1
+- serialise lookup module open and reinit.
5a83b1
 
5a83b1
 25/01/2021 autofs-5.1.7
5a83b1
 - make bind mounts propagation slave by default.
5a83b1
--- autofs-5.1.7.orig/daemon/lookup.c
5a83b1
+++ autofs-5.1.7/daemon/lookup.c
5a83b1
@@ -318,28 +318,27 @@ static int do_read_map(struct autofs_poi
5a83b1
 	struct lookup_mod *lookup;
5a83b1
 	int status;
5a83b1
 
5a83b1
-	lookup = NULL;
5a83b1
-	master_source_writelock(ap->entry);
5a83b1
+	pthread_cleanup_push(map_module_lock_cleanup, map);
5a83b1
+	map_module_writelock(map);
5a83b1
 	if (!map->lookup) {
5a83b1
 		status = open_lookup(map->type, "", map->format,
5a83b1
 				     map->argc, map->argv, &lookup);
5a83b1
-		if (status != NSS_STATUS_SUCCESS) {
5a83b1
-			master_source_unlock(ap->entry);
5a83b1
+		if (status == NSS_STATUS_SUCCESS)
5a83b1
+			map->lookup = lookup;
5a83b1
+		else
5a83b1
 			debug(ap->logopt,
5a83b1
 			      "lookup module %s open failed", map->type);
5a83b1
-			return status;
5a83b1
-		}
5a83b1
-		map->lookup = lookup;
5a83b1
 	} else {
5a83b1
-		lookup = map->lookup;
5a83b1
-		status = lookup->lookup_reinit(map->format,
5a83b1
-					       map->argc, map->argv,
5a83b1
-					       &lookup->context);
5a83b1
+		status = map->lookup->lookup_reinit(map->format,
5a83b1
+						    map->argc, map->argv,
5a83b1
+						    &map->lookup->context);
5a83b1
 		if (status)
5a83b1
 			warn(ap->logopt,
5a83b1
 			     "lookup module %s reinit failed", map->type);
5a83b1
 	}
5a83b1
-	master_source_unlock(ap->entry);
5a83b1
+	pthread_cleanup_pop(1);
5a83b1
+	if (status != NSS_STATUS_SUCCESS)
5a83b1
+		return status;
5a83b1
 
5a83b1
 	if (!map->stale)
5a83b1
 		return NSS_STATUS_SUCCESS;
5a83b1
@@ -347,7 +346,11 @@ static int do_read_map(struct autofs_poi
5a83b1
 	master_source_current_wait(ap->entry);
5a83b1
 	ap->entry->current = map;
5a83b1
 
5a83b1
+	pthread_cleanup_push(map_module_lock_cleanup, map);
5a83b1
+	map_module_readlock(map);
5a83b1
+	lookup = map->lookup;
5a83b1
 	status = lookup->lookup_read_map(ap, age, lookup->context);
5a83b1
+	pthread_cleanup_pop(1);
5a83b1
 
5a83b1
 	if (status != NSS_STATUS_SUCCESS)
5a83b1
 		map->stale = 0;
5a83b1
@@ -804,23 +807,27 @@ int do_lookup_mount(struct autofs_point
5a83b1
 	struct lookup_mod *lookup;
5a83b1
 	int status;
5a83b1
 
5a83b1
+	map_module_writelock(map);
5a83b1
 	if (!map->lookup) {
5a83b1
 		status = open_lookup(map->type, "",
5a83b1
 				     map->format, map->argc, map->argv, &lookup);
5a83b1
 		if (status != NSS_STATUS_SUCCESS) {
5a83b1
+			map_module_unlock(map);
5a83b1
 			debug(ap->logopt,
5a83b1
 			      "lookup module %s open failed", map->type);
5a83b1
 			return status;
5a83b1
 		}
5a83b1
 		map->lookup = lookup;
5a83b1
 	}
5a83b1
-
5a83b1
-	lookup = map->lookup;
5a83b1
+	map_module_unlock(map);
5a83b1
 
5a83b1
 	master_source_current_wait(ap->entry);
5a83b1
 	ap->entry->current = map;
5a83b1
 
5a83b1
+	map_module_readlock(map);
5a83b1
+	lookup = map->lookup;
5a83b1
 	status = lookup->lookup_mount(ap, name, name_len, lookup->context);
5a83b1
+	map_module_unlock(map);
5a83b1
 
5a83b1
 	return status;
5a83b1
 }
5a83b1
--- autofs-5.1.7.orig/daemon/master.c
5a83b1
+++ autofs-5.1.7/daemon/master.c
5a83b1
@@ -65,6 +65,34 @@ void master_mutex_lock_cleanup(void *arg
5a83b1
 	return;
5a83b1
 }
5a83b1
 
5a83b1
+void map_module_writelock(struct map_source *map)
5a83b1
+{
5a83b1
+	int status = pthread_rwlock_wrlock(&map->module_lock);
5a83b1
+	if (status)
5a83b1
+		fatal(status);
5a83b1
+}
5a83b1
+
5a83b1
+void map_module_readlock(struct map_source *map)
5a83b1
+{
5a83b1
+	int status = pthread_rwlock_rdlock(&map->module_lock);
5a83b1
+	if (status)
5a83b1
+		fatal(status);
5a83b1
+}
5a83b1
+
5a83b1
+void map_module_unlock(struct map_source *map)
5a83b1
+{
5a83b1
+	int status = pthread_rwlock_unlock(&map->module_lock);
5a83b1
+	if (status)
5a83b1
+		fatal(status);
5a83b1
+}
5a83b1
+
5a83b1
+void map_module_lock_cleanup(void *arg)
5a83b1
+{
5a83b1
+	struct map_source *map = (struct map_source *) arg;
5a83b1
+
5a83b1
+	map_module_unlock(map);
5a83b1
+}
5a83b1
+
5a83b1
 int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
5a83b1
 			    unsigned nobind, unsigned ghost, int submount)
5a83b1
 {
5a83b1
@@ -155,6 +183,7 @@ master_add_map_source(struct master_mape
5a83b1
 	struct map_source *source;
5a83b1
 	char *ntype, *nformat;
5a83b1
 	const char **tmpargv;
5a83b1
+	int status;
5a83b1
 
5a83b1
 	source = malloc(sizeof(struct map_source));
5a83b1
 	if (!source)
5a83b1
@@ -241,6 +270,10 @@ master_add_map_source(struct master_mape
5a83b1
 
5a83b1
 	master_source_unlock(entry);
5a83b1
 
5a83b1
+	status = pthread_rwlock_init(&source->module_lock, NULL);
5a83b1
+	if (status)
5a83b1
+		fatal(status);
5a83b1
+
5a83b1
 	return source;
5a83b1
 }
5a83b1
 
5a83b1
@@ -330,6 +363,8 @@ master_get_map_source(struct master_mape
5a83b1
 
5a83b1
 static void __master_free_map_source(struct map_source *source, unsigned int free_cache)
5a83b1
 {
5a83b1
+	int status;
5a83b1
+
5a83b1
 	/* instance map sources are not ref counted */
5a83b1
 	if (source->ref && --source->ref)
5a83b1
 		return;
5a83b1
@@ -365,6 +400,10 @@ static void __master_free_map_source(str
5a83b1
 		}
5a83b1
 	}
5a83b1
 
5a83b1
+	status = pthread_rwlock_destroy(&source->module_lock);
5a83b1
+	if (status)
5a83b1
+		fatal(status);
5a83b1
+
5a83b1
 	free(source);
5a83b1
 
5a83b1
 	return;
5a83b1
@@ -496,6 +535,10 @@ master_add_source_instance(struct map_so
5a83b1
 	if (status)
5a83b1
 		fatal(status);
5a83b1
 
5a83b1
+	status = pthread_rwlock_init(&new->module_lock, NULL);
5a83b1
+	if (status)
5a83b1
+		fatal(status);
5a83b1
+
5a83b1
 	return new;
5a83b1
 }
5a83b1
 
5a83b1
--- autofs-5.1.7.orig/include/master.h
5a83b1
+++ autofs-5.1.7/include/master.h
5a83b1
@@ -35,6 +35,7 @@ struct map_source {
5a83b1
 	unsigned int stale;
5a83b1
 	unsigned int recurse;
5a83b1
 	unsigned int depth;
5a83b1
+	pthread_rwlock_t module_lock;
5a83b1
 	struct lookup_mod *lookup;
5a83b1
 	int argc;
5a83b1
 	const char **argv;
5a83b1
@@ -126,5 +127,9 @@ int __master_list_empty(struct master *)
5a83b1
 int master_list_empty(struct master *);
5a83b1
 int master_done(struct master *);
5a83b1
 int master_kill(struct master *);
5a83b1
+void map_module_writelock(struct map_source *map);
5a83b1
+void map_module_readlock(struct map_source *map);
5a83b1
+void map_module_unlock(struct map_source *map);
5a83b1
+void map_module_lock_cleanup(void *arg);
5a83b1
 
5a83b1
 #endif
5a83b1
--- autofs-5.1.7.orig/modules/parse_amd.c
5a83b1
+++ autofs-5.1.7/modules/parse_amd.c
5a83b1
@@ -1358,14 +1358,6 @@ static int do_host_mount(struct autofs_p
5a83b1
 		argc = 1;
5a83b1
 	}
5a83b1
 
5a83b1
-	parse_instance_mutex_lock();
5a83b1
-	status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
5a83b1
-	if (status != NSS_STATUS_SUCCESS) {
5a83b1
-		debug(ap->logopt, "open lookup module hosts failed");
5a83b1
-		parse_instance_mutex_unlock();
5a83b1
-		goto out;
5a83b1
-	}
5a83b1
-
5a83b1
 	instance = master_find_source_instance(source,
5a83b1
 					 "hosts", "sun", argc, pargv);
5a83b1
 	if (!instance) {
5a83b1
@@ -1374,13 +1366,22 @@ static int do_host_mount(struct autofs_p
5a83b1
 		if (!instance) {
5a83b1
 			error(ap->logopt, MODPREFIX
5a83b1
 			     "failed to create source instance for hosts map");
5a83b1
-			parse_instance_mutex_unlock();
5a83b1
 			close_lookup(lookup);
5a83b1
 			goto out;
5a83b1
 		}
5a83b1
 	}
5a83b1
-	instance->lookup = lookup;
5a83b1
-	parse_instance_mutex_unlock();
5a83b1
+
5a83b1
+	map_module_writelock(instance);
5a83b1
+	if (!instance->lookup) {
5a83b1
+		status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
5a83b1
+		if (status != NSS_STATUS_SUCCESS) {
5a83b1
+			map_module_unlock(instance);
5a83b1
+			debug(ap->logopt, "open lookup module hosts failed");
5a83b1
+			goto out;
5a83b1
+		}
5a83b1
+		instance->lookup = lookup;
5a83b1
+	}
5a83b1
+	map_module_unlock(instance);
5a83b1
 
5a83b1
 	cache_writelock(source->mc);
5a83b1
 	me = cache_lookup_distinct(source->mc, name);
5a83b1
@@ -1391,8 +1392,11 @@ static int do_host_mount(struct autofs_p
5a83b1
 	master_source_current_wait(ap->entry);
5a83b1
 	ap->entry->current = source;
5a83b1
 
5a83b1
+	map_module_readlock(instance);
5a83b1
+	lookup = instance->lookup;
5a83b1
 	ret = lookup->lookup_mount(ap, entry->rhost,
5a83b1
 				   strlen(entry->rhost), lookup->context);
5a83b1
+	map_module_unlock(instance);
5a83b1
 
5a83b1
 	if (!strcmp(name, entry->rhost))
5a83b1
 		goto out;