You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.8 KiB
174 lines
4.8 KiB
7 years ago
|
autofs-5.0.9 - amd lookup fix host mount lookup
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
The amd host mount type is implemented by using the autofs internal
|
||
|
hosts map module and the autofs sun parser.
|
||
|
|
||
|
When using the amd mount type host we need to avoid calling back
|
||
|
into the lookup module of the amd map (as an amd format lookup)
|
||
|
since the lookup keys for mounts in the tree might not match
|
||
|
correctly. In any case it's a call into a lookup module that
|
||
|
isn't needed.
|
||
|
---
|
||
|
daemon/lookup.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
modules/parse_amd.c | 34 +++++++++++++++++++++++----
|
||
|
2 files changed, 94 insertions(+), 5 deletions(-)
|
||
|
|
||
|
--- autofs-5.0.7.orig/daemon/lookup.c
|
||
|
+++ autofs-5.0.7/daemon/lookup.c
|
||
|
@@ -795,6 +795,62 @@ int do_lookup_mount(struct autofs_point
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
+static int lookup_amd_instance(struct autofs_point *ap,
|
||
|
+ struct map_source *map,
|
||
|
+ const char *name, int name_len)
|
||
|
+{
|
||
|
+ struct map_source *instance;
|
||
|
+ struct amd_entry *entry;
|
||
|
+ const char *argv[2];
|
||
|
+ const char **pargv = NULL;
|
||
|
+ int argc = 0;
|
||
|
+ struct mapent *me;
|
||
|
+ char *m_key;
|
||
|
+
|
||
|
+ me = cache_lookup_distinct(map->mc, name);
|
||
|
+ if (!me || !me->multi) {
|
||
|
+ error(ap->logopt, "expected multi mount entry not found");
|
||
|
+ return NSS_STATUS_UNKNOWN;
|
||
|
+ }
|
||
|
+
|
||
|
+ m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 1);
|
||
|
+ if (!m_key) {
|
||
|
+ error(ap->logopt, "failed to allocate storage for search key");
|
||
|
+ return NSS_STATUS_UNKNOWN;
|
||
|
+ }
|
||
|
+
|
||
|
+ strcpy(m_key, ap->path);
|
||
|
+ strcat(m_key, "/");
|
||
|
+ strcat(m_key, me->multi->key);
|
||
|
+ entry = master_find_amdmount(ap, m_key);
|
||
|
+ if (!entry) {
|
||
|
+ error(ap->logopt, "expected amd mount entry not found");
|
||
|
+ free(m_key);
|
||
|
+ return NSS_STATUS_UNKNOWN;
|
||
|
+ }
|
||
|
+ free(m_key);
|
||
|
+
|
||
|
+ if (strcmp(entry->type, "host")) {
|
||
|
+ error(ap->logopt, "unexpected map type %s", entry->type);
|
||
|
+ return NSS_STATUS_UNKNOWN;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (entry->opts) {
|
||
|
+ argv[0] = entry->opts;
|
||
|
+ argv[1] = NULL;
|
||
|
+ pargv = argv;
|
||
|
+ argc = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ instance = master_find_source_instance(map, "hosts", "sun", argc, pargv);
|
||
|
+ if (!instance) {
|
||
|
+ error(ap->logopt, "expected hosts map instance not found");
|
||
|
+ return NSS_STATUS_UNKNOWN;
|
||
|
+ }
|
||
|
+
|
||
|
+ return do_lookup_mount(ap, instance, name, name_len);
|
||
|
+}
|
||
|
+
|
||
|
static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_source *map, const char *name, int name_len)
|
||
|
{
|
||
|
struct map_source *instance;
|
||
|
@@ -804,6 +860,9 @@ static int lookup_name_file_source_insta
|
||
|
struct stat st;
|
||
|
char *type, *format;
|
||
|
|
||
|
+ if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD)
|
||
|
+ return lookup_amd_instance(ap, map, name, name_len);
|
||
|
+
|
||
|
if (stat(map->argv[0], &st) == -1) {
|
||
|
debug(ap->logopt, "file map not found");
|
||
|
return NSS_STATUS_NOTFOUND;
|
||
|
@@ -839,6 +898,9 @@ static int lookup_name_source_instance(s
|
||
|
const char *format;
|
||
|
time_t age = time(NULL);
|
||
|
|
||
|
+ if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD)
|
||
|
+ return lookup_amd_instance(ap, map, name, name_len);
|
||
|
+
|
||
|
format = map->format;
|
||
|
|
||
|
instance = master_find_source_instance(map, type, format, 0, NULL);
|
||
|
@@ -867,6 +929,9 @@ static int do_name_lookup_mount(struct a
|
||
|
return NSS_STATUS_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
+ if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD)
|
||
|
+ return lookup_amd_instance(ap, map, name, name_len);
|
||
|
+
|
||
|
/*
|
||
|
* This is only called when map->type != NULL.
|
||
|
* We only need to look for a map if source type is
|
||
|
--- autofs-5.0.7.orig/modules/parse_amd.c
|
||
|
+++ autofs-5.0.7/modules/parse_amd.c
|
||
|
@@ -1073,29 +1073,53 @@ static int do_host_mount(struct autofs_p
|
||
|
unsigned int flags)
|
||
|
{
|
||
|
struct lookup_mod *lookup;
|
||
|
+ struct map_source *instance;
|
||
|
struct mapent *me;
|
||
|
const char *argv[2];
|
||
|
+ const char **pargv = NULL;
|
||
|
+ int argc = 0;
|
||
|
int ret = 1;
|
||
|
|
||
|
- argv[0] = entry->opts;
|
||
|
- argv[1] = NULL;
|
||
|
+ if (entry->opts) {
|
||
|
+ argv[0] = entry->opts;
|
||
|
+ argv[1] = NULL;
|
||
|
+ pargv = argv;
|
||
|
+ argc = 1;
|
||
|
+ }
|
||
|
|
||
|
- lookup = open_lookup("hosts", MODPREFIX, NULL, 1, argv);
|
||
|
+ instance_mutex_lock();
|
||
|
+ lookup = open_lookup("hosts", MODPREFIX, NULL, argc, pargv);
|
||
|
if (!lookup) {
|
||
|
debug(ap->logopt, "open lookup module hosts failed");
|
||
|
+ instance_mutex_unlock();
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
+ instance = master_find_source_instance(source, "hosts", "sun", argc, pargv);
|
||
|
+ if (!instance) {
|
||
|
+ instance = master_add_source_instance(source,
|
||
|
+ "hosts", "sun", time(NULL), argc, pargv);
|
||
|
+ if (!instance) {
|
||
|
+ error(ap->logopt, MODPREFIX
|
||
|
+ "failed to create source instance for hosts map");
|
||
|
+ instance_mutex_unlock();
|
||
|
+ close_lookup(lookup);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ instance->lookup = lookup;
|
||
|
+ instance_mutex_unlock();
|
||
|
+
|
||
|
+ cache_writelock(source->mc);
|
||
|
me = cache_lookup_distinct(source->mc, name);
|
||
|
if (me)
|
||
|
cache_push_mapent(me, NULL);
|
||
|
+ cache_unlock(source->mc);
|
||
|
|
||
|
master_source_current_wait(ap->entry);
|
||
|
ap->entry->current = source;
|
||
|
|
||
|
ret = lookup->lookup_mount(ap, name, strlen(name), lookup->context);
|
||
|
-
|
||
|
- close_lookup(lookup);
|
||
|
out:
|
||
|
return ret;
|
||
|
}
|