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