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);
301
* For maps that don't support enumeration return success
302
* and do whatever we must to have autofs function with an
303
* empty map entry cache.
305
* For indirect maps that use the browse option, when the
306
* server is unavailable continue as best we can with
307
* whatever we have in the cache, if anything.
309
if (status == NSS_STATUS_UNKNOWN ||
310
(ap->type == LKP_INDIRECT && status == NSS_STATUS_UNAVAIL))
311
return NSS_STATUS_SUCCESS;
316
static int read_file_source_instance(struct autofs_point *ap, struct map_source *map, time_t age)
318
struct map_source *instance;
319
char src_file[] = "file";
320
char src_prog[] = "program";
324
if (stat(map->argv[0], &st) == -1) {
325
warn(ap->logopt, "file map %s not found", map->argv[0]);
326
return NSS_STATUS_NOTFOUND;
329
if (!S_ISREG(st.st_mode))
330
return NSS_STATUS_NOTFOUND;
332
if (st.st_mode & __S_IEXEC)
337
format = map->format;
339
instance = master_find_source_instance(map, type, format, 0, NULL);
341
int argc = map->argc;
342
const char **argv = map->argv;
343
instance = master_add_source_instance(map, type, format, age, argc, argv);
345
return NSS_STATUS_UNAVAIL;
346
instance->recurse = map->recurse;
347
instance->depth = map->depth;
349
instance->stale = map->stale;
351
return do_read_map(ap, instance, age);
354
static int read_source_instance(struct autofs_point *ap, struct map_source *map, const char *type, time_t age)
356
struct map_source *instance;
359
format = map->format;
361
instance = master_find_source_instance(map, type, format, 0, NULL);
363
int argc = map->argc;
364
const char **argv = map->argv;
365
instance = master_add_source_instance(map, type, format, age, argc, argv);
367
return NSS_STATUS_UNAVAIL;
368
instance->recurse = map->recurse;
369
instance->depth = map->depth;
371
instance->stale = map->stale;
373
return do_read_map(ap, instance, age);
376
static void argv_cleanup(void *arg)
378
struct map_source *tmap = (struct map_source *) arg;
379
/* path is freed in free_argv */
380
free_argv(tmap->argc, tmap->argv);
384
static enum nsswitch_status read_map_source(struct nss_source *this,
385
struct autofs_point *ap, struct map_source *map, time_t age)
387
enum nsswitch_status result;
388
struct map_source tmap;
391
if (strcasecmp(this->source, "files")) {
392
return read_source_instance(ap, map, this->source, age);
396
* autofs built-in map for nsswitch "files" is "file".
397
* This is a special case as we need to append the
398
* normal location to the map name.
399
* note: It's invalid to specify a relative path.
402
if (strchr(map->argv[0], '/')) {
403
error(ap->logopt, "relative path invalid in files map name");
404
return NSS_STATUS_NOTFOUND;
407
this->source[4] = '\0';
408
tmap.type = this->source;
409
tmap.format = map->format;
410
tmap.lookup = map->lookup;
412
tmap.instance = map->instance;
413
tmap.recurse = map->recurse;
414
tmap.depth = map->depth;
415
tmap.stale = map->stale;
419
path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2);
421
return NSS_STATUS_UNKNOWN;
423
strcpy(path, AUTOFS_MAP_DIR);
425
strcat(path, map->argv[0]);
427
if (map->argc >= 1) {
428
tmap.argc = map->argc;
429
tmap.argv = copy_argv(map->argc, map->argv);
431
error(ap->logopt, "failed to copy args");
433
return NSS_STATUS_UNKNOWN;
436
free((char *) tmap.argv[0]);
439
error(ap->logopt, "invalid arguments for autofs_point");
441
return NSS_STATUS_UNKNOWN;
444
pthread_cleanup_push(argv_cleanup, &tmap);
445
result = read_file_source_instance(ap, &tmap, age);
446
pthread_cleanup_pop(1);
448
map->instance = tmap.instance;
453
int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age)
455
struct master_mapent *entry = ap->entry;
456
struct list_head nsslist;
457
struct list_head *head, *p;
458
struct nss_source *this;
459
struct map_source *map;
460
enum nsswitch_status status;
461
unsigned int at_least_one = 0;
465
* For each map source (ie. each entry for the mount
466
* point in the master map) do the nss lookup to
467
* locate the map and read it.
474
/* Is map source up to date or no longer valid */
475
if (!map->stale || entry->age > map->age) {
481
if (!strncmp(map->type, "multi", 5))
482
debug(ap->logopt, "reading multi map");
486
map->type, map->argv[0]);
487
result = do_read_map(ap, map, age);
492
/* If it starts with a '/' it has to be a file or LDAP map */
493
if (map->argv && *map->argv[0] == '/') {
494
if (*(map->argv[0] + 1) == '/') {
495
char *tmp = strdup("ldap");
502
"reading map %s %s", tmp, map->argv[0]);
503
result = do_read_map(ap, map, age);
506
"reading map file %s", map->argv[0]);
507
result = read_file_source_instance(ap, map, age);
513
INIT_LIST_HEAD(&nsslist);
515
pthread_cleanup_push(nsslist_cleanup, &nsslist);
516
status = nsswitch_parse(&nsslist);
517
pthread_cleanup_pop(0);
520
"can't to read name service switch config.");
525
pthread_cleanup_push(nsslist_cleanup, &nsslist);
527
list_for_each(p, head) {
528
this = list_entry(p, struct nss_source, list);
531
"reading map %s %s", this->source, map->argv[0]);
533
result = read_map_source(this, ap, map, age);
534
if (result == NSS_STATUS_UNKNOWN)
537
/* Don't try to update the map cache if it's unavailable */
538
if (result == NSS_STATUS_UNAVAIL)
541
if (result == NSS_STATUS_SUCCESS) {
543
result = NSS_STATUS_TRYAGAIN;
546
status = check_nss_result(this, result);
552
result = NSS_STATUS_SUCCESS;
554
pthread_cleanup_pop(1);
562
if (!result || at_least_one)
568
int lookup_ghost(struct autofs_point *ap, const char *root)
570
struct master_mapent *entry = ap->entry;
571
struct map_source *map;
572
struct mapent_cache *mc;
574
char buf[MAX_ERR_BUF];
579
if (!strcmp(ap->path, "/-"))
580
return LKP_FAIL | LKP_DIRECT;
582
if (!(ap->flags & MOUNT_FLAG_GHOST))
585
pthread_cleanup_push(master_source_lock_cleanup, entry);
586
master_source_readlock(entry);
590
* Only consider map sources that have been read since
591
* the map entry was last updated.
593
if (entry->age > map->age) {
599
pthread_cleanup_push(cache_lock_cleanup, mc);
601
me = cache_enumerate(mc, NULL);
606
if (*me->key == '/') {
607
/* It's a busy multi-mount - leave till next time */
608
if (list_empty(&me->multi_list))
610
"invalid key %s", me->key);
614
fullpath = malloc(strlen(me->key) + strlen(root) + 3);
616
warn(ap->logopt, "failed to allocate full path");
619
sprintf(fullpath, "%s/%s", root, me->key);
621
ret = stat(fullpath, &st);
622
if (ret == -1 && errno != ENOENT) {
623
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
624
warn(ap->logopt, "stat error %s", estr);
629
ret = mkdir_path(fullpath, 0555);
630
if (ret < 0 && errno != EEXIST) {
631
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
633
"mkdir_path %s failed: %s", fullpath, estr);
638
if (stat(fullpath, &st) != -1) {
645
me = cache_enumerate(mc, me);
647
pthread_cleanup_pop(1);
650
pthread_cleanup_pop(1);
655
int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len)
657
struct lookup_mod *lookup;
661
lookup = open_lookup(map->type, "",
662
map->format, map->argc, map->argv);
665
"lookup module %s failed", map->type);
666
return NSS_STATUS_UNAVAIL;
668
map->lookup = lookup;
671
lookup = map->lookup;
673
master_source_current_wait(ap->entry);
674
ap->entry->current = map;
676
status = lookup->lookup_mount(ap, name, name_len, lookup->context);
681
static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_source *map, const char *name, int name_len)
683
struct map_source *instance;
684
char src_file[] = "file";
685
char src_prog[] = "program";
686
time_t age = time(NULL);
690
if (stat(map->argv[0], &st) == -1) {
691
warn(ap->logopt, "file map not found");
692
return NSS_STATUS_NOTFOUND;
695
if (!S_ISREG(st.st_mode))
696
return NSS_STATUS_NOTFOUND;
698
if (st.st_mode & __S_IEXEC)
703
format = map->format;
705
instance = master_find_source_instance(map, type, format, 0, NULL);
707
int argc = map->argc;
708
const char **argv = map->argv;
709
instance = master_add_source_instance(map, type, format, age, argc, argv);
711
return NSS_STATUS_NOTFOUND;
712
instance->recurse = map->recurse;
713
instance->depth = map->depth;
716
return do_lookup_mount(ap, instance, name, name_len);
719
static int lookup_name_source_instance(struct autofs_point *ap, struct map_source *map, const char *type, const char *name, int name_len)
721
struct map_source *instance;
723
time_t age = time(NULL);
725
format = map->format;
727
instance = master_find_source_instance(map, type, format, 0, NULL);
729
int argc = map->argc;
730
const char **argv = map->argv;
731
instance = master_add_source_instance(map, type, format, age, argc, argv);
733
return NSS_STATUS_NOTFOUND;
734
instance->recurse = map->recurse;
735
instance->depth = map->depth;
738
return do_lookup_mount(ap, instance, name, name_len);
741
static enum nsswitch_status lookup_map_name(struct nss_source *this,
742
struct autofs_point *ap, struct map_source *map,
743
const char *name, int name_len)
745
enum nsswitch_status result;
746
struct map_source tmap;
749
if (strcasecmp(this->source, "files"))
750
return lookup_name_source_instance(ap, map,
751
this->source, name, name_len);
754
* autofs build-in map for nsswitch "files" is "file".
755
* This is a special case as we need to append the
756
* normal location to the map name.
757
* note: we consider it invalid to specify a relative
760
if (strchr(map->argv[0], '/')) {
761
error(ap->logopt, "relative path invalid in files map name");
762
return NSS_STATUS_NOTFOUND;
765
this->source[4] = '\0';
766
tmap.type = this->source;
767
tmap.format = map->format;
769
tmap.instance = map->instance;
770
tmap.recurse = map->recurse;
771
tmap.depth = map->depth;
775
path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2);
777
return NSS_STATUS_UNKNOWN;
779
strcpy(path, AUTOFS_MAP_DIR);
781
strcat(path, map->argv[0]);
783
if (map->argc >= 1) {
784
tmap.argc = map->argc;
785
tmap.argv = copy_argv(map->argc, map->argv);
787
error(ap->logopt, "failed to copy args");
789
return NSS_STATUS_UNKNOWN;
792
free((char *) tmap.argv[0]);
795
error(ap->logopt, "invalid arguments for autofs_point");
797
return NSS_STATUS_UNKNOWN;
800
result = lookup_name_file_source_instance(ap, &tmap, name, name_len);
802
map->instance = tmap.instance;
804
/* path is freed in free_argv */
805
free_argv(tmap.argc, tmap.argv);
810
static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name)
812
struct master_mapent *entry = ap->entry;
813
struct map_source *map;
816
/* Have we recorded the lookup fail for negative caching? */
817
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
820
* Already exists in the cache, the mount fail updates
821
* will update negative timeout status.
823
cache_unlock(me->mc);
825
/* Notify only once after fail */
826
error(ap->logopt, "key \"%s\" not found in map.", name);
828
/* Doesn't exist in any source, just add it somewhere */
834
time_t now = time(NULL);
837
cache_writelock(map->mc);
838
rv = cache_update(map->mc, map, name, NULL, now);
839
if (rv != CHE_FAIL) {
840
me = cache_lookup_distinct(map->mc, name);
841
me->status = now + ap->negative_timeout;
843
cache_unlock(map->mc);
849
int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len)
851
struct master_mapent *entry = ap->entry;
852
struct list_head nsslist;
853
struct list_head *head, *p;
854
struct nss_source *this;
855
struct map_source *map;
856
enum nsswitch_status status;
860
* For each map source (ie. each entry for the mount
861
* point in the master map) do the nss lookup to
862
* locate the map and lookup the name.
864
pthread_cleanup_push(master_source_lock_cleanup, entry);
865
master_source_readlock(entry);
872
* Only consider map sources that have been read since
873
* the map entry was last updated.
875
if (entry->age > map->age) {
883
result = do_lookup_mount(ap, map, name, name_len);
885
if (result == NSS_STATUS_SUCCESS)
892
/* If it starts with a '/' it has to be a file or LDAP map */
893
if (*map->argv[0] == '/') {
894
if (*(map->argv[0] + 1) == '/') {
895
char *tmp = strdup("ldap");
901
result = do_lookup_mount(ap, map, name, name_len);
903
result = lookup_name_file_source_instance(ap, map, name, name_len);
905
if (result == NSS_STATUS_SUCCESS)
912
INIT_LIST_HEAD(&nsslist);
914
status = nsswitch_parse(&nsslist);
917
"can't to read name service switch config.");
923
list_for_each(p, head) {
924
this = list_entry(p, struct nss_source, list);
926
result = lookup_map_name(this, ap, map, name, name_len);
928
if (result == NSS_STATUS_UNKNOWN) {
933
status = check_nss_result(this, result);
940
if (!list_empty(&nsslist))
941
free_sources(&nsslist);
948
if (ap->state != ST_INIT)
949
send_map_update_request(ap);
950
pthread_cleanup_pop(1);
953
* The last source lookup will return NSS_STATUS_NOTFOUND if the
954
* map exits and the key has not been found but the map may also
955
* not exist in which case the key is also not found.
957
if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL)
958
update_negative_cache(ap, source, name);
963
static void lookup_close_lookup_instances(struct map_source *map)
965
struct map_source *instance;
967
instance = map->instance;
969
lookup_close_lookup_instances(instance);
970
instance = instance->next;
974
close_lookup(map->lookup);
979
void lookup_close_lookup(struct autofs_point *ap)
981
struct map_source *map;
983
map = ap->entry->maps;
988
lookup_close_lookup_instances(map);
995
static char *make_fullpath(const char *root, const char *key)
1001
l = strlen(key) + 1;
1002
if (l > KEY_MAX_LEN)
1009
l = strlen(key) + 1 + strlen(root) + 1;
1010
if (l > KEY_MAX_LEN)
1015
sprintf(path, "%s/%s", root, key);
1020
void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age)
1022
struct mapent *me, *this;
1024
int status = CHE_FAIL;
1026
me = cache_enumerate(mc, NULL);
1028
struct mapent *valid;
1029
char *key = NULL, *next_key = NULL;
1031
if (me->age >= age) {
1032
me = cache_enumerate(mc, me);
1036
key = strdup(me->key);
1037
me = cache_enumerate(mc, me);
1038
if (!key || *key == '*') {
1044
path = make_fullpath(ap->path, key);
1046
warn(ap->logopt, "can't malloc storage for path");
1052
* If this key has another valid entry we want to prune it,
1053
* even if it's a mount, as the valid entry will take the
1054
* mount if it is a direct mount or it's just a stale indirect
1057
valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT);
1059
is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
1061
"prune check posponed, %s mounted", path);
1067
cache_unlock(valid->mc);
1070
next_key = strdup(me->key);
1074
cache_writelock(mc);
1075
this = cache_lookup_distinct(mc, key);
1082
cache_delete(mc, key);
1083
else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) {
1085
if (this->ioctlfd == -1)
1086
status = cache_delete(mc, key);
1087
if (status != CHE_FAIL) {
1088
if (ap->type == LKP_INDIRECT) {
1089
if (ap->flags & MOUNT_FLAG_GHOST)
1090
rmdir_path(ap, path, ap->dev);
1092
rmdir_path(ap, path, this->dev);
1100
me = cache_lookup_distinct(mc, next_key);
1110
int lookup_prune_cache(struct autofs_point *ap, time_t age)
1112
struct master_mapent *entry = ap->entry;
1113
struct map_source *map;
1115
pthread_cleanup_push(master_source_lock_cleanup, entry);
1116
master_source_readlock(entry);
1120
/* Is the map stale */
1125
pthread_cleanup_push(cache_lock_cleanup, map->mc);
1126
cache_readlock(map->mc);
1127
lookup_prune_one_cache(ap, map->mc, age);
1128
pthread_cleanup_pop(1);
1133
pthread_cleanup_pop(1);
1138
/* Return with cache readlock held */
1139
struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type)
1141
struct master_mapent *entry = ap->entry;
1142
struct map_source *map;
1143
struct mapent_cache *mc;
1144
struct mapent *me = NULL;
1149
* Only consider map sources that have been read since
1150
* the map entry was last updated.
1152
if (ap->entry->age > map->age) {
1159
if (type == LKP_DISTINCT)
1160
me = cache_lookup_distinct(mc, key);
1162
me = cache_lookup(mc, key);
1172
/* Return with cache readlock held */
1173
struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type)
1175
struct master_mapent *entry = ap->entry;
1176
struct map_source *map;
1177
struct mapent_cache *mc;
1178
struct mapent *me = NULL;
1184
if (type == LKP_DISTINCT)
1185
me = cache_lookup_distinct(mc, key);
1187
me = cache_lookup(mc, key);
1194
if (me && me->mc != mc)
1195
error(LOGOPT_ANY, "mismatching mc in cache", me->key);
1200
int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key)
1202
struct master_mapent *entry = ap->entry;
1203
struct map_source *map;
1204
struct mapent_cache *mc;
1212
me = cache_lookup_distinct(mc, key);
1214
if (me->ioctlfd != -1) {
1215
struct ioctl_ops *ops = get_ioctl_ops();
1216
ops->close(ap->logopt, me->ioctlfd);