autofs-5.0.9 - amd lookup add search_path handling From: Ian Kent --- daemon/lookup.c | 75 +++++++++++++++++++++++++++++++--------- include/master.h | 1 + lib/master.c | 6 +++ man/autofs.conf.5.in | 5 +++ modules/parse_amd.c | 4 ++ redhat/autofs.conf.default.in | 9 ++--- samples/autofs.conf.default.in | 9 ++--- 7 files changed, 79 insertions(+), 30 deletions(-) diff --git a/daemon/lookup.c b/daemon/lookup.c index bc6263b..105433e 100644 --- a/daemon/lookup.c +++ b/daemon/lookup.c @@ -100,25 +100,64 @@ static int do_read_master(struct master *master, char *type, time_t age) return status; } -static char *find_map_path(struct map_source *map) +static char *find_map_path(struct autofs_point *ap, struct map_source *map) { + const char *mname = map->argv[0]; + unsigned int mlen = strlen(mname); + char *tok, *ptr = NULL; + char *path = NULL; + char *search_path; struct stat st; - char *path; - path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2); - if (!path) + /* + * This is different to the way it is in amd. + * autofs will always try to locate maps in AUTOFS_MAP_DIR + * but amd has no default and will not find a file map that + * isn't a full path when no search_path is configured, either + * in the mount point or global configuration. + */ + search_path = strdup(AUTOFS_MAP_DIR); + if (map->flags & MAP_FLAG_FORMAT_AMD) { + struct autofs_point *pap = ap; + char *tmp; + /* + * Make sure we get search_path from the root of the + * mount tree, if one is present in the configuration. + * Again different from amd, which ignores the submount + * case. + */ + while (pap->parent) + pap = pap->parent; + tmp = conf_amd_get_search_path(pap->path); + if (tmp) { + if (search_path) + free(search_path); + search_path = tmp; + } + } + if (!search_path) return NULL; - strcpy(path, AUTOFS_MAP_DIR); - strcat(path, "/"); - strcat(path, map->argv[0]); - - if (!stat(path, &st)) - return path; - - free(path); + tok = strtok_r(search_path, ":", &ptr); + while (tok) { + char *this = malloc(strlen(tok) + mlen + 2); + if (!this) { + free(search_path); + return NULL; + } + strcpy(this, tok); + strcat(this, "/"); + strcat(this, mname); + if (!stat(this, &st)) { + path = this; + break; + } + free(this); + tok = strtok_r(NULL, ":", &ptr); + } - return NULL; + free(search_path); + return path; } static int read_master_map(struct master *master, char *type, time_t age) @@ -435,7 +474,7 @@ static int lookup_map_read_map(struct autofs_point *ap, if (map->argv[0][0] == '/') return do_read_map(ap, map, age); - path = find_map_path(map); + path = find_map_path(ap, map); if (!path) return NSS_STATUS_UNKNOWN; @@ -479,6 +518,7 @@ static enum nsswitch_status read_map_source(struct nss_source *this, tmap.flags = map->flags; tmap.type = this->source; tmap.format = map->format; + tmap.name = map->name; tmap.lookup = map->lookup; tmap.mc = map->mc; tmap.instance = map->instance; @@ -489,7 +529,7 @@ static enum nsswitch_status read_map_source(struct nss_source *this, tmap.argc = 0; tmap.argv = NULL; - path = find_map_path(map); + path = find_map_path(ap, map); if (!path) return NSS_STATUS_UNKNOWN; @@ -830,7 +870,7 @@ static int do_name_lookup_mount(struct autofs_point *ap, if (map->argv[0][0] == '/') return do_lookup_mount(ap, map, name, name_len); - path = find_map_path(map); + path = find_map_path(ap, map); if (!path) return NSS_STATUS_UNKNOWN; @@ -875,6 +915,7 @@ static enum nsswitch_status lookup_map_name(struct nss_source *this, tmap.flags = map->flags; tmap.type = this->source; tmap.format = map->format; + tmap.name = map->name; tmap.mc = map->mc; tmap.instance = map->instance; tmap.exp_timeout = map->exp_timeout; @@ -883,7 +924,7 @@ static enum nsswitch_status lookup_map_name(struct nss_source *this, tmap.argc = 0; tmap.argv = NULL; - path = find_map_path(map); + path = find_map_path(ap, map); if (!path) return NSS_STATUS_UNKNOWN; diff --git a/include/master.h b/include/master.h index bcc8eeb..164fd70 100644 --- a/include/master.h +++ b/include/master.h @@ -26,6 +26,7 @@ struct map_source { unsigned int flags; char *type; char *format; + char *name; time_t exp_timeout; /* Timeout for expiring mounts */ time_t age; unsigned int master_line; diff --git a/lib/master.c b/lib/master.c index 5e4ab51..2fa38c9 100644 --- a/lib/master.c +++ b/lib/master.c @@ -211,6 +211,8 @@ master_add_map_source(struct master_mapent *entry, } source->argc = argc; source->argv = tmpargv; + if (source->argv[0]) + source->name = strdup(source->argv[0]); master_source_writelock(entry); @@ -333,6 +335,8 @@ static void __master_free_map_source(struct map_source *source, unsigned int fre free(source->type); if (source->format) free(source->format); + if (source->name) + free(source->name); if (free_cache && source->mc) cache_release(source); if (source->lookup) { @@ -468,6 +472,8 @@ master_add_source_instance(struct map_source *source, const char *type, const ch } new->argc = argc; new->argv = tmpargv; + if (source->name) + new->name = strdup(source->name); status = pthread_mutex_lock(&instance_mutex); if (status) diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in index aad4143..f25a918 100644 --- a/man/autofs.conf.5.in +++ b/man/autofs.conf.5.in @@ -327,6 +327,11 @@ and can be used to provide different defaults on specific machines without having to modify centrally managed maps. It is empty by default. .TP +.B search_path +.br +Colon seperated paths to search for maps that are not specified +as a full path. +.TP .B dismount_interval .br Is equivalent to the autofs timeout option. It is only possible diff --git a/modules/parse_amd.c b/modules/parse_amd.c index 7e04beb..f294d6e 100644 --- a/modules/parse_amd.c +++ b/modules/parse_amd.c @@ -198,7 +198,9 @@ static struct substvar *add_lookup_vars(struct autofs_point *ap, break; } - if (source->argv[0][0]) + if (source->name) + list = macro_addvar(list, "map", 3, source->name); + else if (source->argv[0][0]) list = macro_addvar(list, "map", 3, source->argv[0]); tsv = pthread_getspecific(key_thread_stdenv_vars); diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in index ccccaab..8b04617 100644 --- a/redhat/autofs.conf.default.in +++ b/redhat/autofs.conf.default.in @@ -221,12 +221,6 @@ mount_nfs_default_protocol = 4 # # A number of configuration options are not yet implemented: # -# search_path - always a little frustrating, the compiled in -# map location should be used to locate maps but isn't -# in some cases. This requires work within autofs itself -# and that will (obviously) include implementing this -# configuration option for the amd map parser as well. -# # fully_qualified_hosts - not yet implemented. # # unmount_on_exit - since autofs always tries to re-connect @@ -269,6 +263,9 @@ mount_nfs_default_protocol = 4 # machines without having to modify centrally managed maps. # It is empty by default. # +# search_path - colon seperated paths to search for maps that +# are not specified as a full path. +# # dismount_interval - is equivalent to the autofs timeout option. It # is only possible to use this with type "auto" mounts due # to the way the autofs kernel module performs expiry. It diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in index 616bc66..d0a2002 100644 --- a/samples/autofs.conf.default.in +++ b/samples/autofs.conf.default.in @@ -220,12 +220,6 @@ browse_mode = no # # A number of configuration options are not yet implemented: # -# search_path - always a little frustrating, the compiled in -# map location should be used to locate maps but isn't -# in some cases. This requires work within autofs itself -# and that will (obviously) include implementing this -# configuration option for the amd map parser as well. -# # fully_qualified_hosts - not yet implemented. # # unmount_on_exit - since autofs always tries to re-connect @@ -268,6 +262,9 @@ browse_mode = no # machines without having to modify centrally managed maps. # It is empty by default. # +# search_path - colon seperated paths to search for maps that +# are not specified as a full path. +# # dismount_interval - is equivalent to the autofs timeout option. It # is only possible to use this with type "auto" mounts due # to the way the autofs kernel module performs expiry. It