1
/* ----------------------------------------------------------------------- *
3
* lookup.c - API layer to implement nsswitch semantics for map reading
6
* Copyright 2006 Ian Kent <raven@themaw.net>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
11
* USA; either version 2 of the License, or (at your option) any later
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* ----------------------------------------------------------------------- */
25
#include "automount.h"
28
static int check_nss_result(struct nss_source *this, enum nsswitch_status result)
30
enum nsswitch_status status;
33
/* Check if we have negated actions */
34
for (status = 0; status < NSS_STATUS_MAX; status++) {
35
a = this->action[status];
36
if (a.action == NSS_ACTION_UNKNOWN)
39
if (a.negated && result != status) {
40
if (a.action == NSS_ACTION_RETURN) {
41
if (result == NSS_STATUS_SUCCESS)
49
a = this->action[result];
51
/* Check if we have other actions for this status */
53
case NSS_STATUS_SUCCESS:
54
if (a.action == NSS_ACTION_CONTINUE)
58
case NSS_STATUS_NOTFOUND:
59
case NSS_STATUS_UNAVAIL:
60
case NSS_STATUS_TRYAGAIN:
61
if (a.action == NSS_ACTION_RETURN) {
73
static void nsslist_cleanup(void *arg)
75
struct list_head *nsslist = (struct list_head *) arg;
76
if (!list_empty(nsslist))
77
free_sources(nsslist);
81
static int do_read_master(struct master *master, char *type, time_t age)
83
struct lookup_mod *lookup;
89
argv[0] = master->name;
92
lookup = open_lookup(type, "", NULL, argc, argv);
94
return NSS_STATUS_UNAVAIL;
96
status = lookup->lookup_read_master(master, age, lookup->context);
103
static int read_master_map(struct master *master, char *type, time_t age)
105
unsigned int logopt = master->logopt;
106
char *path, *save_name;
109
if (strcasecmp(type, "files")) {
110
return do_read_master(master, type, age);
114
* This is a special case as we need to append the
115
* normal location to the map name.
116
* note: It's invalid to specify a relative path.
119
if (strchr(master->name, '/')) {
120
error(logopt, "relative path invalid in files map name");
121
return NSS_STATUS_NOTFOUND;
124
path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(master->name) + 2);
126
return NSS_STATUS_UNKNOWN;
128
strcpy(path, AUTOFS_MAP_DIR);
130
strcat(path, master->name);
132
save_name = master->name;
135
result = do_read_master(master, type, age);
137
master->name = save_name;
143
int lookup_nss_read_master(struct master *master, time_t age)
145
unsigned int logopt = master->logopt;
146
struct list_head nsslist;
147
struct list_head *head, *p;
148
int result = NSS_STATUS_UNKNOWN;
150
/* If it starts with a '/' it has to be a file or LDAP map */
151
if (*master->name == '/') {
152
if (*(master->name + 1) == '/') {
153
debug(logopt, "reading master ldap %s", master->name);
154
result = do_read_master(master, "ldap", age);
156
debug(logopt, "reading master file %s", master->name);
157
result = do_read_master(master, "file", age);
160
if (result == NSS_STATUS_UNAVAIL)
161
master->read_fail = 1;
165
char *name = master->name;
168
/* Old style name specification will remain I think. */
169
tmp = strchr(name, ':');
173
memset(source, 0, 10);
174
if (!strncmp(name, "file:", 5) ||
175
!strncmp(name, "yp:", 3) ||
176
!strncmp(name, "nis:", 4) ||
177
!strncmp(name, "nisplus:", 8) ||
178
!strncmp(name, "ldap:", 5) ||
179
!strncmp(name, "ldaps:", 6)) {
180
strncpy(source, name, tmp - name);
183
* If it's an ldap map leave the source in the
184
* name so the lookup module can work out if
185
* ldaps has been requested.
187
if (strncmp(name, "ldap", 4)) {
188
master->name = tmp + 1;
189
debug(logopt, "reading master %s %s",
190
source, master->name);
193
debug(logopt, "reading master %s %s",
197
result = do_read_master(master, source, age);
200
if (result == NSS_STATUS_UNAVAIL)
201
master->read_fail = 1;
208
INIT_LIST_HEAD(&nsslist);
210
result = nsswitch_parse(&nsslist);
212
if (!list_empty(&nsslist))
213
free_sources(&nsslist);
214
error(logopt, "can't to read name service switch config.");
218
/* First one gets it */
220
list_for_each(p, head) {
221
struct nss_source *this;
224
this = list_entry(p, struct nss_source, list);
227
"reading master %s %s", this->source, master->name);
229
result = read_master_map(master, this->source, age);
232
* If the name of the master map hasn't been explicitly
233
* configured and we're not reading an included master map
234
* then we're using auto.master as the default. Many setups
235
* also use auto_master as the default master map so we
236
* check for this map when auto.master isn't found.
238
if (result != NSS_STATUS_SUCCESS &&
239
!master->depth && !defaults_master_set()) {
240
char *tmp = strchr(master->name, '.');
243
"%s not found, replacing '.' with '_'",
246
result = read_master_map(master, this->source, age);
247
if (result != NSS_STATUS_SUCCESS)
252
if (result == NSS_STATUS_UNKNOWN) {
253
debug(logopt, "no map - continuing to next source");
257
if (result == NSS_STATUS_UNAVAIL)
258
master->read_fail = 1;
260
status = check_nss_result(this, result);
262
free_sources(&nsslist);
267
if (!list_empty(&nsslist))
268
free_sources(&nsslist);
273
static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t age)
275
struct lookup_mod *lookup;
278
lookup = open_lookup(map->type, "", map->format, map->argc, map->argv);
280
debug(ap->logopt, "lookup module %s failed", map->type);
281
return NSS_STATUS_UNAVAIL;
284
master_source_writelock(ap->entry);
286
close_lookup(map->lookup);
287
map->lookup = lookup;
288
master_source_unlock(ap->entry);
291
return NSS_STATUS_SUCCESS;
293
master_source_current_wait(ap->entry);
294
ap->entry->current = map;
296
status = lookup->lookup_read_map(ap, age, lookup->context);
298
if (status != NSS_STATUS_SUCCESS)
302
* For maps that don't support enumeration return success
303
* and do whatever we must to have autofs function with an
304
* empty map entry cache.
306
* For indirect maps that use the browse option, when the
307
* server is unavailable continue as best we can with
308
* whatever we have in the cache, if anything.
310
if (status == NSS_STATUS_UNKNOWN ||
311
(ap->type == LKP_INDIRECT && status == NSS_STATUS_UNAVAIL))
312
return NSS_STATUS_SUCCESS;
317
static int read_file_source_instance(struct autofs_point *ap, struct map_source *map, time_t age)
319
struct map_source *instance;
320
char src_file[] = "file";
321
char src_prog[] = "program";
325
if (stat(map->argv[0], &st) == -1) {
326
warn(ap->logopt, "file map %s not found", map->argv[0]);
327
return NSS_STATUS_NOTFOUND;
330
if (!S_ISREG(st.st_mode))
331
return NSS_STATUS_NOTFOUND;
333
if (st.st_mode & __S_IEXEC)
338
format = map->format;
340
instance = master_find_source_instance(map, type, format, 0, NULL);
342
int argc = map->argc;
343
const char **argv = map->argv;
344
instance = master_add_source_instance(map, type, format, age, argc, argv);
346
return NSS_STATUS_UNAVAIL;
347
instance->recurse = map->recurse;
348
instance->depth = map->depth;
350
instance->stale = map->stale;
352
return do_read_map(ap, instance, age);
355
static int read_source_instance(struct autofs_point *ap, struct map_source *map, const char *type, time_t age)
357
struct map_source *instance;
360
format = map->format;
362
instance = master_find_source_instance(map, type, format, 0, NULL);
364
int argc = map->argc;
365
const char **argv = map->argv;
366
instance = master_add_source_instance(map, type, format, age, argc, argv);
368
return NSS_STATUS_UNAVAIL;
369
instance->recurse = map->recurse;
370
instance->depth = map->depth;
372
instance->stale = map->stale;
374
return do_read_map(ap, instance, age);
377
static void argv_cleanup(void *arg)
379
struct map_source *tmap = (struct map_source *) arg;
380
/* path is freed in free_argv */
381
free_argv(tmap->argc, tmap->argv);
385
static enum nsswitch_status read_map_source(struct nss_source *this,
386
struct autofs_point *ap, struct map_source *map, time_t age)
388
enum nsswitch_status result;
389
struct map_source tmap;
392
if (strcasecmp(this->source, "files")) {
393
return read_source_instance(ap, map, this->source, age);
397
* autofs built-in map for nsswitch "files" is "file".
398
* This is a special case as we need to append the
399
* normal location to the map name.
400
* note: It's invalid to specify a relative path.
403
if (strchr(map->argv[0], '/')) {
404
error(ap->logopt, "relative path invalid in files map name");
405
return NSS_STATUS_NOTFOUND;
408
this->source[4] = '\0';
409
tmap.type = this->source;
410
tmap.format = map->format;
411
tmap.lookup = map->lookup;
413
tmap.instance = map->instance;
414
tmap.recurse = map->recurse;
415
tmap.depth = map->depth;
416
tmap.stale = map->stale;
420
path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2);
422
return NSS_STATUS_UNKNOWN;
424
strcpy(path, AUTOFS_MAP_DIR);
426
strcat(path, map->argv[0]);
428
if (map->argc >= 1) {
429
tmap.argc = map->argc;
430
tmap.argv = copy_argv(map->argc, map->argv);
432
error(ap->logopt, "failed to copy args");
434
return NSS_STATUS_UNKNOWN;
437
free((char *) tmap.argv[0]);
440
error(ap->logopt, "invalid arguments for autofs_point");
442
return NSS_STATUS_UNKNOWN;
445
pthread_cleanup_push(argv_cleanup, &tmap);
446
result = read_file_source_instance(ap, &tmap, age);
447
pthread_cleanup_pop(1);
449
map->instance = tmap.instance;
454
int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age)
456
struct master_mapent *entry = ap->entry;
457
struct list_head nsslist;
458
struct list_head *head, *p;
459
struct nss_source *this;
460
struct map_source *map;
461
enum nsswitch_status status;
462
unsigned int at_least_one = 0;
466
* For each map source (ie. each entry for the mount
467
* point in the master map) do the nss lookup to
468
* locate the map and read it.
475
/* Is map source up to date or no longer valid */
476
if (!map->stale || entry->age > map->age) {
482
if (!strncmp(map->type, "multi", 5))
483
debug(ap->logopt, "reading multi map");
487
map->type, map->argv[0]);
488
result = do_read_map(ap, map, age);
493
/* If it starts with a '/' it has to be a file or LDAP map */
494
if (map->argv && *map->argv[0] == '/') {
495
if (*(map->argv[0] + 1) == '/') {
496
char *tmp = strdup("ldap");
503
"reading map %s %s", tmp, map->argv[0]);
504
result = do_read_map(ap, map, age);
507
"reading map file %s", map->argv[0]);
508
result = read_file_source_instance(ap, map, age);
514
INIT_LIST_HEAD(&nsslist);
516
pthread_cleanup_push(nsslist_cleanup, &nsslist);
517
status = nsswitch_parse(&nsslist);
518
pthread_cleanup_pop(0);
521
"can't to read name service switch config.");
526
pthread_cleanup_push(nsslist_cleanup, &nsslist);
528
list_for_each(p, head) {
529
this = list_entry(p, struct nss_source, list);
532
"reading map %s %s", this->source, map->argv[0]);
534
result = read_map_source(this, ap, map, age);
535
if (result == NSS_STATUS_UNKNOWN)
538
/* Don't try to update the map cache if it's unavailable */
539
if (result == NSS_STATUS_UNAVAIL)
542
if (result == NSS_STATUS_SUCCESS) {
544
result = NSS_STATUS_TRYAGAIN;
547
status = check_nss_result(this, result);
553
result = NSS_STATUS_SUCCESS;
555
pthread_cleanup_pop(1);
563
if (!result || at_least_one)
569
int lookup_ghost(struct autofs_point *ap, const char *root)
571
struct master_mapent *entry = ap->entry;
572
struct map_source *map;
573
struct mapent_cache *mc;
575
char buf[MAX_ERR_BUF];
580
if (!strcmp(ap->path, "/-"))
581
return LKP_FAIL | LKP_DIRECT;
583
if (!(ap->flags & MOUNT_FLAG_GHOST))
586
pthread_cleanup_push(master_source_lock_cleanup, entry);
587
master_source_readlock(entry);
591
* Only consider map sources that have been read since
592
* the map entry was last updated.
594
if (entry->age > map->age) {
600
pthread_cleanup_push(cache_lock_cleanup, mc);
602
me = cache_enumerate(mc, NULL);
604
if (!strcmp(me->key, "*"))
607
if (*me->key == '/') {
608
/* It's a busy multi-mount - leave till next time */
609
if (list_empty(&me->multi_list))
611
"invalid key %s", me->key);
615
fullpath = malloc(strlen(me->key) + strlen(root) + 3);
617
warn(ap->logopt, "failed to allocate full path");
620
sprintf(fullpath, "%s/%s", root, me->key);
622
ret = stat(fullpath, &st);
623
if (ret == -1 && errno != ENOENT) {
624
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
625
warn(ap->logopt, "stat error %s", estr);
630
ret = mkdir_path(fullpath, 0555);
631
if (ret < 0 && errno != EEXIST) {
632
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
634
"mkdir_path %s failed: %s", fullpath, estr);
639
if (stat(fullpath, &st) != -1) {
646
me = cache_enumerate(mc, me);
648
pthread_cleanup_pop(1);
651
pthread_cleanup_pop(1);
656
int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len)
658
struct lookup_mod *lookup;
662
lookup = open_lookup(map->type, "",
663
map->format, map->argc, map->argv);
666
"lookup module %s failed", map->type);
667
return NSS_STATUS_UNAVAIL;
669
map->lookup = lookup;
672
lookup = map->lookup;
674
master_source_current_wait(ap->entry);
675
ap->entry->current = map;
677
status = lookup->lookup_mount(ap, name, name_len, lookup->context);
682
static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_source *map, const char *name, int name_len)
684
struct map_source *instance;
685
char src_file[] = "file";
686
char src_prog[] = "program";
687
time_t age = time(NULL);
691
if (stat(map->argv[0], &st) == -1) {
692
debug(ap->logopt, "file map not found");
693
return NSS_STATUS_NOTFOUND;
696
if (!S_ISREG(st.st_mode))
697
return NSS_STATUS_NOTFOUND;
699
if (st.st_mode & __S_IEXEC)
704
format = map->format;
706
instance = master_find_source_instance(map, type, format, 0, NULL);
708
int argc = map->argc;
709
const char **argv = map->argv;
710
instance = master_add_source_instance(map, type, format, age, argc, argv);
712
return NSS_STATUS_NOTFOUND;
713
instance->recurse = map->recurse;
714
instance->depth = map->depth;
717
return do_lookup_mount(ap, instance, name, name_len);
720
static int lookup_name_source_instance(struct autofs_point *ap, struct map_source *map, const char *type, const char *name, int name_len)
722
struct map_source *instance;
724
time_t age = time(NULL);
726
format = map->format;
728
instance = master_find_source_instance(map, type, format, 0, NULL);
730
int argc = map->argc;
731
const char **argv = map->argv;
732
instance = master_add_source_instance(map, type, format, age, argc, argv);
734
return NSS_STATUS_NOTFOUND;
735
instance->recurse = map->recurse;
736
instance->depth = map->depth;
739
return do_lookup_mount(ap, instance, name, name_len);
742
static enum nsswitch_status lookup_map_name(struct nss_source *this,
743
struct autofs_point *ap, struct map_source *map,
744
const char *name, int name_len)
746
enum nsswitch_status result;
747
struct map_source tmap;
750
if (strcasecmp(this->source, "files"))
751
return lookup_name_source_instance(ap, map,
752
this->source, name, name_len);
755
* autofs build-in map for nsswitch "files" is "file".
756
* This is a special case as we need to append the
757
* normal location to the map name.
758
* note: we consider it invalid to specify a relative
761
if (strchr(map->argv[0], '/')) {
762
error(ap->logopt, "relative path invalid in files map name");
763
return NSS_STATUS_NOTFOUND;
766
this->source[4] = '\0';
767
tmap.type = this->source;
768
tmap.format = map->format;
770
tmap.instance = map->instance;
771
tmap.recurse = map->recurse;
772
tmap.depth = map->depth;
776
path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2);
778
return NSS_STATUS_UNKNOWN;
780
strcpy(path, AUTOFS_MAP_DIR);
782
strcat(path, map->argv[0]);
784
if (map->argc >= 1) {
785
tmap.argc = map->argc;
786
tmap.argv = copy_argv(map->argc, map->argv);
788
error(ap->logopt, "failed to copy args");
790
return NSS_STATUS_UNKNOWN;
793
free((char *) tmap.argv[0]);
796
error(ap->logopt, "invalid arguments for autofs_point");
798
return NSS_STATUS_UNKNOWN;
801
result = lookup_name_file_source_instance(ap, &tmap, name, name_len);
803
map->instance = tmap.instance;
805
/* path is freed in free_argv */
806
free_argv(tmap.argc, tmap.argv);
811
static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name)
813
struct master_mapent *entry = ap->entry;
814
struct map_source *map;
817
/* Don't update negative cache for included maps */
818
if (source && source->depth)
821
/* Have we recorded the lookup fail for negative caching? */
822
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
825
* Already exists in the cache, the mount fail updates
826
* will update negative timeout status.
828
cache_unlock(me->mc);
830
/* Notify only once after fail */
831
logmsg("key \"%s\" not found in map source(s).", name);
833
/* Doesn't exist in any source, just add it somewhere */
839
time_t now = time(NULL);
842
cache_writelock(map->mc);
843
rv = cache_update(map->mc, map, name, NULL, now);
844
if (rv != CHE_FAIL) {
845
me = cache_lookup_distinct(map->mc, name);
846
me->status = now + ap->negative_timeout;
848
cache_unlock(map->mc);
854
int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len)
856
struct master_mapent *entry = ap->entry;
857
struct list_head nsslist;
858
struct list_head *head, *p;
859
struct nss_source *this;
860
struct map_source *map;
861
enum nsswitch_status status;
865
* For each map source (ie. each entry for the mount
866
* point in the master map) do the nss lookup to
867
* locate the map and lookup the name.
869
pthread_cleanup_push(master_source_lock_cleanup, entry);
870
master_source_readlock(entry);
877
* Only consider map sources that have been read since
878
* the map entry was last updated.
880
if (entry->age > map->age) {
888
result = do_lookup_mount(ap, map, name, name_len);
890
if (result == NSS_STATUS_SUCCESS)
897
/* If it starts with a '/' it has to be a file or LDAP map */
898
if (*map->argv[0] == '/') {
899
if (*(map->argv[0] + 1) == '/') {
900
char *tmp = strdup("ldap");
906
result = do_lookup_mount(ap, map, name, name_len);
908
result = lookup_name_file_source_instance(ap, map, name, name_len);
910
if (result == NSS_STATUS_SUCCESS)
917
INIT_LIST_HEAD(&nsslist);
919
status = nsswitch_parse(&nsslist);
922
"can't to read name service switch config.");
928
list_for_each(p, head) {
929
this = list_entry(p, struct nss_source, list);
931
result = lookup_map_name(this, ap, map, name, name_len);
933
if (result == NSS_STATUS_UNKNOWN) {
938
status = check_nss_result(this, result);
945
if (!list_empty(&nsslist))
946
free_sources(&nsslist);
953
if (ap->state != ST_INIT)
954
send_map_update_request(ap);
955
pthread_cleanup_pop(1);
958
* The last source lookup will return NSS_STATUS_NOTFOUND if the
959
* map exits and the key has not been found but the map may also
960
* not exist in which case the key is also not found.
962
if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL)
963
update_negative_cache(ap, source, name);
968
static void lookup_close_lookup_instances(struct map_source *map)
970
struct map_source *instance;
972
instance = map->instance;
974
lookup_close_lookup_instances(instance);
975
instance = instance->next;
979
close_lookup(map->lookup);
984
void lookup_close_lookup(struct autofs_point *ap)
986
struct map_source *map;
988
map = ap->entry->maps;
993
lookup_close_lookup_instances(map);
1000
static char *make_fullpath(const char *root, const char *key)
1006
l = strlen(key) + 1;
1007
if (l > KEY_MAX_LEN)
1014
l = strlen(key) + 1 + strlen(root) + 1;
1015
if (l > KEY_MAX_LEN)
1020
sprintf(path, "%s/%s", root, key);
1025
void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age)
1027
struct mapent *me, *this;
1029
int status = CHE_FAIL;
1031
me = cache_enumerate(mc, NULL);
1033
struct mapent *valid;
1034
char *key = NULL, *next_key = NULL;
1036
if (me->age >= age) {
1037
me = cache_enumerate(mc, me);
1041
key = strdup(me->key);
1042
me = cache_enumerate(mc, me);
1043
if (!key || !strcmp(key, "*")) {
1049
path = make_fullpath(ap->path, key);
1051
warn(ap->logopt, "can't malloc storage for path");
1057
* If this key has another valid entry we want to prune it,
1058
* even if it's a mount, as the valid entry will take the
1059
* mount if it is a direct mount or it's just a stale indirect
1062
valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT);
1064
is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
1066
"prune check posponed, %s mounted", path);
1072
cache_unlock(valid->mc);
1075
next_key = strdup(me->key);
1079
cache_writelock(mc);
1080
this = cache_lookup_distinct(mc, key);
1087
cache_delete(mc, key);
1088
else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) {
1090
if (this->ioctlfd == -1)
1091
status = cache_delete(mc, key);
1092
if (status != CHE_FAIL) {
1093
if (ap->type == LKP_INDIRECT) {
1094
if (ap->flags & MOUNT_FLAG_GHOST)
1095
rmdir_path(ap, path, ap->dev);
1097
rmdir_path(ap, path, this->dev);
1105
me = cache_lookup_distinct(mc, next_key);
1115
int lookup_prune_cache(struct autofs_point *ap, time_t age)
1117
struct master_mapent *entry = ap->entry;
1118
struct map_source *map;
1120
pthread_cleanup_push(master_source_lock_cleanup, entry);
1121
master_source_readlock(entry);
1125
/* Is the map stale */
1130
pthread_cleanup_push(cache_lock_cleanup, map->mc);
1131
cache_readlock(map->mc);
1132
lookup_prune_one_cache(ap, map->mc, age);
1133
pthread_cleanup_pop(1);
1138
pthread_cleanup_pop(1);
1143
/* Return with cache readlock held */
1144
struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type)
1146
struct master_mapent *entry = ap->entry;
1147
struct map_source *map;
1148
struct mapent_cache *mc;
1149
struct mapent *me = NULL;
1154
* Only consider map sources that have been read since
1155
* the map entry was last updated.
1157
if (ap->entry->age > map->age) {
1164
if (type == LKP_DISTINCT)
1165
me = cache_lookup_distinct(mc, key);
1167
me = cache_lookup(mc, key);
1177
/* Return with cache readlock held */
1178
struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type)
1180
struct master_mapent *entry = ap->entry;
1181
struct map_source *map;
1182
struct mapent_cache *mc;
1183
struct mapent *me = NULL;
1189
if (type == LKP_DISTINCT)
1190
me = cache_lookup_distinct(mc, key);
1192
me = cache_lookup(mc, key);
1199
if (me && me->mc != mc)
1200
error(LOGOPT_ANY, "mismatching mc in cache", me->key);
1205
int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key)
1207
struct master_mapent *entry = ap->entry;
1208
struct map_source *map;
1209
struct mapent_cache *mc;
1217
me = cache_lookup_distinct(mc, key);
1219
if (me->ioctlfd != -1) {
1220
struct ioctl_ops *ops = get_ioctl_ops();
1221
ops->close(ap->logopt, me->ioctlfd);