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